From 1e993193672e390ee58b18d1dc3b2735d7734b68 Mon Sep 17 00:00:00 2001 From: Tig Date: Sun, 13 Oct 2024 08:01:57 -0600 Subject: [PATCH 01/35] Fixed --- Terminal.Gui/Views/ListView.cs | 2 +- Terminal.Gui/Views/TableView/TableView.cs | 2 +- Terminal.Gui/Views/TreeView/TreeView.cs | 2 +- UICatalog/UICatalog.cs | 42 +++++++++++------------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 0c54aa261..94d2f8282 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -803,7 +803,7 @@ public class ListView : View, IDesignable } /// - public override bool OnProcessKeyDown (Key a) + public override bool OnKeyDown (Key a) { // Enable user to find & select an item by typing text if (CollectionNavigatorBase.IsCompatibleKey (a)) diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 1717b35d6..5df54ae36 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -988,7 +988,7 @@ public class TableView : View } /// - public override bool OnProcessKeyDown (Key keyEvent) + public override bool OnKeyDown (Key keyEvent) { if (TableIsNullOrInvisible ()) { diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 6a43a3e1e..1450a57ba 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -1182,7 +1182,7 @@ public class TreeView : View, ITreeView where T : class } /// - public override bool OnProcessKeyDown (Key keyEvent) + public override bool OnKeyDown (Key keyEvent) { if (!Enabled) { diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 975fcc048..3bc368f57 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -620,28 +620,28 @@ public class UICatalogApp ); ScenarioList.Style.ColumnStyles.Add (1, new () { MaxWidth = 1 }); - // Enable user to find & select a scenario by typing text - // TableView does not (currently) have built-in CollectionNavigator support (the ability for the - // user to type and the items that match get selected). We implement it in the app instead. - ScenarioList.KeyDown += (s, a) => - { - if (CollectionNavigatorBase.IsCompatibleKey (a)) - { - int? newItem = - _scenarioCollectionNav?.GetNextMatchingItem ( - ScenarioList.SelectedRow, - (char)a - ); + //// Enable user to find & select a scenario by typing text + //// TableView does not (currently) have built-in CollectionNavigator support (the ability for the + //// user to type and the items that match get selected). We implement it in the app instead. + //ScenarioList.KeyDown += (s, a) => + // { + // if (CollectionNavigatorBase.IsCompatibleKey (a)) + // { + // int? newItem = + // _scenarioCollectionNav?.GetNextMatchingItem ( + // ScenarioList.SelectedRow, + // (char)a + // ); - if (newItem is int v && newItem != -1) - { - ScenarioList.SelectedRow = v; - ScenarioList.EnsureSelectedCellIsVisible (); - ScenarioList.SetNeedsDisplay (); - a.Handled = true; - } - } - }; + // if (newItem is int v && newItem != -1) + // { + // ScenarioList.SelectedRow = v; + // ScenarioList.EnsureSelectedCellIsVisible (); + // ScenarioList.SetNeedsDisplay (); + // a.Handled = true; + // } + // } + // }; ScenarioList.CellActivated += ScenarioView_OpenSelectedItem; // TableView typically is a grid where nav keys are biased for moving left/right. From 8cb0c84282519e77bd7e7ef863a75d41fe409feb Mon Sep 17 00:00:00 2001 From: Tig Date: Sun, 13 Oct 2024 08:40:38 -0600 Subject: [PATCH 02/35] Fixed View.KeyDown/Up event handling --- Terminal.Gui/View/View.Keyboard.cs | 81 ++++++++++++----------- Terminal.Gui/Views/ListView.cs | 2 +- Terminal.Gui/Views/TableView/TableView.cs | 14 ++-- Terminal.Gui/Views/TextView.cs | 2 +- UnitTests/View/KeyboardEventTests.cs | 42 +++++------- UnitTests/Views/ListViewTests.cs | 12 ++-- 6 files changed, 75 insertions(+), 78 deletions(-) diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index f9c835512..37f2cf2c0 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -259,9 +259,9 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - /// + /// /// if the event was handled. - public bool NewKeyDownEvent (Key keyEvent) + public bool NewKeyDownEvent (Key key) { if (!Enabled) { @@ -270,28 +270,27 @@ public partial class View // Keyboard APIs // By default the KeyBindingScope is View - if (Focused?.NewKeyDownEvent (keyEvent) == true) + if (Focused?.NewKeyDownEvent (key) == true) { return true; } - // Before (fire the cancellable event) - if (OnKeyDown (keyEvent)) + if (RaiseKeyDown (key) || key.Handled) { return true; } // During (this is what can be cancelled) - InvokingKeyBindings?.Invoke (this, keyEvent); + InvokingKeyBindings?.Invoke (this, key); - if (keyEvent.Handled) + if (key.Handled) { return true; } // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommand can be reflected up stack - bool? handled = OnInvokingKeyBindings (keyEvent, KeyBindingScope.HotKey | KeyBindingScope.Focused); + bool? handled = OnInvokingKeyBindings (key, KeyBindingScope.HotKey | KeyBindingScope.Focused); if (handled is { } && (bool)handled) { @@ -302,14 +301,28 @@ public partial class View // Keyboard APIs // TODO: But I've moved it outside of the v-function to test something. // After (fire the cancellable event) // fire event - ProcessKeyDown?.Invoke (this, keyEvent); + ProcessKeyDown?.Invoke (this, key); - if (!keyEvent.Handled && OnProcessKeyDown (keyEvent)) + if (!key.Handled && OnProcessKeyDown (key)) { return true; } - return keyEvent.Handled; + return key.Handled; + } + + private bool RaiseKeyDown (Key key) + { + // Before (fire the cancellable event) + if (OnKeyDown (key) || key.Handled) + { + return true; + } + + // fire event + KeyDown?.Invoke (this, key); + + return key.Handled; } /// @@ -330,10 +343,7 @@ public partial class View // Keyboard APIs /// public virtual bool OnKeyDown (Key keyEvent) { - // fire event - KeyDown?.Invoke (this, keyEvent); - - return keyEvent.Handled; + return false; } /// @@ -421,35 +431,38 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - /// + /// /// if the event was handled. - public bool NewKeyUpEvent (Key keyEvent) + public bool NewKeyUpEvent (Key key) { if (!Enabled) { return false; } - if (Focused?.NewKeyUpEvent (keyEvent) == true) + if (RaiseKeyUp (key) || key.Handled) { return true; } - // Before (fire the cancellable event) - if (OnKeyUp (keyEvent)) - { - return true; - } - - // During (this is what can be cancelled) - // TODO: Until there's a clear use-case, we will not define 'during' event (e.g. OnDuringKeyUp). - - // After (fire the cancellable event InvokingKeyBindings) - // TODO: Until there's a clear use-case, we will not define an 'after' event (e.g. OnAfterKeyUp). - return false; } + private bool RaiseKeyUp (Key key) + { + // Before (fire the cancellable event) + if (OnKeyUp (key) || key.Handled) + { + return true; + } + + // fire event + KeyUp?.Invoke (this, key); + + return key.Handled; + } + + /// Method invoked when a key is released. This method is called from . /// Contains the details about the key that produced the event. /// @@ -467,14 +480,6 @@ public partial class View // Keyboard APIs /// public virtual bool OnKeyUp (Key keyEvent) { - // fire event - KeyUp?.Invoke (this, keyEvent); - - if (keyEvent.Handled) - { - return true; - } - return false; } diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 94d2f8282..fddd0482f 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -806,7 +806,7 @@ public class ListView : View, IDesignable public override bool OnKeyDown (Key a) { // Enable user to find & select an item by typing text - if (CollectionNavigatorBase.IsCompatibleKey (a)) + if (CollectionNavigatorBase.IsCompatibleKey (a) && (!AllowsMarking && a == Key.Space)) { int? newItem = KeystrokeNavigator?.GetNextMatchingItem (SelectedItem, (char)a); diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 5df54ae36..8e90bd42d 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -988,7 +988,7 @@ public class TableView : View } /// - public override bool OnKeyDown (Key keyEvent) + public override bool OnKeyDown (Key key) { if (TableIsNullOrInvisible ()) { @@ -998,12 +998,14 @@ public class TableView : View if (CollectionNavigator != null && HasFocus && Table.Rows != 0 - && CollectionNavigatorBase.IsCompatibleKey (keyEvent) - && !keyEvent.KeyCode.HasFlag (KeyCode.CtrlMask) - && !keyEvent.KeyCode.HasFlag (KeyCode.AltMask) - && Rune.IsLetterOrDigit ((Rune)keyEvent)) + && key != KeyBindings.GetKeyFromCommands (Command.Accept) + && key != CellActivationKey + && CollectionNavigatorBase.IsCompatibleKey (key) + && !key.KeyCode.HasFlag (KeyCode.CtrlMask) + && !key.KeyCode.HasFlag (KeyCode.AltMask) + && Rune.IsLetterOrDigit ((Rune)key)) { - return CycleToNextTableEntryBeginningWith (keyEvent); + return CycleToNextTableEntryBeginningWith (key); } return false; diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 674d8328e..a539aadf3 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3688,7 +3688,7 @@ public class TextView : View return true; } - return base.OnKeyUp (key); + return false; } /// diff --git a/UnitTests/View/KeyboardEventTests.cs b/UnitTests/View/KeyboardEventTests.cs index ec7eec6aa..70965a8da 100644 --- a/UnitTests/View/KeyboardEventTests.cs +++ b/UnitTests/View/KeyboardEventTests.cs @@ -108,7 +108,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.Equal (alt, e.IsAlt); Assert.Equal (control, e.IsCtrl); Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); keyDown = true; }; view.ProcessKeyDown += (s, e) => { keyPressed = true; }; @@ -120,7 +120,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.Equal (alt, e.IsAlt); Assert.Equal (control, e.IsCtrl); Assert.False (keyUp); - Assert.False (view.OnKeyUpContinued); + Assert.True (view.OnKeyUpCalled); keyUp = true; }; @@ -138,7 +138,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews ) ); Assert.True (keyPressed); - Assert.True (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); Assert.True (view.OnKeyPressedContinued); view.NewKeyUpEvent ( @@ -150,7 +150,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews ) ); Assert.True (keyUp); - Assert.True (view.OnKeyUpContinued); + Assert.True (view.OnKeyUpCalled); } [Fact] @@ -215,7 +215,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); e.Handled = false; keyDown = true; }; @@ -243,7 +243,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (invokingKeyBindings); Assert.False (keyPressed); - Assert.True (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); Assert.False (view.OnInvokingKeyBindingsContinued); Assert.False (view.OnKeyPressedContinued); } @@ -263,7 +263,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); e.Handled = true; keyDown = true; }; @@ -291,7 +291,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.False (invokingKeyBindings); Assert.False (keyPressed); - Assert.False (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); Assert.False (view.OnInvokingKeyBindingsContinued); Assert.False (view.OnKeyPressedContinued); } @@ -352,7 +352,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); e.Handled = false; keyDown = true; }; @@ -380,7 +380,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (invokingKeyBindings); Assert.True (keyPressed); - Assert.True (view.OnKeyDownContinued); + Assert.True (view.OnKeyDownCalled); Assert.True (view.OnInvokingKeyBindingsContinued); Assert.False (view.OnKeyPressedContinued); } @@ -406,8 +406,8 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews view.NewKeyUpEvent (Key.A); Assert.True (keyUp); - Assert.False (view.OnKeyUpContinued); - Assert.False (view.OnKeyDownContinued); + Assert.True (view.OnKeyUpCalled); + Assert.False (view.OnKeyDownCalled); Assert.False (view.OnInvokingKeyBindingsContinued); Assert.False (view.OnKeyPressedContinued); } @@ -444,9 +444,9 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews public OnKeyTestView () { CanFocus = true; } public bool CancelVirtualMethods { set; private get; } public bool OnInvokingKeyBindingsContinued { get; set; } - public bool OnKeyDownContinued { get; set; } + public bool OnKeyDownCalled { get; set; } public bool OnKeyPressedContinued { get; set; } - public bool OnKeyUpContinued { get; set; } + public bool OnKeyUpCalled { get; set; } public override string Text { get; set; } public override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) @@ -465,24 +465,14 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews public override bool OnKeyDown (Key keyEvent) { - if (base.OnKeyDown (keyEvent)) - { - return true; - } - - OnKeyDownContinued = true; + OnKeyDownCalled = true; return CancelVirtualMethods; } public override bool OnKeyUp (Key keyEvent) { - if (base.OnKeyUp (keyEvent)) - { - return true; - } - - OnKeyUpContinued = true; + OnKeyUpCalled = true; return CancelVirtualMethods; } diff --git a/UnitTests/Views/ListViewTests.cs b/UnitTests/Views/ListViewTests.cs index ff84f1b2f..7714c8204 100644 --- a/UnitTests/Views/ListViewTests.cs +++ b/UnitTests/Views/ListViewTests.cs @@ -539,10 +539,10 @@ Item 6", lv.KeyBindings.Add (Key.Space.WithShift, Command.Select, Command.Down); - Key ev = Key.Space.WithShift; + Key key = Key.Space.WithShift; // view should indicate that it has accepted and consumed the event - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (key)); // first item should now be selected Assert.Equal (0, lv.SelectedItem); @@ -553,7 +553,7 @@ Item 6", Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (key)); // second item should now be selected Assert.Equal (1, lv.SelectedItem); @@ -564,21 +564,21 @@ Item 6", Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (key)); Assert.Equal (2, lv.SelectedItem); Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (key)); Assert.Equal (2, lv.SelectedItem); // cannot move down any further Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); Assert.True (lv.Source.IsMarked (2)); // but can toggle marked // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (key)); Assert.Equal (2, lv.SelectedItem); // cannot move down any further Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); From 61be0615e0ebf7b8f9c0bcc73550f49d8876df49 Mon Sep 17 00:00:00 2001 From: Tig Date: Sun, 13 Oct 2024 09:25:37 -0600 Subject: [PATCH 03/35] Fixed TableView key handling --- Terminal.Gui/View/View.Keyboard.cs | 106 ++++++++++------- Terminal.Gui/Views/DateField.cs | 2 +- Terminal.Gui/Views/FileDialog.cs | 2 +- Terminal.Gui/Views/HexView.cs | 2 +- Terminal.Gui/Views/ListView.cs | 2 +- Terminal.Gui/Views/ScrollView.cs | 2 +- Terminal.Gui/Views/TableView/TableView.cs | 2 +- Terminal.Gui/Views/TextField.cs | 2 +- Terminal.Gui/Views/TextValidateField.cs | 2 +- Terminal.Gui/Views/TextView.cs | 2 +- Terminal.Gui/Views/TileView.cs | 2 +- Terminal.Gui/Views/TimeField.cs | 2 +- Terminal.Gui/Views/TreeView/TreeView.cs | 2 +- Terminal.Gui/Views/Wizard/Wizard.cs | 2 +- UICatalog/Scenarios/LineDrawing.cs | 4 +- UICatalog/Scenarios/Snake.cs | 2 +- UICatalog/Scenarios/VkeyPacketSimulator.cs | 2 +- UnitTests/FileServices/FileDialogTests.cs | 10 +- UnitTests/Input/ResponderTests.cs | 10 +- UnitTests/View/KeyboardEventTests.cs | 4 +- UnitTests/View/ViewTests.cs | 8 +- UnitTests/Views/ScrollViewTests.cs | 130 ++++++++++----------- 22 files changed, 162 insertions(+), 140 deletions(-) diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index 37f2cf2c0..317079358 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -268,63 +268,84 @@ public partial class View // Keyboard APIs return false; } - // By default the KeyBindingScope is View - + // If there's a Focused subview, give it a chance (this recurses down the hierarchy) if (Focused?.NewKeyDownEvent (key) == true) { return true; } + // Before (fire the cancellable event) if (RaiseKeyDown (key) || key.Handled) { return true; } // During (this is what can be cancelled) - InvokingKeyBindings?.Invoke (this, key); - if (key.Handled) + if (RaiseInvokingKeyBindings (key) || key.Handled) { return true; } - // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommand can be reflected up stack - - bool? handled = OnInvokingKeyBindings (key, KeyBindingScope.HotKey | KeyBindingScope.Focused); - - if (handled is { } && (bool)handled) - { - return true; - } - - // TODO: The below is not right. OnXXX handlers are supposed to fire the events. - // TODO: But I've moved it outside of the v-function to test something. - // After (fire the cancellable event) - // fire event - ProcessKeyDown?.Invoke (this, key); - - if (!key.Handled && OnProcessKeyDown (key)) + if (RaiseProcessKeyDown(key) || key.Handled) { return true; } return key.Handled; - } - private bool RaiseKeyDown (Key key) - { - // Before (fire the cancellable event) - if (OnKeyDown (key) || key.Handled) + bool RaiseKeyDown (Key key) { - return true; + // Before (fire the cancellable event) + if (OnKeyDown (key) || key.Handled) + { + return true; + } + + // fire event + KeyDown?.Invoke (this, key); + + return key.Handled; } - // fire event - KeyDown?.Invoke (this, key); + bool RaiseInvokingKeyBindings (Key key) + { + // BUGBUG: The proper pattern is for the v-method (OnInvokingKeyBindings) to be called first, then the event + InvokingKeyBindings?.Invoke (this, key); - return key.Handled; + if (key.Handled) + { + return true; + } + + // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommand can be reflected up stack + + bool? handled = OnInvokingKeyBindings (key, KeyBindingScope.HotKey | KeyBindingScope.Focused); + + if (handled is { } && (bool)handled) + { + return true; + } + + return false; + } + + bool RaiseProcessKeyDown (Key key) + { + // BUGBUG: The proper pattern is for the v-method (OnProcessKeyDown) to be called first, then the event + ProcessKeyDown?.Invoke (this, key); + + if (!key.Handled && OnProcessKeyDown (key)) + { + return true; + } + + return false; + } } + + /// /// Low-level API called when the user presses a key, allowing a view to pre-process the key down event. This is /// called from before . @@ -341,7 +362,7 @@ public partial class View // Keyboard APIs /// /// Fires the event. /// - public virtual bool OnKeyDown (Key keyEvent) + protected virtual bool OnKeyDown (Key keyEvent) { return false; } @@ -384,9 +405,8 @@ public partial class View // Keyboard APIs /// KeyUp events. /// /// - public virtual bool OnProcessKeyDown (Key keyEvent) + protected virtual bool OnProcessKeyDown (Key keyEvent) { - //ProcessKeyDown?.Invoke (this, keyEvent); return keyEvent.Handled; } @@ -446,20 +466,20 @@ public partial class View // Keyboard APIs } return false; - } - private bool RaiseKeyUp (Key key) - { - // Before (fire the cancellable event) - if (OnKeyUp (key) || key.Handled) + bool RaiseKeyUp (Key key) { - return true; + // Before (fire the cancellable event) + if (OnKeyUp (key) || key.Handled) + { + return true; + } + + // fire event + KeyUp?.Invoke (this, key); + + return key.Handled; } - - // fire event - KeyUp?.Invoke (this, key); - - return key.Handled; } diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 2e07f0afa..43060c0a5 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -131,7 +131,7 @@ public class DateField : TextField public virtual void OnDateChanged (DateTimeEventArgs args) { DateChanged?.Invoke (this, args); } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnProcessKeyDown (Key a) { // Ignore non-numeric characters. if (a >= Key.D0 && a <= Key.D9) diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index d0022fea0..78ed5b584 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -233,7 +233,7 @@ public class FileDialog : Dialog _tbPath.TextChanged += (s, e) => PathChanged (); _tableView.CellActivated += CellActivate; - _tableView.KeyUp += (s, k) => k.Handled = TableView_KeyUp (k); + _tableView.KeyDown += (s, k) => k.Handled = TableView_KeyUp (k); _tableView.SelectedCellChanged += TableView_SelectedCellChanged; _tableView.KeyBindings.ReplaceCommands (Key.Home, Command.Start); diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index 16a363755..8f7e3c1a0 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -452,7 +452,7 @@ public class HexView : View, IDesignable public virtual void OnPositionChanged () { PositionChanged?.Invoke (this, new HexViewEventArgs (Position, CursorPosition, BytesPerLine)); } /// - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnProcessKeyDown (Key keyEvent) { if (!AllowEdits) { diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index fddd0482f..f7e65f843 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -803,7 +803,7 @@ public class ListView : View, IDesignable } /// - public override bool OnKeyDown (Key a) + protected override bool OnKeyDown (Key a) { // Enable user to find & select an item by typing text if (CollectionNavigatorBase.IsCompatibleKey (a) && (!AllowsMarking && a == Key.Space)) diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 576973ed6..6a2c6ffbe 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -388,7 +388,7 @@ public class ScrollView : View } /// - public override bool OnKeyDown (Key a) + protected override bool OnKeyDown (Key a) { if (base.OnKeyDown (a)) { diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 8e90bd42d..5da0b11e3 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -988,7 +988,7 @@ public class TableView : View } /// - public override bool OnKeyDown (Key key) + protected override bool OnKeyDown (Key key) { if (TableIsNullOrInvisible ()) { diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index c9d681867..984f151f4 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -1055,7 +1055,7 @@ public class TextField : View /// /// /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnProcessKeyDown (Key a) { // Remember the cursor position because the new calculated cursor position is needed // to be set BEFORE the TextChanged event is triggered. diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index a6c740d1b..579b22f56 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -597,7 +597,7 @@ namespace Terminal.Gui } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnProcessKeyDown (Key a) { if (_provider is null) { diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index a539aadf3..f5436ea96 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3703,7 +3703,7 @@ public class TextView : View } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnProcessKeyDown (Key a) { if (!CanFocus) { diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index b6e57dd90..4adbb5b1b 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -286,7 +286,7 @@ public class TileView : View //// BUGBUG: Why is this not handled by a key binding??? /// - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnProcessKeyDown (Key keyEvent) { var focusMoved = false; diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index b198d66a0..305a3ce59 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -177,7 +177,7 @@ public class TimeField : TextField } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnProcessKeyDown (Key a) { // Ignore non-numeric characters. if (a.KeyCode is >= (KeyCode)(int)KeyCode.D0 and <= (KeyCode)(int)KeyCode.D9) diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 1450a57ba..59fe8e04f 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -1182,7 +1182,7 @@ public class TreeView : View, ITreeView where T : class } /// - public override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key keyEvent) { if (!Enabled) { diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index 6c9fe55c1..338328b02 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -386,7 +386,7 @@ public class Wizard : Dialog /// /// /// - public override bool OnProcessKeyDown (Key key) + protected override bool OnProcessKeyDown (Key key) { //// BUGBUG: Why is this not handled by a key binding??? if (!Modal) diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index 5b2887c59..d2fdb7800 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -121,7 +121,7 @@ public class LineDrawing : Scenario tools.CurrentColor = canvas.GetNormalColor (); canvas.CurrentAttribute = tools.CurrentColor; - win.KeyDown += (s, e) => { e.Handled = canvas.OnKeyDown (e); }; + win.KeyDown += (s, e) => { e.Handled = canvas.NewKeyDownEvent (e); }; Application.Run (win); win.Dispose (); @@ -290,7 +290,7 @@ public class DrawingArea : View } //// BUGBUG: Why is this not handled by a key binding??? - public override bool OnKeyDown (Key e) + protected override bool OnKeyDown (Key e) { // BUGBUG: These should be implemented with key bindings if (e.KeyCode == (KeyCode.Z | KeyCode.CtrlMask)) diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 0a16aed95..998969d8d 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -357,7 +357,7 @@ public class Snake : Scenario } // BUGBUG: Should (can) this use key bindings instead. - public override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key keyEvent) { if (keyEvent.KeyCode == KeyCode.CursorUp) { diff --git a/UICatalog/Scenarios/VkeyPacketSimulator.cs b/UICatalog/Scenarios/VkeyPacketSimulator.cs index 94a8618fe..6bea34c91 100644 --- a/UICatalog/Scenarios/VkeyPacketSimulator.cs +++ b/UICatalog/Scenarios/VkeyPacketSimulator.cs @@ -112,7 +112,7 @@ public class VkeyPacketSimulator : Scenario if (handled == null || handled == false) { - if (!tvOutput.OnProcessKeyDown (e)) + if (!tvOutput.NewKeyDownEvent (e)) { Application.Invoke ( () => MessageBox.Query ( diff --git a/UnitTests/FileServices/FileDialogTests.cs b/UnitTests/FileServices/FileDialogTests.cs index f446f5be9..28e81ef60 100644 --- a/UnitTests/FileServices/FileDialogTests.cs +++ b/UnitTests/FileServices/FileDialogTests.cs @@ -140,7 +140,7 @@ public class FileDialogTests () AssertIsTheStartingDirectory (dlg.Path); Assert.IsType (dlg.MostFocused); - Send ('v', ConsoleKey.DownArrow); + Application.OnKeyDown (Key.CursorDown); var tv = GetTableView(dlg); tv.SetFocus (); @@ -152,15 +152,17 @@ public class FileDialogTests () AssertIsTheStartingDirectory (dlg.Path); // Accept navigation up a directory - Send ('\n', ConsoleKey.Enter); + Application.OnKeyDown (Key.Enter); AssertIsTheRootDirectory (dlg.Path); Assert.True (dlg.Canceled); Assert.False (selected); - // Now press the back button (in table view) - Send ('<', ConsoleKey.Backspace); + Assert.IsType (dlg.MostFocused); + + // Now press Backspace (in table view) + Application.OnKeyDown (Key.Backspace); // Should move us back to the root AssertIsTheStartingDirectory (dlg.Path); diff --git a/UnitTests/Input/ResponderTests.cs b/UnitTests/Input/ResponderTests.cs index cd02fa0ed..cac5c549e 100644 --- a/UnitTests/Input/ResponderTests.cs +++ b/UnitTests/Input/ResponderTests.cs @@ -205,11 +205,11 @@ public class ResponderTests var r = new View (); var args = new Key { KeyCode = KeyCode.Null }; - Assert.False (r.OnKeyDown (args)); + Assert.False (r.NewKeyDownEvent (args)); Assert.False (args.Handled); r.KeyDown += (s, a) => a.Handled = true; - Assert.True (r.OnKeyDown (args)); + Assert.True (r.NewKeyDownEvent (args)); Assert.True (args.Handled); r.Dispose (); @@ -232,8 +232,8 @@ public class ResponderTests var r = new View (); //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.OnKeyDown (new Key { KeyCode = KeyCode.Null })); - Assert.False (r.OnKeyUp (new Key { KeyCode = KeyCode.Null })); + Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null })); + Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null })); Assert.False (r.NewMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents })); var v = new View (); @@ -293,6 +293,6 @@ public class ResponderTests public class DerivedView : View { - public override bool OnKeyDown (Key keyEvent) { return true; } + protected override bool OnKeyDown (Key keyEvent) { return true; } } } diff --git a/UnitTests/View/KeyboardEventTests.cs b/UnitTests/View/KeyboardEventTests.cs index 70965a8da..d60e4ec35 100644 --- a/UnitTests/View/KeyboardEventTests.cs +++ b/UnitTests/View/KeyboardEventTests.cs @@ -463,7 +463,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews return CancelVirtualMethods; } - public override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key keyEvent) { OnKeyDownCalled = true; @@ -477,7 +477,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews return CancelVirtualMethods; } - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnProcessKeyDown (Key keyEvent) { if (base.OnProcessKeyDown (keyEvent)) { diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index 6f1392a46..54b9b31b5 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -870,10 +870,10 @@ At 0,0 { var r = new View (); - Assert.False (r.OnKeyDown (new () { KeyCode = KeyCode.Null })); + Assert.False (r.NewKeyDownEvent (Key.Empty)); //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.OnKeyUp (new () { KeyCode = KeyCode.Null })); + Assert.False (r.NewKeyUpEvent (Key.Empty)); Assert.False (r.NewMouseEvent (new () { Flags = MouseFlags.AllEvents })); r.Dispose (); @@ -1132,7 +1132,7 @@ At 0,0 ClearNeedsDisplay (); } - public override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key keyEvent) { IsKeyDown = true; @@ -1146,7 +1146,7 @@ At 0,0 return true; } - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnProcessKeyDown (Key keyEvent) { IsKeyPress = true; diff --git a/UnitTests/Views/ScrollViewTests.cs b/UnitTests/Views/ScrollViewTests.cs index fd207e28f..b179cd0ca 100644 --- a/UnitTests/Views/ScrollViewTests.cs +++ b/UnitTests/Views/ScrollViewTests.cs @@ -579,7 +579,7 @@ public class ScrollViewTests (ITestOutputHelper output) Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -603,7 +603,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -627,7 +627,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -651,7 +651,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -675,7 +675,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -699,7 +699,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -723,7 +723,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -746,7 +746,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.End.WithCtrl)); + Assert.True (scrollView.NewKeyDownEvent (Key.End.WithCtrl)); top.Draw (); expected = @" @@ -769,8 +769,8 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.Home.WithCtrl)); - Assert.True (scrollView.OnKeyDown (Key.CursorDown)); + Assert.True (scrollView.NewKeyDownEvent (Key.Home.WithCtrl)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorDown)); top.Draw (); expected = @" @@ -793,7 +793,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorDown)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorDown)); top.Draw (); expected = @" @@ -816,7 +816,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorDown)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorDown)); top.Draw (); expected = @" @@ -839,7 +839,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.End)); + Assert.True (scrollView.NewKeyDownEvent (Key.End)); top.Draw (); expected = @" @@ -940,120 +940,120 @@ public class ScrollViewTests (ITestOutputHelper output) Assert.True (sv.KeepContentAlwaysInViewport); Assert.True (sv.AutoHideScrollBars); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorUp)); + Assert.False (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorDown)); + Assert.True (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (new (0, -1), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorUp)); + Assert.True (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown)); Point point0xMinus10 = new (0, -10); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageDown)); + Assert.False (sv.NewKeyDownEvent (Key.PageDown)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorDown)); + Assert.False (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithAlt)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithAlt)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorLeft)); + Assert.False (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorRight)); + Assert.True (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (new (-1, -10), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorLeft)); + Assert.True (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Point pointMinus20xMinus10 = new (-20, -10); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorRight)); + Assert.False (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home)); + Assert.True (sv.NewKeyDownEvent (Key.Home)); Point pointMinus20x0 = new (-20, 0); Assert.Equal (pointMinus20x0, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home)); + Assert.False (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (pointMinus20x0, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End)); + Assert.True (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End)); + Assert.False (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home)); + Assert.True (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (pointMinus20x0, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (Point.Empty, sv.ContentOffset); sv.KeepContentAlwaysInViewport = false; Assert.False (sv.KeepContentAlwaysInViewport); Assert.True (sv.AutoHideScrollBars); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorUp)); + Assert.False (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorDown)); + Assert.True (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (new (0, -1), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorUp)); + Assert.True (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown)); Point point0xMinus19 = new (0, -19); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageDown)); + Assert.False (sv.NewKeyDownEvent (Key.PageDown)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorDown)); + Assert.False (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithAlt)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithAlt)); Assert.Equal (new (0, -9), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorLeft)); + Assert.False (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorRight)); + Assert.True (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (new (-1, -19), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorLeft)); + Assert.True (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Assert.Equal (new (-20, -19), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Point pointMinus39xMinus19 = new (-39, -19); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorRight)); + Assert.False (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageUp.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageUp.WithCtrl)); var pointMinus19xMinus19 = new Point (-19, -19); Assert.Equal (pointMinus19xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home)); + Assert.True (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (new (-19, 0), sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home)); + Assert.False (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (new (-19, 0), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End)); + Assert.True (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus19xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End)); + Assert.False (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus19xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); } From d6852cbbdc7ea07e33f3a4509d27516ed42a8e40 Mon Sep 17 00:00:00 2001 From: Tig Date: Sun, 13 Oct 2024 09:39:50 -0600 Subject: [PATCH 04/35] KeyUp/Down api docs --- Terminal.Gui/View/View.Keyboard.cs | 103 +++++++++++++++-------------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index 317079358..c3ccd8ca9 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -243,7 +243,8 @@ public partial class View // Keyboard APIs #region Key Down Event /// - /// If the view is enabled, processes a new key down event and returns if the event was + /// If the view is enabled, raises the related key down events on the view, and returns if the + /// event was /// handled. /// /// @@ -252,10 +253,19 @@ public partial class View // Keyboard APIs /// first. /// /// - /// If the focused sub view does not handle the key press, this method calls to allow the - /// view to pre-process the key press. If returns , this method then - /// calls to invoke any key bindings. Then, only if no key bindings are - /// handled, will be called allowing the view to process the key press. + /// If the focused sub view does not handle the key press, this method raises / + /// to allow the + /// view to pre-process the key press. If / is not handled + /// / will be raised to invoke any key + /// bindings. + /// Then, only if no key bindings are + /// handled, / will be raised allowing the view to + /// process the key press. + /// + /// + /// Callling this method for a key bound to the view via an Application-scoped keybinding will have no effect. + /// Instead, + /// use . /// /// See for an overview of Terminal.Gui keyboard APIs. /// @@ -287,7 +297,8 @@ public partial class View // Keyboard APIs return true; } - if (RaiseProcessKeyDown(key) || key.Handled) + // After + if (RaiseProcessKeyDown (key) || key.Handled) { return true; } @@ -344,11 +355,11 @@ public partial class View // Keyboard APIs } } - - /// - /// Low-level API called when the user presses a key, allowing a view to pre-process the key down event. This is - /// called from before . + /// Called when the user presses a key, allowing subscribers to pre-process the key down event. Called + /// before and are raised. Set + /// to true to + /// stop the key from being processed by other views. /// /// Contains the details about the key that produced the event. /// @@ -362,14 +373,11 @@ public partial class View // Keyboard APIs /// /// Fires the event. /// - protected virtual bool OnKeyDown (Key keyEvent) - { - return false; - } + protected virtual bool OnKeyDown (Key keyEvent) { return false; } /// - /// Invoked when the user presses a key, allowing subscribers to pre-process the key down event. This is fired - /// from before . Set to true to + /// Raised when the user presses a key, allowing subscribers to pre-process the key down event. Raised + /// before and . Set to true to /// stop the key from being processed by other views. /// /// @@ -382,47 +390,39 @@ public partial class View // Keyboard APIs public event EventHandler? KeyDown; /// - /// Low-level API called when the user presses a key, allowing views do things during key down events. This is - /// called from after . + /// Called when the user presses a key, allowing views do things during key down events. This is + /// called after the after are raised. /// - /// Contains the details about the key that produced the event. - /// - /// if the key press was not handled. if the keypress was handled - /// and no other view should see it. - /// /// /// - /// Override to override the behavior of how the base class processes key down - /// events. - /// - /// /// For processing s and commands, use and /// instead. /// - /// Fires the event. /// /// Not all terminals support distinct key up notifications; applications should avoid depending on distinct /// KeyUp events. /// /// - protected virtual bool OnProcessKeyDown (Key keyEvent) - { - return keyEvent.Handled; - } + /// Contains the details about the key that produced the event. + /// + /// if the key press was not handled. if the keypress was handled + /// and no other view should see it. + /// + protected virtual bool OnProcessKeyDown (Key keyEvent) { return keyEvent.Handled; } /// - /// Invoked when the user presses a key, allowing subscribers to do things during key down events. Set + /// Raised when the user presses a key, allowing subscribers to do things during key down events. Set /// to true to stop the key from being processed by other views. Invoked after - /// and before . + /// and . /// /// /// - /// SubViews can use the of their super view override the default behavior of when - /// key bindings are invoked. + /// For processing s and commands, use and + /// instead. /// /// - /// Not all terminals support distinct key up notifications; applications should avoid depending on distinct - /// KeyUp events. + /// SubViews can use the of their super view override the default behavior of when + /// key bindings are invoked. /// /// See for an overview of Terminal.Gui keyboard APIs. /// @@ -433,8 +433,9 @@ public partial class View // Keyboard APIs #region KeyUp Event /// - /// If the view is enabled, processes a new key up event and returns if the event was - /// handled. Called before . + /// If the view is enabled, raises the related key up events on the view, and returns if the + /// event was + /// handled. /// /// /// @@ -446,8 +447,9 @@ public partial class View // Keyboard APIs /// first. /// /// - /// If the focused sub view does not handle the key press, this method calls , which is - /// cancellable. + /// If the focused sub view does not handle the key press, this method raises / + /// to allow the + /// view to pre-process the key press. If /. /// /// See for an overview of Terminal.Gui keyboard APIs. /// @@ -460,11 +462,16 @@ public partial class View // Keyboard APIs return false; } + // Before if (RaiseKeyUp (key) || key.Handled) { return true; } + // During + + // After + return false; bool RaiseKeyUp (Key key) @@ -482,7 +489,6 @@ public partial class View // Keyboard APIs } } - /// Method invoked when a key is released. This method is called from . /// Contains the details about the key that produced the event. /// @@ -498,10 +504,7 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - public virtual bool OnKeyUp (Key keyEvent) - { - return false; - } + public virtual bool OnKeyUp (Key keyEvent) { return false; } /// /// Invoked when a key is released. Set to true to stop the key up event from being processed @@ -537,7 +540,8 @@ public partial class View // Keyboard APIs /// The scope. /// /// if no event was raised; input proessing should continue. - /// if the event was raised and was not handled (or cancelled); input proessing should continue. + /// if the event was raised and was not handled (or cancelled); input proessing should + /// continue. /// if the event was raised and handled (or cancelled); input proessing should stop. /// public virtual bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) @@ -715,7 +719,8 @@ public partial class View // Keyboard APIs /// The scope. /// /// if no command was invoked; input proessing should continue. - /// if at least one command was invoked and was not handled (or cancelled); input proessing should continue. + /// if at least one command was invoked and was not handled (or cancelled); input proessing + /// should continue. /// if at least one command was invoked and handled (or cancelled); input proessing should stop. /// protected bool? InvokeKeyBindings (Key key, KeyBindingScope scope) From ee196fec48327b2fc0651d168ea79e8b505dc347 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 08:41:22 -0600 Subject: [PATCH 05/35] WIP: Keyboard event improvements --- Terminal.Gui/View/View.Keyboard.cs | 147 +++++++++------------ Terminal.Gui/Views/Menu/Menu.cs | 4 +- Terminal.Gui/Views/ScrollView.cs | 2 +- Terminal.Gui/Views/TextField.cs | 2 +- Terminal.Gui/Views/TextView.cs | 2 +- UICatalog/Scenarios/VkeyPacketSimulator.cs | 2 +- UnitTests/View/KeyboardEventTests.cs | 28 ++-- 7 files changed, 83 insertions(+), 104 deletions(-) diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index c3ccd8ca9..c1a28a5b9 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -292,16 +292,17 @@ public partial class View // Keyboard APIs // During (this is what can be cancelled) - if (RaiseInvokingKeyBindings (key) || key.Handled) + if (RaiseInvokingKeyBindingsAndInvokeCommands (key) is not false || key.Handled) + { + return true; + } + + if (RaiseProcessKeyDown (key) || key.Handled) { return true; } // After - if (RaiseProcessKeyDown (key) || key.Handled) - { - return true; - } return key.Handled; @@ -319,28 +320,6 @@ public partial class View // Keyboard APIs return key.Handled; } - bool RaiseInvokingKeyBindings (Key key) - { - // BUGBUG: The proper pattern is for the v-method (OnInvokingKeyBindings) to be called first, then the event - InvokingKeyBindings?.Invoke (this, key); - - if (key.Handled) - { - return true; - } - - // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommand can be reflected up stack - - bool? handled = OnInvokingKeyBindings (key, KeyBindingScope.HotKey | KeyBindingScope.Focused); - - if (handled is { } && (bool)handled) - { - return true; - } - - return false; - } - bool RaiseProcessKeyDown (Key key) { // BUGBUG: The proper pattern is for the v-method (OnProcessKeyDown) to be called first, then the event @@ -529,70 +508,78 @@ public partial class View // Keyboard APIs private Dictionary CommandImplementations { get; } = new (); /// - /// Low-level API called when a user presses a key; invokes any key bindings set on the view. This is called - /// during after has returned. + /// /// - /// - /// Fires the event. - /// See for an overview of Terminal.Gui keyboard APIs. - /// - /// Contains the details about the key that produced the event. - /// The scope. - /// - /// if no event was raised; input proessing should continue. - /// if the event was raised and was not handled (or cancelled); input proessing should - /// continue. - /// if the event was raised and handled (or cancelled); input proessing should stop. - /// - public virtual bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + /// + /// + /// + internal bool? RaiseInvokingKeyBindingsAndInvokeCommands (Key key) { + // Before // fire event only if there's a hotkey binding for the key - if (KeyBindings.TryGet (keyEvent, scope, out KeyBinding kb)) + if (!KeyBindings.TryGet (key, KeyBindingScope.Focused | KeyBindingScope.HotKey, out KeyBinding kb)) { - InvokingKeyBindings?.Invoke (this, keyEvent); - - if (keyEvent.Handled) - { - return true; - } + return null; } + KeyBindingScope scope = kb.Scope; + + // During + // BUGBUG: The proper pattern is for the v-method (OnInvokingKeyBindings) to be called first, then the event + InvokingKeyBindings?.Invoke (this, key); + + if (key.Handled) + { + return true; + } + + // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommand can be reflected up stac + bool? handled = OnInvokingKeyBindings (key, scope); + + if (handled is { } && (bool)handled) + { + return true; + } + + // After + // * If no key binding was found, `InvokeKeyBindings` returns `null`. // Continue passing the event (return `false` from `OnInvokeKeyBindings`). // * If key bindings were found, but none handled the key (all `Command`s returned `false`), // `InvokeKeyBindings` returns `false`. Continue passing the event (return `false` from `OnInvokeKeyBindings`).. // * If key bindings were found, and any handled the key (at least one `Command` returned `true`), // `InvokeKeyBindings` returns `true`. Continue passing the event (return `false` from `OnInvokeKeyBindings`). - bool? handled = InvokeKeyBindings (keyEvent, scope); + handled = InvokeCommands (key, scope); if (handled is { } && (bool)handled) { // Stop processing if any key binding handled the key. // DO NOT stop processing if there are no matching key bindings or none of the key bindings handled the key - return true; + return handled; } - if (Margin is { } && ProcessAdornmentKeyBindings (Margin, keyEvent, scope, ref handled)) + if (Margin is { } && ProcessAdornmentKeyBindings (Margin, key, scope, ref handled)) { return true; } - if (Padding is { } && ProcessAdornmentKeyBindings (Padding, keyEvent, scope, ref handled)) + if (Padding is { } && ProcessAdornmentKeyBindings (Padding, key, scope, ref handled)) { return true; } - if (Border is { } && ProcessAdornmentKeyBindings (Border, keyEvent, scope, ref handled)) + if (Border is { } && ProcessAdornmentKeyBindings (Border, key, scope, ref handled)) { return true; } - if (ProcessSubViewKeyBindings (keyEvent, scope, ref handled)) + if (ProcessSubViewKeyBindings (key, scope, ref handled)) { return true; } return handled; + } private bool ProcessAdornmentKeyBindings (Adornment adornment, Key keyEvent, KeyBindingScope scope, ref bool? handled) @@ -705,6 +692,28 @@ public partial class View // Keyboard APIs return false; } + + /// + /// Low-level API called when a user presses a key; invokes any key bindings set on the view. This is called + /// during after has returned. + /// + /// + /// Fires the event. + /// See for an overview of Terminal.Gui keyboard APIs. + /// + /// Contains the details about the key that produced the event. + /// The scope. + /// + /// if no event was raised; input proessing should continue. + /// if the event was raised and was not handled (or cancelled); input proessing should + /// continue. + /// if the event was raised and handled (or cancelled); input proessing should stop. + /// + protected virtual bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + { + return false; + } + /// /// Raised when a key is pressed that may be mapped to a key binding. Set to true to /// stop the key from being processed by other views. @@ -712,7 +721,7 @@ public partial class View // Keyboard APIs public event EventHandler? InvokingKeyBindings; /// - /// Invokes any binding that is registered on this and matches the + /// Invokes the Commands bound to . /// See for an overview of Terminal.Gui keyboard APIs. /// /// The key event passed. @@ -723,7 +732,7 @@ public partial class View // Keyboard APIs /// should continue. /// if at least one command was invoked and handled (or cancelled); input proessing should stop. /// - protected bool? InvokeKeyBindings (Key key, KeyBindingScope scope) + protected bool? InvokeCommands (Key key, KeyBindingScope scope) { bool? toReturn = null; @@ -753,30 +762,6 @@ public partial class View // Keyboard APIs #endif return InvokeCommands (binding.Commands, key, binding); - - foreach (Command command in binding.Commands) - { - if (!CommandImplementations.ContainsKey (command)) - { - throw new NotSupportedException ( - @$"A KeyBinding was set up for the command {command} ({key}) but that command is not supported by this View ({GetType ().Name})" - ); - } - - // each command has its own return value - bool? thisReturn = InvokeCommand (command, key, binding); - - // if we haven't got anything yet, the current command result should be used - toReturn ??= thisReturn; - - // if ever see a true then that's what we will return - if (thisReturn ?? false) - { - toReturn = true; - } - } - - return toReturn; } #endregion Key Bindings diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index 1744251f3..7d7715a53 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -306,7 +306,7 @@ internal sealed class Menu : View } /// - public override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + protected override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) { bool? handled = base.OnInvokingKeyBindings (keyEvent, scope); @@ -317,7 +317,7 @@ internal sealed class Menu : View // TODO: Determine if there's a cleaner way to handle this. // This supports the case where the menu bar is a context menu - return _host.OnInvokingKeyBindings (keyEvent, scope); + return _host.RaiseInvokingKeyBindingsAndInvokeCommands (keyEvent); } private void Current_TerminalResized (object? sender, SizeChangedEventArgs e) diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 6a2c6ffbe..9ad1a75f1 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -395,7 +395,7 @@ public class ScrollView : View return true; } - bool? result = InvokeKeyBindings (a, KeyBindingScope.HotKey | KeyBindingScope.Focused); + bool? result = InvokeCommands (a, KeyBindingScope.HotKey | KeyBindingScope.Focused); if (result is { }) { diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 984f151f4..b27cd82e0 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -1014,7 +1014,7 @@ public class TextField : View } /// - public override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) + protected override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) { // Give autocomplete first opportunity to respond to key presses if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (a)) diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index f5436ea96..770e4293b 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3664,7 +3664,7 @@ public class TextView : View } /// - public override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) + protected override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) { if (!a.IsValid) { diff --git a/UICatalog/Scenarios/VkeyPacketSimulator.cs b/UICatalog/Scenarios/VkeyPacketSimulator.cs index 6bea34c91..059203ea7 100644 --- a/UICatalog/Scenarios/VkeyPacketSimulator.cs +++ b/UICatalog/Scenarios/VkeyPacketSimulator.cs @@ -108,7 +108,7 @@ public class VkeyPacketSimulator : Scenario if (_outputStarted) { // If the key wasn't handled by the TextView will popup a Dialog with the keys pressed. - bool? handled = tvOutput.OnInvokingKeyBindings (e, KeyBindingScope.HotKey | KeyBindingScope.Focused); + bool? handled = tvOutput.NewKeyDownEvent (e); if (handled == null || handled == false) { diff --git a/UnitTests/View/KeyboardEventTests.cs b/UnitTests/View/KeyboardEventTests.cs index d60e4ec35..fc601590c 100644 --- a/UnitTests/View/KeyboardEventTests.cs +++ b/UnitTests/View/KeyboardEventTests.cs @@ -224,7 +224,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsContinued); + Assert.False (view.OnInvokingKeyBindingsCalled); e.Handled = true; invokingKeyBindings = true; }; @@ -244,7 +244,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.False (keyPressed); Assert.True (view.OnKeyDownCalled); - Assert.False (view.OnInvokingKeyBindingsContinued); + Assert.False (view.OnInvokingKeyBindingsCalled); Assert.False (view.OnKeyPressedContinued); } @@ -272,7 +272,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsContinued); + Assert.False (view.OnInvokingKeyBindingsCalled); e.Handled = true; invokingKeyBindings = true; }; @@ -292,7 +292,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.False (keyPressed); Assert.True (view.OnKeyDownCalled); - Assert.False (view.OnInvokingKeyBindingsContinued); + Assert.False (view.OnInvokingKeyBindingsCalled); Assert.False (view.OnKeyPressedContinued); } @@ -361,7 +361,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsContinued); + Assert.False (view.OnInvokingKeyBindingsCalled); e.Handled = false; invokingKeyBindings = true; }; @@ -381,7 +381,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (keyPressed); Assert.True (view.OnKeyDownCalled); - Assert.True (view.OnInvokingKeyBindingsContinued); + Assert.True (view.OnInvokingKeyBindingsCalled); Assert.False (view.OnKeyPressedContinued); } @@ -408,7 +408,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyUpCalled); Assert.False (view.OnKeyDownCalled); - Assert.False (view.OnInvokingKeyBindingsContinued); + Assert.False (view.OnInvokingKeyBindingsCalled); Assert.False (view.OnKeyPressedContinued); } @@ -421,7 +421,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews var view = new KeyBindingsTestView (); view.CommandReturns = toReturn; - bool? result = view.OnInvokingKeyBindings (Key.A, KeyBindingScope.HotKey | KeyBindingScope.Focused); + bool? result = view.RaiseInvokingKeyBindingsAndInvokeCommands (Key.A); Assert.Equal (expected, result); } @@ -443,22 +443,16 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { public OnKeyTestView () { CanFocus = true; } public bool CancelVirtualMethods { set; private get; } - public bool OnInvokingKeyBindingsContinued { get; set; } + public bool OnInvokingKeyBindingsCalled { get; set; } public bool OnKeyDownCalled { get; set; } public bool OnKeyPressedContinued { get; set; } public bool OnKeyUpCalled { get; set; } public override string Text { get; set; } - public override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + protected override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) { - bool? handled = base.OnInvokingKeyBindings (keyEvent, scope); - if (handled != null && (bool)handled) - { - return true; - } - - OnInvokingKeyBindingsContinued = true; + OnInvokingKeyBindingsCalled = true; return CancelVirtualMethods; } From 6df071fbe1e420efee7ffd2fb626d3b0f624cea4 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 12:32:41 -0600 Subject: [PATCH 06/35] Fixed. Added event.md --- Terminal.Gui/View/View.Keyboard.cs | 70 +++++----- Terminal.Gui/Views/Menu/Menu.cs | 16 +-- Terminal.Gui/Views/TextField.cs | 2 +- Terminal.Gui/Views/TextView.cs | 2 +- .../View/{ => Keyboard}/KeyboardEventTests.cs | 76 +++++------ UnitTests/Views/MenuBarTests.cs | 2 +- docfx/docs/events.md | 126 ++++++++++++++++++ 7 files changed, 207 insertions(+), 87 deletions(-) rename UnitTests/View/{ => Keyboard}/KeyboardEventTests.cs (86%) create mode 100644 docfx/docs/events.md diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index c1a28a5b9..cf7f9cdf1 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -1,5 +1,6 @@ #nullable enable using System.Diagnostics; +using Microsoft.CodeAnalysis.FlowAnalysis; namespace Terminal.Gui; @@ -292,17 +293,20 @@ public partial class View // Keyboard APIs // During (this is what can be cancelled) - if (RaiseInvokingKeyBindingsAndInvokeCommands (key) is not false || key.Handled) - { - return true; - } + // TODO: NewKeyDownEvent returns bool. It should be bool? so state of RaiseInvokingKeyBindingsAndInvokeCommands can be reflected up stack - if (RaiseProcessKeyDown (key) || key.Handled) + + if (RaiseInvokingKeyBindingsAndInvokeCommands (key) is true || key.Handled) { return true; } // After + // TODO: Is ProcessKeyDown really the right name? + if (RaiseProcessKeyDown (key) || key.Handled) + { + return true; + } return key.Handled; @@ -322,14 +326,13 @@ public partial class View // Keyboard APIs bool RaiseProcessKeyDown (Key key) { - // BUGBUG: The proper pattern is for the v-method (OnProcessKeyDown) to be called first, then the event - ProcessKeyDown?.Invoke (this, key); - - if (!key.Handled && OnProcessKeyDown (key)) + if (OnProcessKeyDown (key) || key.Handled) { return true; } + ProcessKeyDown?.Invoke (this, key); + return false; } } @@ -512,17 +515,22 @@ public partial class View // Keyboard APIs /// /// /// - /// + /// + /// if no command was invoked or there was no matching key binding; input processing should continue. + /// if a command was invoked and was not handled (or cancelled); input processing should + /// continue. + /// if was handled or a command was invoked and handled (or cancelled); input processing should stop. + /// internal bool? RaiseInvokingKeyBindingsAndInvokeCommands (Key key) { - // Before - // fire event only if there's a hotkey binding for the key - if (!KeyBindings.TryGet (key, KeyBindingScope.Focused | KeyBindingScope.HotKey, out KeyBinding kb)) - { - return null; - } + //// Before + //// fire event only if there's a hotkey binding for the key + //if (!KeyBindings.TryGet (key, KeyBindingScope.Focused | KeyBindingScope.HotKey, out KeyBinding kb)) + //{ + // return null; + //} - KeyBindingScope scope = kb.Scope; + KeyBindingScope scope = KeyBindingScope.Focused | KeyBindingScope.HotKey; // During // BUGBUG: The proper pattern is for the v-method (OnInvokingKeyBindings) to be called first, then the event @@ -533,14 +541,13 @@ public partial class View // Keyboard APIs return true; } - // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommand can be reflected up stac - bool? handled = OnInvokingKeyBindings (key, scope); - - if (handled is { } && (bool)handled) + if (OnInvokingKeyBindings (key, scope)) { return true; } + bool? handled; + // After // * If no key binding was found, `InvokeKeyBindings` returns `null`. @@ -636,7 +643,7 @@ public partial class View // Keyboard APIs return true; } - bool? subViewHandled = subview.OnInvokingKeyBindings (keyEvent, scope); + bool? subViewHandled = subview.RaiseInvokingKeyBindingsAndInvokeCommands (keyEvent); if (subViewHandled is { }) { @@ -694,26 +701,25 @@ public partial class View // Keyboard APIs /// - /// Low-level API called when a user presses a key; invokes any key bindings set on the view. This is called - /// during after has returned. + /// Called when a key is pressed that may be mapped to a key binding. Set to true to + /// stop the key from being processed by other views. /// /// - /// Fires the event. /// See for an overview of Terminal.Gui keyboard APIs. /// /// Contains the details about the key that produced the event. /// The scope. /// - /// if no event was raised; input proessing should continue. - /// if the event was raised and was not handled (or cancelled); input proessing should + /// if the event was raised and was not handled (or cancelled); input processing should /// continue. - /// if the event was raised and handled (or cancelled); input proessing should stop. + /// if the event was raised and handled (or cancelled); input processing should stop. /// - protected virtual bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + protected virtual bool OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) { return false; } + // TODO: This does not carry KeyBindingScope, but OnInvokingKeyBindings does /// /// Raised when a key is pressed that may be mapped to a key binding. Set to true to /// stop the key from being processed by other views. @@ -727,10 +733,10 @@ public partial class View // Keyboard APIs /// The key event passed. /// The scope. /// - /// if no command was invoked; input proessing should continue. - /// if at least one command was invoked and was not handled (or cancelled); input proessing + /// if no command was invoked; input processing should continue. + /// if at least one command was invoked and was not handled (or cancelled); input processing /// should continue. - /// if at least one command was invoked and handled (or cancelled); input proessing should stop. + /// if at least one command was invoked and handled (or cancelled); input processing should stop. /// protected bool? InvokeCommands (Key key, KeyBindingScope scope) { diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index 7d7715a53..9ee580d49 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -305,19 +305,11 @@ internal sealed class Menu : View return true; } - /// - protected override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + /// + protected override bool OnProcessKeyDown (Key keyEvent) { - bool? handled = base.OnInvokingKeyBindings (keyEvent, scope); - - if (handled is { } && (bool)handled) - { - return true; - } - - // TODO: Determine if there's a cleaner way to handle this. - // This supports the case where the menu bar is a context menu - return _host.RaiseInvokingKeyBindingsAndInvokeCommands (keyEvent); + // We didn't handle the key, pass it on to host + return _host.RaiseInvokingKeyBindingsAndInvokeCommands (keyEvent) == true; } private void Current_TerminalResized (object? sender, SizeChangedEventArgs e) diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index b27cd82e0..d1cfed3b1 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -1014,7 +1014,7 @@ public class TextField : View } /// - protected override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) + protected override bool OnInvokingKeyBindings (Key a, KeyBindingScope scope) { // Give autocomplete first opportunity to respond to key presses if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (a)) diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 770e4293b..4cc86bf2f 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3664,7 +3664,7 @@ public class TextView : View } /// - protected override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) + protected override bool OnInvokingKeyBindings (Key a, KeyBindingScope scope) { if (!a.IsValid) { diff --git a/UnitTests/View/KeyboardEventTests.cs b/UnitTests/View/Keyboard/KeyboardEventTests.cs similarity index 86% rename from UnitTests/View/KeyboardEventTests.cs rename to UnitTests/View/Keyboard/KeyboardEventTests.cs index fc601590c..ae597a596 100644 --- a/UnitTests/View/KeyboardEventTests.cs +++ b/UnitTests/View/Keyboard/KeyboardEventTests.cs @@ -12,7 +12,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews /// [Theory] [MemberData (nameof (AllViewTypes))] - public void AllViews_KeyDown_All_EventsFire (Type viewType) + public void AllViews_NewKeyDownEvent_All_EventsFire (Type viewType) { var view = CreateInstanceIfNotGeneric (viewType); @@ -49,7 +49,8 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews keyDownProcessed = true; }; - Assert.True (view.NewKeyDownEvent (Key.A)); // this will be true because the ProcessKeyDown event handled it + // Key.Empty is invalid, but it's used here to test that the event is fired + Assert.True (view.NewKeyDownEvent (Key.Empty)); // this will be true because the ProcessKeyDown event handled it Assert.True (keyDown); Assert.True (invokingKeyBindings); Assert.True (keyDownProcessed); @@ -62,7 +63,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews /// [Theory] [MemberData (nameof (AllViewTypes))] - public void AllViews_KeyUp_All_EventsFire (Type viewType) + public void AllViews_NewKeyUpEvent_All_EventsFire (Type viewType) { var view = CreateInstanceIfNotGeneric (viewType); @@ -92,13 +93,13 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews [InlineData (true, false, false)] [InlineData (true, true, false)] [InlineData (true, true, true)] - public void Events_Are_Called_With_Only_Key_Modifiers (bool shift, bool alt, bool control) + public void NewKeyDownUpEvents_Events_Are_Raised_With_Only_Key_Modifiers (bool shift, bool alt, bool control) { var keyDown = false; var keyPressed = false; var keyUp = false; - var view = new OnKeyTestView (); + var view = new OnNewKeyTestView (); view.CancelVirtualMethods = false; view.KeyDown += (s, e) => @@ -139,7 +140,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews ); Assert.True (keyPressed); Assert.True (view.OnKeyDownCalled); - Assert.True (view.OnKeyPressedContinued); + Assert.True (view.OnProcessKeyDownCalled); view.NewKeyUpEvent ( new ( @@ -154,7 +155,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews } [Fact] - public void InvokingKeyBindings_Handled_Cancels () + public void NewKeyDownEvent_InvokingKeyBindings_Handled_Cancels () { var view = new View (); var keyPressInvoked = false; @@ -201,13 +202,13 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews } [Fact] - public void InvokingKeyBindings_Handled_True_Stops_Processing () + public void NewKeyDownEvent_InvokingKeyBindings_Handled_True_Stops_Processing () { var keyDown = false; var invokingKeyBindings = false; var keyPressed = false; - var view = new OnKeyTestView (); + var view = new OnNewKeyTestView (); Assert.True (view.CanFocus); view.CancelVirtualMethods = false; @@ -233,7 +234,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); - Assert.False (view.OnKeyPressedContinued); + Assert.False (view.OnProcessKeyDownCalled); e.Handled = true; keyPressed = true; }; @@ -245,17 +246,17 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyDownCalled); Assert.False (view.OnInvokingKeyBindingsCalled); - Assert.False (view.OnKeyPressedContinued); + Assert.False (view.OnProcessKeyDownCalled); } [Fact] - public void KeyDown_Handled_True_Stops_Processing () + public void NewKeyDownEvent_Handled_True_Stops_Processing () { var keyDown = false; var invokingKeyBindings = false; var keyPressed = false; - var view = new OnKeyTestView (); + var view = new OnNewKeyTestView (); Assert.True (view.CanFocus); view.CancelVirtualMethods = false; @@ -281,7 +282,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); - Assert.False (view.OnKeyPressedContinued); + Assert.False (view.OnProcessKeyDownCalled); e.Handled = true; keyPressed = true; }; @@ -293,11 +294,11 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyDownCalled); Assert.False (view.OnInvokingKeyBindingsCalled); - Assert.False (view.OnKeyPressedContinued); + Assert.False (view.OnProcessKeyDownCalled); } [Fact] - public void KeyPress_Handled_Cancels () + public void NewKeyDownEvent_KeyDown_Handled_Stops_Processing () { var view = new View (); var invokingKeyBindingsInvoked = false; @@ -338,13 +339,13 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews } [Fact] - public void KeyPressed_Handled_True_Stops_Processing () + public void NewKeyDownEvent_ProcessKeyDown_Handled_Stops_Processing () { var keyDown = false; var invokingKeyBindings = false; - var keyPressed = false; + var processKeyDown = false; - var view = new OnKeyTestView (); + var view = new OnNewKeyTestView (); Assert.True (view.CanFocus); view.CancelVirtualMethods = false; @@ -360,7 +361,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews view.InvokingKeyBindings += (s, e) => { Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); + Assert.False (processKeyDown); Assert.False (view.OnInvokingKeyBindingsCalled); e.Handled = false; invokingKeyBindings = true; @@ -369,28 +370,28 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews view.ProcessKeyDown += (s, e) => { Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnKeyPressedContinued); + Assert.False (processKeyDown); + Assert.True (view.OnProcessKeyDownCalled); e.Handled = true; - keyPressed = true; + processKeyDown = true; }; view.NewKeyDownEvent (Key.A); Assert.True (keyDown); Assert.True (invokingKeyBindings); - Assert.True (keyPressed); + Assert.True (processKeyDown); Assert.True (view.OnKeyDownCalled); Assert.True (view.OnInvokingKeyBindingsCalled); - Assert.False (view.OnKeyPressedContinued); + Assert.True (view.OnProcessKeyDownCalled); } [Fact] - public void KeyUp_Handled_True_Stops_Processing () + public void NewKeyUpEvent_KeyUp_Handled_True_Stops_Processing () { var keyUp = false; - var view = new OnKeyTestView (); + var view = new OnNewKeyTestView (); Assert.True (view.CanFocus); view.CancelVirtualMethods = false; @@ -398,7 +399,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyUp); - Assert.False (view.OnKeyPressedContinued); + Assert.False (view.OnProcessKeyDownCalled); e.Handled = true; keyUp = true; }; @@ -409,14 +410,14 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyUpCalled); Assert.False (view.OnKeyDownCalled); Assert.False (view.OnInvokingKeyBindingsCalled); - Assert.False (view.OnKeyPressedContinued); + Assert.False (view.OnProcessKeyDownCalled); } [Theory] [InlineData (null, null)] [InlineData (true, true)] [InlineData (false, false)] - public void OnInvokingKeyBindings_Returns_Nullable_Properly (bool? toReturn, bool? expected) + public void RaiseInvokingKeyBindingsAndInvokeCommands_Returns_Nullable_Properly (bool? toReturn, bool? expected) { var view = new KeyBindingsTestView (); view.CommandReturns = toReturn; @@ -439,17 +440,17 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews } /// A view that overrides the OnKey* methods so we can test that they are called. - public class OnKeyTestView : View + public class OnNewKeyTestView : View { - public OnKeyTestView () { CanFocus = true; } + public OnNewKeyTestView () { CanFocus = true; } public bool CancelVirtualMethods { set; private get; } public bool OnInvokingKeyBindingsCalled { get; set; } public bool OnKeyDownCalled { get; set; } - public bool OnKeyPressedContinued { get; set; } + public bool OnProcessKeyDownCalled { get; set; } public bool OnKeyUpCalled { get; set; } public override string Text { get; set; } - protected override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + protected override bool OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) { OnInvokingKeyBindingsCalled = true; @@ -473,12 +474,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews protected override bool OnProcessKeyDown (Key keyEvent) { - if (base.OnProcessKeyDown (keyEvent)) - { - return true; - } - - OnKeyPressedContinued = true; + OnProcessKeyDownCalled = true; return CancelVirtualMethods; } diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 736e79890..849d9b8f4 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -1384,7 +1384,7 @@ wo foreach (Key key in keys) { - top.NewKeyDownEvent (new (key)); + top.NewKeyDownEvent (key); Application.MainLoop.RunIteration (); } diff --git a/docfx/docs/events.md b/docfx/docs/events.md new file mode 100644 index 000000000..19e853f6a --- /dev/null +++ b/docfx/docs/events.md @@ -0,0 +1,126 @@ +# Terminal.Gui Event Deep Dive + +Terminal.Gui exposes and uses events in many places. This deep dive covers the patterns used, where they are used, and notes any exceptions. + +## Tenets for Terminal.Gui Events (Unless you know better ones...) + +Tenets higher in the list have precedence over tenets lower in the list. + +* **UI Interaction and Live Data Are Different Beasts** - TG distinguishes between events used for human interaction and events for live data. We don't believe in a one-size-fits-all eventing model. For UI interactions we use `EventHandler`. For data binding we think `INotifyPropertyChanged` is groovy. For some callbacks we use `Action`. + +## Lexicon and Taxonomy + +* *Action* +* *Event* +* *Command* +* *Invoke* +* *Raise* +* *Listen* +* *Handle/Handling/Handled* - Applies to scenarios where an event can either be handled by an event listener (or override) vs not handled. Events that originate from a user action like mouse moves and key presses are examples. +* *Cancel/Cancelling/Cancelled* - Applies to scenarios where something can be cancelled. Changing the `Orientation` of a `Slider` is cancelable. + +## Useful External Documentation + +* [.NET Naming Guidelines - Names of Events](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members?redirectedfrom=MSDN#names-of-events) +* [.NET Design for Extensibility - Events and Callbacks](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/events-and-callbacks) +* [C# Event Implementation Fundamentals, Best Practices and Conventions](https://www.codeproject.com/Articles/20550/C-Event-Implementation-Fundamentals-Best-Practices) + +## Naming + +TG follows the *naming* advice provided in [.NET Naming Guidelines - Names of Events](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members?redirectedfrom=MSDN#names-of-events). + +## `EventHandler` style event best-practices + +* Implement a helper method for raising the event: `RaisexxxEvent`. + * If the event is cancelable, the return type should be either `bool` or `bool?`. + * Can be `private`, `internal`, or `public` depending on the situation. `internal` should only be used to enable unit tests. +* Raising an event involves FIRST calling the `protected virtual` method, THEN invoking the `EventHandler. + +## `Action` style callback best-practices + +- tbd + +## `INotifyPropertyChanged` style notification best practices + +- tbd + +## Common Patterns + +The primary pattern for events is the `event/EventHandler` idiom. We use the `Action` idiom sparingly. We support `INotifyPropertyChanged` in cases where data binding is relevant. + + + +## Cancellable Event Pattern + +A cancellable event is really two events and some activity that takes place between those events. The "pre-event" happens before the activity. The activity then takes place (or not). If the activity takes place, then the "post-event" is typically raised. So, to be precise, no event is being cancelled even though we say we have a cancellable event. Rather, the activity that takes place between the two events is what is cancelled — and likely prevented from starting at all. + +### **Before** - If any pre-conditions are met raise the "pre-event", typically named in the form of "xxxChanging". e.g. + + - A `protected virtual` method is called. This method is named `OnxxxChanging` and the base implementation simply does `return false`. + - If the `OnxxxChanging` method returns `true` it means a derived class canceled the event. Processing should stop. + - Otherwise, the `xxxChanging` event is invoked via `xxxChanging?.Invoke(args)`. If `args.Cancel/Handled == true` it means a subscriber has cancelled the event. Processing should stop. + + +### **During** - Do work. + +### **After** - Raise the "post-event", typically named in the form of "xxxChanged" + + - A `protected virtual` method is called. This method is named `OnxxxChanged` has a return type of `void`. + - The `xxxChanged` event is invoked via `xxxChanging?.Invoke(args)`. + +The `OrientationHelper` class supporting `IOrientation` and a `View` having an `Orientation` property illustrates the preferred TG pattern for cancelable events. + +```cs + /// + /// Gets or sets the orientation of the View. + /// + public Orientation Orientation + { + get => _orientation; + set + { + if (_orientation == value) + { + return; + } + + // Best practice is to invoke the virtual method first. + // This allows derived classes to handle the event and potentially cancel it. + if (_owner?.OnOrientationChanging (value, _orientation) ?? false) + { + return; + } + + // If the event is not canceled by the virtual method, raise the event to notify any external subscribers. + CancelEventArgs args = new (in _orientation, ref value); + OrientationChanging?.Invoke (_owner, args); + + if (args.Cancel) + { + return; + } + + // If the event is not canceled, update the value. + Orientation old = _orientation; + + if (_orientation != value) + { + _orientation = value; + + if (_owner is { }) + { + _owner.Orientation = value; + } + } + + // Best practice is to invoke the virtual method first. + _owner?.OnOrientationChanged (_orientation); + + // Even though Changed is not cancelable, it is still a good practice to raise the event after. + OrientationChanged?.Invoke (_owner, new (in _orientation)); + } + } +``` + + + From 84b271947a205f2ada39fc596e7784f11c90b79a Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 12:43:14 -0600 Subject: [PATCH 07/35] Fixed InvokingKeyBindings event semantics --- .../View/Orientation/OrientationHelper.cs | 6 +- Terminal.Gui/View/View.Keyboard.cs | 89 ++++++++----------- UnitTests/View/Keyboard/KeyboardEventTests.cs | 6 +- docfx/docs/events.md | 84 ++++++++--------- 4 files changed, 85 insertions(+), 100 deletions(-) diff --git a/Terminal.Gui/View/Orientation/OrientationHelper.cs b/Terminal.Gui/View/Orientation/OrientationHelper.cs index 33c33c70f..380dfbb53 100644 --- a/Terminal.Gui/View/Orientation/OrientationHelper.cs +++ b/Terminal.Gui/View/Orientation/OrientationHelper.cs @@ -69,7 +69,7 @@ public class OrientationHelper return; } - // Best practice is to invoke the virtual method first. + // Best practice is to call the virtual method first. // This allows derived classes to handle the event and potentially cancel it. if (_owner?.OnOrientationChanging (value, _orientation) ?? false) { @@ -98,10 +98,8 @@ public class OrientationHelper } } - // Best practice is to invoke the virtual method first. + // Best practice is to call the virtual method first, then raise the event. _owner?.OnOrientationChanged (_orientation); - - // Even though Changed is not cancelable, it is still a good practice to raise the event after. OrientationChanged?.Invoke (_owner, new (in _orientation)); } } diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index cf7f9cdf1..e3b2ab2ba 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -219,7 +219,7 @@ public partial class View // Keyboard APIs private void SetHotKeyFromTitle () { - if (TitleTextFormatter == null || HotKeySpecifier == new Rune ('\xFFFF')) + if (HotKeySpecifier == new Rune ('\xFFFF')) { return; // throw new InvalidOperationException ("Can't set HotKey unless a TextFormatter has been created"); } @@ -264,7 +264,7 @@ public partial class View // Keyboard APIs /// process the key press. /// /// - /// Callling this method for a key bound to the view via an Application-scoped keybinding will have no effect. + /// Calling this method for a key bound to the view via an Application-scoped keybinding will have no effect. /// Instead, /// use . /// @@ -294,8 +294,6 @@ public partial class View // Keyboard APIs // During (this is what can be cancelled) // TODO: NewKeyDownEvent returns bool. It should be bool? so state of RaiseInvokingKeyBindingsAndInvokeCommands can be reflected up stack - - if (RaiseInvokingKeyBindingsAndInvokeCommands (key) is true || key.Handled) { return true; @@ -310,28 +308,28 @@ public partial class View // Keyboard APIs return key.Handled; - bool RaiseKeyDown (Key key) + bool RaiseKeyDown (Key k) { // Before (fire the cancellable event) - if (OnKeyDown (key) || key.Handled) + if (OnKeyDown (k) || k.Handled) { return true; } // fire event - KeyDown?.Invoke (this, key); + KeyDown?.Invoke (this, k); - return key.Handled; + return k.Handled; } - bool RaiseProcessKeyDown (Key key) + bool RaiseProcessKeyDown (Key k) { - if (OnProcessKeyDown (key) || key.Handled) + if (OnProcessKeyDown (k) || k.Handled) { return true; } - ProcessKeyDown?.Invoke (this, key); + ProcessKeyDown?.Invoke (this, k); return false; } @@ -343,7 +341,7 @@ public partial class View // Keyboard APIs /// to true to /// stop the key from being processed by other views. /// - /// Contains the details about the key that produced the event. + /// Contains the details about the key that produced the event. /// /// if the key press was not handled. if the keypress was handled /// and no other view should see it. @@ -355,7 +353,7 @@ public partial class View // Keyboard APIs /// /// Fires the event. /// - protected virtual bool OnKeyDown (Key keyEvent) { return false; } + protected virtual bool OnKeyDown (Key key) { return false; } /// /// Raised when the user presses a key, allowing subscribers to pre-process the key down event. Raised @@ -385,12 +383,12 @@ public partial class View // Keyboard APIs /// KeyUp events. /// /// - /// Contains the details about the key that produced the event. + /// Contains the details about the key that produced the event. /// /// if the key press was not handled. if the keypress was handled /// and no other view should see it. /// - protected virtual bool OnProcessKeyDown (Key keyEvent) { return keyEvent.Handled; } + protected virtual bool OnProcessKeyDown (Key key) { return key.Handled; } /// /// Raised when the user presses a key, allowing subscribers to do things during key down events. Set @@ -456,25 +454,25 @@ public partial class View // Keyboard APIs return false; - bool RaiseKeyUp (Key key) + bool RaiseKeyUp (Key k) { // Before (fire the cancellable event) - if (OnKeyUp (key) || key.Handled) + if (OnKeyUp (k) || k.Handled) { return true; } // fire event - KeyUp?.Invoke (this, key); + KeyUp?.Invoke (this, k); - return key.Handled; + return k.Handled; } } /// Method invoked when a key is released. This method is called from . - /// Contains the details about the key that produced the event. + /// Contains the details about the key that produced the event. /// - /// if the key stroke was not handled. if no other view should see + /// if the keys up event was not handled. if no other view should see /// it. /// /// @@ -486,7 +484,7 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - public virtual bool OnKeyUp (Key keyEvent) { return false; } + public virtual bool OnKeyUp (Key key) { return false; } /// /// Invoked when a key is released. Set to true to stop the key up event from being processed @@ -514,7 +512,6 @@ public partial class View // Keyboard APIs /// /// /// - /// /// /// if no command was invoked or there was no matching key binding; input processing should continue. /// if a command was invoked and was not handled (or cancelled); input processing should @@ -523,25 +520,18 @@ public partial class View // Keyboard APIs /// internal bool? RaiseInvokingKeyBindingsAndInvokeCommands (Key key) { - //// Before - //// fire event only if there's a hotkey binding for the key - //if (!KeyBindings.TryGet (key, KeyBindingScope.Focused | KeyBindingScope.HotKey, out KeyBinding kb)) - //{ - // return null; - //} - KeyBindingScope scope = KeyBindingScope.Focused | KeyBindingScope.HotKey; // During - // BUGBUG: The proper pattern is for the v-method (OnInvokingKeyBindings) to be called first, then the event - InvokingKeyBindings?.Invoke (this, key); - - if (key.Handled) + if (OnInvokingKeyBindings (key, scope)) { return true; } - if (OnInvokingKeyBindings (key, scope)) + // BUGBUG: The proper pattern is for the v-method (OnInvokingKeyBindings) to be called first, then the event + InvokingKeyBindings?.Invoke (this, key); + + if (key.Handled) { return true; } @@ -589,9 +579,9 @@ public partial class View // Keyboard APIs } - private bool ProcessAdornmentKeyBindings (Adornment adornment, Key keyEvent, KeyBindingScope scope, ref bool? handled) + private bool ProcessAdornmentKeyBindings (Adornment adornment, Key key, KeyBindingScope scope, ref bool? handled) { - bool? adornmentHandled = adornment.OnInvokingKeyBindings (keyEvent, scope); + bool? adornmentHandled = adornment.OnInvokingKeyBindings (key, scope); if (adornmentHandled is true) { @@ -605,7 +595,7 @@ public partial class View // Keyboard APIs foreach (View subview in adornment.Subviews) { - bool? subViewHandled = subview.OnInvokingKeyBindings (keyEvent, scope); + bool? subViewHandled = subview.OnInvokingKeyBindings (key, scope); if (subViewHandled is { }) { @@ -621,7 +611,7 @@ public partial class View // Keyboard APIs return false; } - private bool ProcessSubViewKeyBindings (Key keyEvent, KeyBindingScope scope, ref bool? handled, bool invoke = true) + private bool ProcessSubViewKeyBindings (Key key, KeyBindingScope scope, ref bool? handled, bool invoke = true) { // Now, process any key bindings in the subviews that are tagged to KeyBindingScope.HotKey. foreach (View subview in Subviews) @@ -631,7 +621,7 @@ public partial class View // Keyboard APIs continue; } - if (subview.KeyBindings.TryGet (keyEvent, scope, out KeyBinding binding)) + if (subview.KeyBindings.TryGet (key, scope, out KeyBinding binding)) { if (binding.Scope == KeyBindingScope.Focused && !subview.HasFocus) { @@ -643,7 +633,7 @@ public partial class View // Keyboard APIs return true; } - bool? subViewHandled = subview.RaiseInvokingKeyBindingsAndInvokeCommands (keyEvent); + bool? subViewHandled = subview.RaiseInvokingKeyBindingsAndInvokeCommands (key); if (subViewHandled is { }) { @@ -656,7 +646,7 @@ public partial class View // Keyboard APIs } } - bool recurse = subview.ProcessSubViewKeyBindings (keyEvent, scope, ref handled, invoke); + bool recurse = subview.ProcessSubViewKeyBindings (key, scope, ref handled, invoke); if (recurse || (handled is { } && (bool)handled)) { @@ -676,7 +666,7 @@ public partial class View // Keyboard APIs /// The key to test. /// Returns the view the key is bound to. /// - public bool IsHotKeyKeyBound (Key key, out View? boundView) + public bool IsHotKeyBound (Key key, out View? boundView) { // recurse through the subviews to find the views that has the key bound boundView = null; @@ -690,7 +680,7 @@ public partial class View // Keyboard APIs return true; } - if (subview.IsHotKeyKeyBound (key, out boundView)) + if (subview.IsHotKeyBound (key, out boundView)) { return true; } @@ -707,14 +697,14 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - /// Contains the details about the key that produced the event. + /// Contains the details about the key that produced the event. /// The scope. /// /// if the event was raised and was not handled (or cancelled); input processing should /// continue. /// if the event was raised and handled (or cancelled); input processing should stop. /// - protected virtual bool OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + protected virtual bool OnInvokingKeyBindings (Key key, KeyBindingScope scope) { return false; } @@ -749,19 +739,16 @@ public partial class View // Keyboard APIs #if DEBUG - // TODO: Determine if App scope bindings should be fired first or last (currently last). if (Application.KeyBindings.TryGet (key, KeyBindingScope.Focused | KeyBindingScope.HotKey, out KeyBinding b)) { - //var boundView = views [0]; - //var commandBinding = boundView.KeyBindings.Get (key); Debug.WriteLine ( - $"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command."); //{commandBinding.Commands [0]}: {boundView}."); + $"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command."); } // TODO: This is a "prototype" debug check. It may be too annoying vs. useful. // Scour the bindings up our View hierarchy // to ensure that the key is not already bound to a different set of commands. - if (SuperView?.IsHotKeyKeyBound (key, out View? previouslyBoundView) ?? false) + if (SuperView?.IsHotKeyBound (key, out View? previouslyBoundView) ?? false) { Debug.WriteLine ($"WARNING: InvokeKeyBindings ({key}) - A subview or peer has bound this Key and will not see it: {previouslyBoundView}."); } diff --git a/UnitTests/View/Keyboard/KeyboardEventTests.cs b/UnitTests/View/Keyboard/KeyboardEventTests.cs index ae597a596..471016231 100644 --- a/UnitTests/View/Keyboard/KeyboardEventTests.cs +++ b/UnitTests/View/Keyboard/KeyboardEventTests.cs @@ -225,7 +225,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsCalled); + Assert.True (view.OnInvokingKeyBindingsCalled); e.Handled = true; invokingKeyBindings = true; }; @@ -245,7 +245,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.False (keyPressed); Assert.True (view.OnKeyDownCalled); - Assert.False (view.OnInvokingKeyBindingsCalled); + Assert.True (view.OnInvokingKeyBindingsCalled); Assert.False (view.OnProcessKeyDownCalled); } @@ -362,7 +362,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (processKeyDown); - Assert.False (view.OnInvokingKeyBindingsCalled); + Assert.True (view.OnInvokingKeyBindingsCalled); e.Handled = false; invokingKeyBindings = true; }; diff --git a/docfx/docs/events.md b/docfx/docs/events.md index 19e853f6a..56580a7a4 100644 --- a/docfx/docs/events.md +++ b/docfx/docs/events.md @@ -71,56 +71,56 @@ A cancellable event is really two events and some activity that takes place betw The `OrientationHelper` class supporting `IOrientation` and a `View` having an `Orientation` property illustrates the preferred TG pattern for cancelable events. ```cs - /// - /// Gets or sets the orientation of the View. - /// - public Orientation Orientation - { - get => _orientation; - set - { - if (_orientation == value) - { - return; - } + /// + /// Gets or sets the orientation of the View. + /// + public Orientation Orientation + { + get => _orientation; + set + { + if (_orientation == value) + { + return; + } - // Best practice is to invoke the virtual method first. - // This allows derived classes to handle the event and potentially cancel it. - if (_owner?.OnOrientationChanging (value, _orientation) ?? false) - { - return; - } + // Best practice is to call the virtual method first. + // This allows derived classes to handle the event and potentially cancel it. + if (_owner?.OnOrientationChanging (value, _orientation) ?? false) + { + return; + } - // If the event is not canceled by the virtual method, raise the event to notify any external subscribers. - CancelEventArgs args = new (in _orientation, ref value); - OrientationChanging?.Invoke (_owner, args); + // If the event is not canceled by the virtual method, raise the event to notify any external subscribers. + CancelEventArgs args = new (in _orientation, ref value); + OrientationChanging?.Invoke (_owner, args); - if (args.Cancel) - { - return; - } + if (args.Cancel) + { + return; + } - // If the event is not canceled, update the value. - Orientation old = _orientation; + // If the event is not canceled, update the value. + Orientation old = _orientation; - if (_orientation != value) - { - _orientation = value; + if (_orientation != value) + { + _orientation = value; - if (_owner is { }) - { - _owner.Orientation = value; - } - } + if (_owner is { }) + { + _owner.Orientation = value; + } + } - // Best practice is to invoke the virtual method first. - _owner?.OnOrientationChanged (_orientation); - - // Even though Changed is not cancelable, it is still a good practice to raise the event after. - OrientationChanged?.Invoke (_owner, new (in _orientation)); - } - } + // Best practice is to call the virtual method first, then raise the event. + _owner?.OnOrientationChanged (_orientation); + OrientationChanged?.Invoke (_owner, new (in _orientation)); + } + } ``` + ## `bool` or `bool?` + From c19cc7c332db278caeb4cf6c6a182d78da2f3d44 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 14:06:27 -0600 Subject: [PATCH 08/35] Code cleanup --- Terminal.Gui/View/View.Keyboard.cs | 108 +++++++++--------- Terminal.Gui/Views/DateField.cs | 2 +- Terminal.Gui/Views/HexView.cs | 2 +- Terminal.Gui/Views/Menu/Menu.cs | 2 +- Terminal.Gui/Views/TextField.cs | 21 +--- Terminal.Gui/Views/TextValidateField.cs | 2 +- Terminal.Gui/Views/TextView.cs | 2 +- Terminal.Gui/Views/TileView.cs | 2 +- Terminal.Gui/Views/TimeField.cs | 2 +- Terminal.Gui/Views/Wizard/Wizard.cs | 4 +- UnitTests/View/Keyboard/KeyboardEventTests.cs | 16 +-- UnitTests/View/ViewTests.cs | 2 +- 12 files changed, 72 insertions(+), 93 deletions(-) diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index e3b2ab2ba..2bb4b3da6 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -27,7 +27,7 @@ public partial class View // Keyboard APIs #region HotKey Support - /// Invoked when the is changed. + /// Raised when the is changed. public event EventHandler? HotKeyChanged; private Key _hotKey = new (); @@ -254,13 +254,13 @@ public partial class View // Keyboard APIs /// first. /// /// - /// If the focused sub view does not handle the key press, this method raises / + /// If a more focused subview does not handle the key press, this method raises / /// to allow the /// view to pre-process the key press. If / is not handled /// / will be raised to invoke any key /// bindings. /// Then, only if no key bindings are - /// handled, / will be raised allowing the view to + /// handled, / will be raised allowing the view to /// process the key press. /// /// @@ -301,7 +301,7 @@ public partial class View // Keyboard APIs // After // TODO: Is ProcessKeyDown really the right name? - if (RaiseProcessKeyDown (key) || key.Handled) + if (RaiseKeyDownNotHandled (key) || key.Handled) { return true; } @@ -322,14 +322,14 @@ public partial class View // Keyboard APIs return k.Handled; } - bool RaiseProcessKeyDown (Key k) + bool RaiseKeyDownNotHandled (Key k) { - if (OnProcessKeyDown (k) || k.Handled) + if (OnKeyDownNotHandled (k) || k.Handled) { return true; } - ProcessKeyDown?.Invoke (this, k); + KeyDownNotHandled?.Invoke (this, k); return false; } @@ -337,14 +337,14 @@ public partial class View // Keyboard APIs /// /// Called when the user presses a key, allowing subscribers to pre-process the key down event. Called - /// before and are raised. Set + /// before and are raised. Set /// to true to - /// stop the key from being processed by other views. + /// stop the key from being processed further. /// - /// Contains the details about the key that produced the event. + /// The key that produced the event. /// - /// if the key press was not handled. if the keypress was handled - /// and no other view should see it. + /// if the key down event was not handled. if the event was handled + /// and processing should stop. /// /// /// @@ -356,9 +356,10 @@ public partial class View // Keyboard APIs protected virtual bool OnKeyDown (Key key) { return false; } /// - /// Raised when the user presses a key, allowing subscribers to pre-process the key down event. Raised - /// before and . Set to true to - /// stop the key from being processed by other views. + /// Raised when the user presses a key, allowing subscribers to pre-process the key down event. Called + /// before and are raised. Set + /// to true to + /// stop the key from being processed further. /// /// /// @@ -370,8 +371,7 @@ public partial class View // Keyboard APIs public event EventHandler? KeyDown; /// - /// Called when the user presses a key, allowing views do things during key down events. This is - /// called after the after are raised. + /// Called when the user has pressed key it wasn't handled by and was not bound to a key binding. /// /// /// @@ -388,12 +388,10 @@ public partial class View // Keyboard APIs /// if the key press was not handled. if the keypress was handled /// and no other view should see it. /// - protected virtual bool OnProcessKeyDown (Key key) { return key.Handled; } + protected virtual bool OnKeyDownNotHandled (Key key) { return key.Handled; } /// - /// Raised when the user presses a key, allowing subscribers to do things during key down events. Set - /// to true to stop the key from being processed by other views. Invoked after - /// and . + /// Raised when the user has pressed key it wasn't handled by and was not bound to a key binding. /// /// /// @@ -401,12 +399,12 @@ public partial class View // Keyboard APIs /// instead. /// /// - /// SubViews can use the of their super view override the default behavior of when + /// SubViews can use the of their super view override the default behavior of when /// key bindings are invoked. /// /// See for an overview of Terminal.Gui keyboard APIs. /// - public event EventHandler? ProcessKeyDown; + public event EventHandler? KeyDownNotHandled; #endregion KeyDown Event @@ -469,7 +467,7 @@ public partial class View // Keyboard APIs } } - /// Method invoked when a key is released. This method is called from . + /// Called when a key is released. This method is called from . /// Contains the details about the key that produced the event. /// /// if the keys up event was not handled. if no other view should see @@ -487,7 +485,7 @@ public partial class View // Keyboard APIs public virtual bool OnKeyUp (Key key) { return false; } /// - /// Invoked when a key is released. Set to true to stop the key up event from being processed + /// Raised when a key is released. Set to true to stop the key up event from being processed /// by other views. /// /// Not all terminals support key distinct down/up notifications, Applications should avoid depending on @@ -509,7 +507,7 @@ public partial class View // Keyboard APIs private Dictionary CommandImplementations { get; } = new (); /// - /// + /// INTERNAL API: Raises the event and invokes the commands bound to . /// /// /// @@ -576,12 +574,37 @@ public partial class View // Keyboard APIs } return handled; - } + /// + /// Called when a key is pressed that may be mapped to a key binding. Set to true to + /// stop the key from being processed by other views. + /// + /// + /// See for an overview of Terminal.Gui keyboard APIs. + /// + /// Contains the details about the key that produced the event. + /// The scope. + /// + /// if the event was raised and was not handled (or cancelled); input processing should + /// continue. + /// if the event was raised and handled (or cancelled); input processing should stop. + /// + protected virtual bool OnInvokingKeyBindings (Key key, KeyBindingScope scope) + { + return false; + } + + // TODO: This does not carry KeyBindingScope, but OnInvokingKeyBindings does + /// + /// Raised when a key is pressed that may be mapped to a key binding. Set to true to + /// stop the key from being processed by other views. + /// + public event EventHandler? InvokingKeyBindings; + private bool ProcessAdornmentKeyBindings (Adornment adornment, Key key, KeyBindingScope scope, ref bool? handled) { - bool? adornmentHandled = adornment.OnInvokingKeyBindings (key, scope); + bool? adornmentHandled = adornment.RaiseInvokingKeyBindingsAndInvokeCommands (key); if (adornmentHandled is true) { @@ -595,7 +618,7 @@ public partial class View // Keyboard APIs foreach (View subview in adornment.Subviews) { - bool? subViewHandled = subview.OnInvokingKeyBindings (key, scope); + bool? subViewHandled = subview.RaiseInvokingKeyBindingsAndInvokeCommands (key); if (subViewHandled is { }) { @@ -689,33 +712,6 @@ public partial class View // Keyboard APIs return false; } - - /// - /// Called when a key is pressed that may be mapped to a key binding. Set to true to - /// stop the key from being processed by other views. - /// - /// - /// See for an overview of Terminal.Gui keyboard APIs. - /// - /// Contains the details about the key that produced the event. - /// The scope. - /// - /// if the event was raised and was not handled (or cancelled); input processing should - /// continue. - /// if the event was raised and handled (or cancelled); input processing should stop. - /// - protected virtual bool OnInvokingKeyBindings (Key key, KeyBindingScope scope) - { - return false; - } - - // TODO: This does not carry KeyBindingScope, but OnInvokingKeyBindings does - /// - /// Raised when a key is pressed that may be mapped to a key binding. Set to true to - /// stop the key from being processed by other views. - /// - public event EventHandler? InvokingKeyBindings; - /// /// Invokes the Commands bound to . /// See for an overview of Terminal.Gui keyboard APIs. diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 43060c0a5..49da4f100 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -131,7 +131,7 @@ public class DateField : TextField public virtual void OnDateChanged (DateTimeEventArgs args) { DateChanged?.Invoke (this, args); } /// - protected override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDownNotHandled (Key a) { // Ignore non-numeric characters. if (a >= Key.D0 && a <= Key.D9) diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index 8f7e3c1a0..a5a213b82 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -452,7 +452,7 @@ public class HexView : View, IDesignable public virtual void OnPositionChanged () { PositionChanged?.Invoke (this, new HexViewEventArgs (Position, CursorPosition, BytesPerLine)); } /// - protected override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key keyEvent) { if (!AllowEdits) { diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index 9ee580d49..b3429b190 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -306,7 +306,7 @@ internal sealed class Menu : View } /// - protected override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key keyEvent) { // We didn't handle the key, pass it on to host return _host.RaiseInvokingKeyBindingsAndInvokeCommands (keyEvent) == true; diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index d1cfed3b1..cb6d2e82a 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -1037,25 +1037,8 @@ public class TextField : View // ClearAllSelection (); } - /// TODO: Flush out these docs - /// - /// Processes key presses for the . - /// - /// The control responds to the following keys: - /// - /// - /// Keys Function - /// - /// - /// , - /// Deletes the character before cursor. - /// - /// - /// - /// - /// - /// - protected override bool OnProcessKeyDown (Key a) + /// + protected override bool OnKeyDownNotHandled (Key a) { // Remember the cursor position because the new calculated cursor position is needed // to be set BEFORE the TextChanged event is triggered. diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index 579b22f56..c6927b5e3 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -597,7 +597,7 @@ namespace Terminal.Gui } /// - protected override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDownNotHandled (Key a) { if (_provider is null) { diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 4cc86bf2f..97ccc47a9 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3703,7 +3703,7 @@ public class TextView : View } /// - protected override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDownNotHandled (Key a) { if (!CanFocus) { diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index 4adbb5b1b..ec117c652 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -286,7 +286,7 @@ public class TileView : View //// BUGBUG: Why is this not handled by a key binding??? /// - protected override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key keyEvent) { var focusMoved = false; diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index 305a3ce59..687a8cd71 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -177,7 +177,7 @@ public class TimeField : TextField } /// - protected override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDownNotHandled (Key a) { // Ignore non-numeric characters. if (a.KeyCode is >= (KeyCode)(int)KeyCode.D0 and <= (KeyCode)(int)KeyCode.D9) diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index 338328b02..b9bc49bd5 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -381,12 +381,12 @@ public class Wizard : Dialog /// /// is derived from and Dialog causes Esc to call /// , closing the Dialog. Wizard overrides - /// to instead fire the event when Wizard is being used as a + /// to instead fire the event when Wizard is being used as a /// non-modal (see ). /// /// /// - protected override bool OnProcessKeyDown (Key key) + protected override bool OnKeyDownNotHandled (Key key) { //// BUGBUG: Why is this not handled by a key binding??? if (!Modal) diff --git a/UnitTests/View/Keyboard/KeyboardEventTests.cs b/UnitTests/View/Keyboard/KeyboardEventTests.cs index 471016231..6b484ec58 100644 --- a/UnitTests/View/Keyboard/KeyboardEventTests.cs +++ b/UnitTests/View/Keyboard/KeyboardEventTests.cs @@ -43,7 +43,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews var keyDownProcessed = false; - view.ProcessKeyDown += (s, a) => + view.KeyDownNotHandled += (s, a) => { a.Handled = true; keyDownProcessed = true; @@ -112,7 +112,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyDownCalled); keyDown = true; }; - view.ProcessKeyDown += (s, e) => { keyPressed = true; }; + view.KeyDownNotHandled += (s, e) => { keyPressed = true; }; view.KeyUp += (s, e) => { @@ -178,7 +178,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.Equal (KeyCode.N, e.KeyCode); }; - view.ProcessKeyDown += (s, e) => + view.KeyDownNotHandled += (s, e) => { processKeyPressInvoked = true; processKeyPressInvoked = true; @@ -230,7 +230,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews invokingKeyBindings = true; }; - view.ProcessKeyDown += (s, e) => + view.KeyDownNotHandled += (s, e) => { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); @@ -278,7 +278,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews invokingKeyBindings = true; }; - view.ProcessKeyDown += (s, e) => + view.KeyDownNotHandled += (s, e) => { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (keyPressed); @@ -319,7 +319,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.Equal (KeyCode.N, e.KeyCode); }; - view.ProcessKeyDown += (s, e) => + view.KeyDownNotHandled += (s, e) => { processKeyPressInvoked = true; Assert.False (e.Handled); @@ -367,7 +367,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews invokingKeyBindings = true; }; - view.ProcessKeyDown += (s, e) => + view.KeyDownNotHandled += (s, e) => { Assert.Equal (KeyCode.A, e.KeyCode); Assert.False (processKeyDown); @@ -472,7 +472,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews return CancelVirtualMethods; } - protected override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key keyEvent) { OnProcessKeyDownCalled = true; diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index 54b9b31b5..1dc072e3a 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -1146,7 +1146,7 @@ At 0,0 return true; } - protected override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key keyEvent) { IsKeyPress = true; From f536945df5a8e26c2345790720b978369ba27df5 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 14:19:48 -0600 Subject: [PATCH 09/35] Application.Keyboard Code cleanup --- .../Application/Application.Initialization.cs | 2 +- .../Application/Application.Keyboard.cs | 246 +++++------------- Terminal.Gui/Application/Application.Run.cs | 35 +++ Terminal.Gui/View/View.Keyboard.cs | 26 +- UnitTests/Application/KeyboardTests.cs | 58 ++--- UnitTests/Dialogs/MessageBoxTests.cs | 10 +- UnitTests/FileServices/FileDialogTests.cs | 6 +- UnitTests/UICatalog/ScenarioTests.cs | 2 +- UnitTests/View/HotKeyTests.cs | 6 +- UnitTests/View/Navigation/CanFocusTests.cs | 2 +- UnitTests/View/Navigation/NavigationTests.cs | 22 +- UnitTests/View/ViewKeyBindingTests.cs | 22 +- UnitTests/Views/ButtonTests.cs | 12 +- UnitTests/Views/ColorPickerTests.cs | 46 ++-- UnitTests/Views/ComboBoxTests.cs | 88 +++---- UnitTests/Views/ContextMenuTests.cs | 82 +++--- UnitTests/Views/DatePickerTests.cs | 2 +- UnitTests/Views/LabelTests.cs | 4 +- UnitTests/Views/MenuBarTests.cs | 4 +- UnitTests/Views/RadioGroupTests.cs | 66 ++--- UnitTests/Views/ShortcutTests.cs | 10 +- UnitTests/Views/StatusBarTests.cs | 2 +- UnitTests/Views/TabViewTests.cs | 30 +-- UnitTests/Views/TableViewTests.cs | 22 +- UnitTests/Views/TextFieldTests.cs | 6 +- UnitTests/Views/ToplevelTests.cs | 40 +-- UnitTests/Views/TreeTableSourceTests.cs | 2 +- 27 files changed, 387 insertions(+), 466 deletions(-) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index 4fb11621d..640c9b5f5 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -178,7 +178,7 @@ public static partial class Application // Initialization (Init/Shutdown) } private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } - private static void Driver_KeyDown (object? sender, Key e) { OnKeyDown (e); } + private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); } private static void Driver_KeyUp (object? sender, Key e) { OnKeyUp (e); } private static void Driver_MouseEvent (object? sender, MouseEvent e) { OnMouseEvent (e); } diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs index 01545dedd..a73e7cb86 100644 --- a/Terminal.Gui/Application/Application.Keyboard.cs +++ b/Terminal.Gui/Application/Application.Keyboard.cs @@ -3,91 +3,16 @@ namespace Terminal.Gui; public static partial class Application // Keyboard handling { - private static Key _nextTabGroupKey = Key.F6; // Resources/config.json overrrides - private static Key _nextTabKey = Key.Tab; // Resources/config.json overrrides - private static Key _prevTabGroupKey = Key.F6.WithShift; // Resources/config.json overrrides - private static Key _prevTabKey = Key.Tab.WithShift; // Resources/config.json overrrides - private static Key _quitKey = Key.Esc; // Resources/config.json overrrides - private static Key _arrangeKey = Key.F5.WithCtrl; // Resources/config.json overrrides - - static Application () { AddApplicationKeyBindings (); } - - /// Gets the key bindings for this view. - public static KeyBindings KeyBindings { get; internal set; } = new (); - /// - /// Event fired when the user presses a key. Fired by . - /// - /// Set to to indicate the key was handled and to prevent - /// additional processing. - /// - /// - /// - /// All drivers support firing the event. Some drivers (Curses) do not support firing the - /// and events. - /// Fired after and before . - /// - public static event EventHandler? KeyDown; - - /// - /// Event fired when the user releases a key. Fired by . - /// - /// Set to to indicate the key was handled and to prevent - /// additional processing. - /// - /// - /// - /// All drivers support firing the event. Some drivers (Curses) do not support firing the - /// and events. - /// Fired after . - /// - public static event EventHandler? KeyUp; - - /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key NextTabGroupKey - { - get => _nextTabGroupKey; - set - { - if (_nextTabGroupKey != value) - { - ReplaceKey (_nextTabGroupKey, value); - _nextTabGroupKey = value; - } - } - } - - /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key NextTabKey - { - get => _nextTabKey; - set - { - if (_nextTabKey != value) - { - ReplaceKey (_nextTabKey, value); - _nextTabKey = value; - } - } - } - - /// - /// Called by the when the user presses a key. Fires the event - /// then calls on all top level views. Called after and - /// before . + /// Called when the user presses a key (by the ). Raises the cancelable + /// event + /// then calls on all top level views. Called before . /// /// Can be used to simulate key press events. /// /// if the key was handled. - public static bool OnKeyDown (Key keyEvent) + public static bool RaiseKeyDownEvent (Key keyEvent) { - //if (!IsInitialized) - //{ - // return true; - //} - KeyDown?.Invoke (null, keyEvent); if (keyEvent.Handled) @@ -150,43 +75,50 @@ public static partial class Application // Keyboard handling } return false; + + static bool? InvokeCommand (Command command, Key keyEvent, KeyBinding appBinding) + { + if (!CommandImplementations!.ContainsKey (command)) + { + throw new NotSupportedException ( + @$"A KeyBinding was set up for the command {command} ({keyEvent}) but that command is not supported by Application." + ); + } + + if (CommandImplementations.TryGetValue (command, out View.CommandImplementation? implementation)) + { + var context = new CommandContext (command, keyEvent, appBinding); // Create the context here + + return implementation (context); + } + + return false; + } } /// - /// INTENRAL method to invoke one of the commands in + /// Raised when the user presses a key. + /// + /// Set to to indicate the key was handled and to prevent + /// additional processing. + /// /// - /// - /// - /// - /// - /// - private static bool? InvokeCommand (Command command, Key keyEvent, KeyBinding appBinding) - { - if (!CommandImplementations!.ContainsKey (command)) - { - throw new NotSupportedException ( - @$"A KeyBinding was set up for the command {command} ({keyEvent}) but that command is not supported by Application." - ); - } - - if (CommandImplementations.TryGetValue (command, out View.CommandImplementation? implementation)) - { - var context = new CommandContext (command, keyEvent, appBinding); // Create the context here - - return implementation (context); - } - - return false; - } + /// + /// All drivers support firing the event. Some drivers (Curses) do not support firing the + /// and events. + /// Fired after and before . + /// + public static event EventHandler? KeyDown; /// - /// Called by the when the user releases a key. Fires the event - /// then calls on all top level views. Called after . + /// Called when the user releases a key (by the ). Raises the cancelable + /// event + /// then calls on all top level views. Called after . /// - /// Can be used to simulate key press events. + /// Can be used to simulate key release events. /// /// if the key was handled. - public static bool OnKeyUp (Key a) + public static bool RaiseKeyUpEvent (Key a) { if (!IsInitialized) { @@ -216,65 +148,12 @@ public static partial class Application // Keyboard handling return false; } - /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key PrevTabGroupKey - { - get => _prevTabGroupKey; - set - { - if (_prevTabGroupKey != value) - { - ReplaceKey (_prevTabGroupKey, value); - _prevTabGroupKey = value; - } - } - } + #region Application-scoped KeyBindings - /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key PrevTabKey - { - get => _prevTabKey; - set - { - if (_prevTabKey != value) - { - ReplaceKey (_prevTabKey, value); - _prevTabKey = value; - } - } - } + static Application () { AddApplicationKeyBindings (); } - /// Gets or sets the key to quit the application. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key QuitKey - { - get => _quitKey; - set - { - if (_quitKey != value) - { - ReplaceKey (_quitKey, value); - _quitKey = value; - } - } - } - - /// Gets or sets the key to activate arranging views using the keyboard. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key ArrangeKey - { - get => _arrangeKey; - set - { - if (_arrangeKey != value) - { - ReplaceKey (_arrangeKey, value); - _arrangeKey = value; - } - } - } + /// Gets the Application-scoped key bindings. + public static KeyBindings KeyBindings { get; internal set; } = new (); internal static void AddApplicationKeyBindings () { @@ -286,6 +165,7 @@ public static partial class Application // Keyboard handling static () => { RequestStop (); + return true; } ); @@ -348,7 +228,7 @@ public static partial class Application // Keyboard handling KeyBindings.Clear (); - // Resources/config.json overrrides + // Resources/config.json overrides NextTabKey = Key.Tab; PrevTabKey = Key.Tab.WithShift; NextTabGroupKey = Key.F6; @@ -397,6 +277,26 @@ public static partial class Application // Keyboard handling .ToList (); } + private static void ReplaceKey (Key oldKey, Key newKey) + { + if (KeyBindings.Bindings.Count == 0) + { + return; + } + + if (newKey == Key.Empty) + { + KeyBindings.Remove (oldKey); + } + else + { + KeyBindings.ReplaceKey (oldKey, newKey); + } + } + + + #endregion Application-scoped KeyBindings + /// /// /// Sets the function that will be invoked for a . @@ -420,20 +320,4 @@ public static partial class Application // Keyboard handling /// private static Dictionary? CommandImplementations { get; set; } - private static void ReplaceKey (Key oldKey, Key newKey) - { - if (KeyBindings.Bindings.Count == 0) - { - return; - } - - if (newKey == Key.Empty) - { - KeyBindings.Remove (oldKey); - } - else - { - KeyBindings.ReplaceKey (oldKey, newKey); - } - } } diff --git a/Terminal.Gui/Application/Application.Run.cs b/Terminal.Gui/Application/Application.Run.cs index 4a1d89541..e3c78bdd7 100644 --- a/Terminal.Gui/Application/Application.Run.cs +++ b/Terminal.Gui/Application/Application.Run.cs @@ -6,6 +6,41 @@ namespace Terminal.Gui; public static partial class Application // Run (Begin, Run, End, Stop) { + private static Key _quitKey = Key.Esc; // Resources/config.json overrides + + /// Gets or sets the key to quit the application. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key QuitKey + { + get => _quitKey; + set + { + if (_quitKey != value) + { + ReplaceKey (_quitKey, value); + _quitKey = value; + } + } + } + + private static Key _arrangeKey = Key.F5.WithCtrl; // Resources/config.json overrides + + + /// Gets or sets the key to activate arranging views using the keyboard. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key ArrangeKey + { + get => _arrangeKey; + set + { + if (_arrangeKey != value) + { + ReplaceKey (_arrangeKey, value); + _arrangeKey = value; + } + } + } + // When `End ()` is called, it is possible `RunState.Toplevel` is a different object than `Top`. // This variable is set in `End` in this case so that `Begin` correctly sets `Top`. private static Toplevel? _cachedRunStateToplevel; diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index 2bb4b3da6..992f29e2f 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -1,6 +1,5 @@ #nullable enable using System.Diagnostics; -using Microsoft.CodeAnalysis.FlowAnalysis; namespace Terminal.Gui; @@ -266,7 +265,7 @@ public partial class View // Keyboard APIs /// /// Calling this method for a key bound to the view via an Application-scoped keybinding will have no effect. /// Instead, - /// use . + /// use . /// /// See for an overview of Terminal.Gui keyboard APIs. /// @@ -337,7 +336,8 @@ public partial class View // Keyboard APIs /// /// Called when the user presses a key, allowing subscribers to pre-process the key down event. Called - /// before and are raised. Set + /// before and are raised. Set + /// /// to true to /// stop the key from being processed further. /// @@ -357,7 +357,8 @@ public partial class View // Keyboard APIs /// /// Raised when the user presses a key, allowing subscribers to pre-process the key down event. Called - /// before and are raised. Set + /// before and are raised. Set + /// /// to true to /// stop the key from being processed further. /// @@ -507,14 +508,17 @@ public partial class View // Keyboard APIs private Dictionary CommandImplementations { get; } = new (); /// - /// INTERNAL API: Raises the event and invokes the commands bound to . + /// INTERNAL API: Raises the event and invokes the commands bound to + /// . /// /// /// - /// if no command was invoked or there was no matching key binding; input processing should continue. + /// if no command was invoked or there was no matching key binding; input processing should + /// continue. /// if a command was invoked and was not handled (or cancelled); input processing should /// continue. - /// if was handled or a command was invoked and handled (or cancelled); input processing should stop. + /// if was handled or a command was invoked and handled (or + /// cancelled); input processing should stop. /// internal bool? RaiseInvokingKeyBindingsAndInvokeCommands (Key key) { @@ -590,10 +594,7 @@ public partial class View // Keyboard APIs /// continue. /// if the event was raised and handled (or cancelled); input processing should stop. /// - protected virtual bool OnInvokingKeyBindings (Key key, KeyBindingScope scope) - { - return false; - } + protected virtual bool OnInvokingKeyBindings (Key key, KeyBindingScope scope) { return false; } // TODO: This does not carry KeyBindingScope, but OnInvokingKeyBindings does /// @@ -722,7 +723,8 @@ public partial class View // Keyboard APIs /// if no command was invoked; input processing should continue. /// if at least one command was invoked and was not handled (or cancelled); input processing /// should continue. - /// if at least one command was invoked and handled (or cancelled); input processing should stop. + /// if at least one command was invoked and handled (or cancelled); input processing should + /// stop. /// protected bool? InvokeCommands (Key key, KeyBindingScope scope) { diff --git a/UnitTests/Application/KeyboardTests.cs b/UnitTests/Application/KeyboardTests.cs index 09b1bf7a3..71b93ecc4 100644 --- a/UnitTests/Application/KeyboardTests.cs +++ b/UnitTests/Application/KeyboardTests.cs @@ -64,14 +64,14 @@ public class KeyboardTests Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.True (win2.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); @@ -117,14 +117,14 @@ public class KeyboardTests Assert.False (win2.HasFocus); Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.True (win.CanFocus); Assert.True (win.HasFocus); Assert.True (win2.CanFocus); @@ -170,31 +170,31 @@ public class KeyboardTests top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.A); + Application.NewKeyDown (Key.A); Assert.False (invoked); Assert.True (view.ApplicationCommand); invoked = false; view.ApplicationCommand = false; Application.KeyBindings.Remove (KeyCode.A); - Application.OnKeyDown (Key.A); // old + Application.NewKeyDown (Key.A); // old Assert.False (invoked); Assert.False (view.ApplicationCommand); Application.KeyBindings.Add (Key.A.WithCtrl, view, Command.Save); - Application.OnKeyDown (Key.A); // old + Application.NewKeyDown (Key.A); // old Assert.False (invoked); Assert.False (view.ApplicationCommand); - Application.OnKeyDown (Key.A.WithCtrl); // new + Application.NewKeyDown (Key.A.WithCtrl); // new Assert.False (invoked); Assert.True (view.ApplicationCommand); invoked = false; - Application.OnKeyDown (Key.H); + Application.NewKeyDown (Key.H); Assert.True (invoked); invoked = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.F); + Application.NewKeyDown (Key.F); Assert.False (invoked); Assert.True (view.ApplicationCommand); @@ -215,7 +215,7 @@ public class KeyboardTests top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.A.WithCtrl); + Application.NewKeyDown (Key.A.WithCtrl); Assert.False (invoked); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); @@ -223,7 +223,7 @@ public class KeyboardTests invoked = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.Z); + Application.NewKeyDown (Key.Z); Assert.False (invoked); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); @@ -399,7 +399,7 @@ public class KeyboardTests Assert.True (subView1.HasFocus); // Act - Application.OnKeyDown (Application.NextTabGroupKey); + Application.NewKeyDown (Application.NextTabGroupKey); // Assert Assert.True (view2.HasFocus); @@ -432,24 +432,24 @@ public class KeyboardTests Assert.True (v1.HasFocus); // Across TabGroups - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.True (v3.HasFocus); - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.True (v1.HasFocus); - Application.OnKeyDown (Key.F6.WithShift); + Application.NewKeyDown (Key.F6.WithShift); Assert.True (v3.HasFocus); - Application.OnKeyDown (Key.F6.WithShift); + Application.NewKeyDown (Key.F6.WithShift); Assert.True (v1.HasFocus); // Restore? - Application.OnKeyDown (Key.Tab); + Application.NewKeyDown (Key.Tab); Assert.True (v2.HasFocus); - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.True (v3.HasFocus); - Application.OnKeyDown (Key.F6); + Application.NewKeyDown (Key.F6); Assert.True (v1.HasFocus); Application.RequestStop (); @@ -485,7 +485,7 @@ public class KeyboardTests view1.SetFocus (); // Act - Application.OnKeyDown (Application.NextTabKey); + Application.NewKeyDown (Application.NextTabKey); // Assert Assert.True (view2.HasFocus); @@ -539,7 +539,7 @@ public class KeyboardTests Assert.True (subView1.HasFocus); // Act - Application.OnKeyDown (Application.PrevTabGroupKey); + Application.NewKeyDown (Application.PrevTabGroupKey); // Assert Assert.True (view2.HasFocus); @@ -562,7 +562,7 @@ public class KeyboardTests view1.SetFocus (); // Act - Application.OnKeyDown (Application.NextTabKey); + Application.NewKeyDown (Application.NextTabKey); // Assert Assert.True (view2.HasFocus); @@ -605,21 +605,21 @@ public class KeyboardTests Key prevKey = Application.QuitKey; - Application.OnKeyDown (Application.QuitKey); + Application.NewKeyDown (Application.QuitKey); Assert.True (isQuiting); isQuiting = false; - Application.OnKeyDown (Application.QuitKey); + Application.NewKeyDown (Application.QuitKey); Assert.True (isQuiting); isQuiting = false; Application.QuitKey = Key.C.WithCtrl; - Application.OnKeyDown (prevKey); // Should not quit + Application.NewKeyDown (prevKey); // Should not quit Assert.False (isQuiting); - Application.OnKeyDown (Key.Q.WithCtrl); // Should not quit + Application.NewKeyDown (Key.Q.WithCtrl); // Should not quit Assert.False (isQuiting); - Application.OnKeyDown (Application.QuitKey); + Application.NewKeyDown (Application.QuitKey); Assert.True (isQuiting); // Reset the QuitKey to avoid throws errors on another tests @@ -728,7 +728,7 @@ public class KeyboardTests if (Application.IsInitialized) { _output.WriteLine (" Pressing QuitKey"); - Application.OnKeyDown (Application.QuitKey); + Application.NewKeyDown (Application.QuitKey); } } } diff --git a/UnitTests/Dialogs/MessageBoxTests.cs b/UnitTests/Dialogs/MessageBoxTests.cs index 541ecd9e4..caad58da5 100644 --- a/UnitTests/Dialogs/MessageBoxTests.cs +++ b/UnitTests/Dialogs/MessageBoxTests.cs @@ -33,14 +33,14 @@ public class MessageBoxTests case 2: // Tab to btn2 - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Button btn = Application.Navigation!.GetFocused () as Button; btn.Accepting += (sender, e) => { btnAcceptCount++; }; // Click - Application.OnKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); break; @@ -77,7 +77,7 @@ public class MessageBoxTests break; case 2: - Application.OnKeyDown (Key.Esc); + Application.RaiseKeyDownEvent (Key.Esc); break; @@ -116,13 +116,13 @@ public class MessageBoxTests case 2: // Tab to btn2 - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Button btn = Application.Navigation!.GetFocused () as Button; btn.Accepting += (sender, e) => { btnAcceptCount++; }; - Application.OnKeyDown (Key.Space); + Application.RaiseKeyDownEvent (Key.Space); break; diff --git a/UnitTests/FileServices/FileDialogTests.cs b/UnitTests/FileServices/FileDialogTests.cs index 28e81ef60..cb31b7462 100644 --- a/UnitTests/FileServices/FileDialogTests.cs +++ b/UnitTests/FileServices/FileDialogTests.cs @@ -140,7 +140,7 @@ public class FileDialogTests () AssertIsTheStartingDirectory (dlg.Path); Assert.IsType (dlg.MostFocused); - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); var tv = GetTableView(dlg); tv.SetFocus (); @@ -152,7 +152,7 @@ public class FileDialogTests () AssertIsTheStartingDirectory (dlg.Path); // Accept navigation up a directory - Application.OnKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); AssertIsTheRootDirectory (dlg.Path); @@ -162,7 +162,7 @@ public class FileDialogTests () Assert.IsType (dlg.MostFocused); // Now press Backspace (in table view) - Application.OnKeyDown (Key.Backspace); + Application.RaiseKeyDownEvent (Key.Backspace); // Should move us back to the root AssertIsTheStartingDirectory (dlg.Path); diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index d7549b594..4575ea5ba 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -132,7 +132,7 @@ public class ScenarioTests : TestsAllViews { // Press QuitKey //_output.WriteLine ($"Forcing Quit with {Application.QuitKey}"); - Application.OnKeyDown (Application.QuitKey); + Application.NewKeyDown (Application.QuitKey); } } } diff --git a/UnitTests/View/HotKeyTests.cs b/UnitTests/View/HotKeyTests.cs index c7032347c..a3edaaf6c 100644 --- a/UnitTests/View/HotKeyTests.cs +++ b/UnitTests/View/HotKeyTests.cs @@ -362,20 +362,20 @@ public class HotKeyTests view.Selecting += (s, e) => selectRaised = true; Assert.Equal (KeyCode.T, view.HotKey); - Assert.True (Application.OnKeyDown (Key.T)); + Assert.True (Application.RaiseKeyDownEvent (Key.T)); Assert.True (hotKeyRaised); Assert.False (acceptRaised); Assert.False (selectRaised); hotKeyRaised = false; - Assert.True (Application.OnKeyDown (Key.T.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.T.WithAlt)); Assert.True (hotKeyRaised); Assert.False (acceptRaised); Assert.False (selectRaised); hotKeyRaised = false; view.HotKey = KeyCode.E; - Assert.True (Application.OnKeyDown (Key.E.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.E.WithAlt)); Assert.True (hotKeyRaised); Assert.False (acceptRaised); Assert.False (selectRaised); diff --git a/UnitTests/View/Navigation/CanFocusTests.cs b/UnitTests/View/Navigation/CanFocusTests.cs index 006a84dd4..39fa34ad8 100644 --- a/UnitTests/View/Navigation/CanFocusTests.cs +++ b/UnitTests/View/Navigation/CanFocusTests.cs @@ -354,7 +354,7 @@ public class CanFocusTests () : TestsAllViews Assert.False (label.HasFocus); Assert.True (view.HasFocus); - Assert.True (Application.OnKeyDown (Key.Tab)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); Assert.True (label.HasFocus); Assert.False (view.HasFocus); diff --git a/UnitTests/View/Navigation/NavigationTests.cs b/UnitTests/View/Navigation/NavigationTests.cs index 12b49c129..19b4757f9 100644 --- a/UnitTests/View/Navigation/NavigationTests.cs +++ b/UnitTests/View/Navigation/NavigationTests.cs @@ -59,17 +59,17 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews case TabBehavior.TabStop: case TabBehavior.NoStop: case TabBehavior.TabGroup: - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); if (view.HasFocus) { // Try once more (HexView) - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); } break; default: - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); break; } @@ -178,18 +178,18 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews case null: case TabBehavior.NoStop: case TabBehavior.TabStop: - if (Application.OnKeyDown (Key.Tab)) + if (Application.RaiseKeyDownEvent (Key.Tab)) { if (view.HasFocus) { // Try another nav key (e.g. for TextView that eats Tab) - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); } }; break; case TabBehavior.TabGroup: - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); break; default: @@ -211,18 +211,18 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews break; case TabBehavior.TabStop: - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); break; case TabBehavior.TabGroup: - if (!Application.OnKeyDown (Key.F6)) + if (!Application.RaiseKeyDownEvent (Key.F6)) { view.SetFocus (); } break; case null: - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); break; default: @@ -308,12 +308,12 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews Assert.Equal (0, hasFocusChangingCount); Assert.Equal (0, hasFocusChangedCount); - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.Equal (0, hasFocusChangingCount); Assert.Equal (0, hasFocusChangedCount); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.Equal (0, hasFocusChangingCount); Assert.Equal (0, hasFocusChangedCount); diff --git a/UnitTests/View/ViewKeyBindingTests.cs b/UnitTests/View/ViewKeyBindingTests.cs index 2ac278a7b..05471e4b5 100644 --- a/UnitTests/View/ViewKeyBindingTests.cs +++ b/UnitTests/View/ViewKeyBindingTests.cs @@ -18,17 +18,17 @@ public class ViewKeyBindingTests (ITestOutputHelper output) top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.A); + Application.RaiseKeyDownEvent (Key.A); Assert.False (invoked); Assert.True (view.ApplicationCommand); invoked = false; - Application.OnKeyDown (Key.H); + Application.RaiseKeyDownEvent (Key.H); Assert.True (invoked); invoked = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.F); + Application.RaiseKeyDownEvent (Key.F); Assert.False (invoked); Assert.False (view.FocusedCommand); @@ -36,7 +36,7 @@ public class ViewKeyBindingTests (ITestOutputHelper output) view.CanFocus = true; view.SetFocus (); Assert.True (view.HasFocus); - Application.OnKeyDown (Key.F); + Application.RaiseKeyDownEvent (Key.F); Assert.True (invoked); Assert.True (view.ApplicationCommand); @@ -57,7 +57,7 @@ public class ViewKeyBindingTests (ITestOutputHelper output) top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.Z); + Application.RaiseKeyDownEvent (Key.Z); Assert.False (invoked); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); @@ -65,7 +65,7 @@ public class ViewKeyBindingTests (ITestOutputHelper output) invoked = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.F); + Application.RaiseKeyDownEvent (Key.F); Assert.False (invoked); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); @@ -86,18 +86,18 @@ public class ViewKeyBindingTests (ITestOutputHelper output) Application.Begin (top); invoked = false; - Application.OnKeyDown (Key.H); + Application.RaiseKeyDownEvent (Key.H); Assert.True (invoked); Assert.True (view.HotKeyCommand); view.HotKey = KeyCode.Z; invoked = false; view.HotKeyCommand = false; - Application.OnKeyDown (Key.H); // old hot key + Application.RaiseKeyDownEvent (Key.H); // old hot key Assert.False (invoked); Assert.False (view.HotKeyCommand); - Application.OnKeyDown (Key.Z); // new hot key + Application.RaiseKeyDownEvent (Key.Z); // new hot key Assert.True (invoked); Assert.True (view.HotKeyCommand); top.Dispose (); @@ -115,12 +115,12 @@ public class ViewKeyBindingTests (ITestOutputHelper output) top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.Z); + Application.RaiseKeyDownEvent (Key.Z); Assert.False (invoked); Assert.False (view.HotKeyCommand); invoked = false; - Application.OnKeyDown (Key.F); + Application.RaiseKeyDownEvent (Key.F); Assert.False (view.HotKeyCommand); top.Dispose (); } diff --git a/UnitTests/Views/ButtonTests.cs b/UnitTests/Views/ButtonTests.cs index d7f092e80..e4b4f7efd 100644 --- a/UnitTests/Views/ButtonTests.cs +++ b/UnitTests/Views/ButtonTests.cs @@ -376,7 +376,7 @@ public class ButtonTests (ITestOutputHelper output) Assert.True (btn.HasFocus); // default keybinding is Space which results in Command.Accept (when focused) - Application.OnKeyDown (new ((KeyCode)' ')); + Application.RaiseKeyDownEvent (new ((KeyCode)' ')); Assert.Equal (1, pressed); // remove the default keybinding (Space) @@ -384,26 +384,26 @@ public class ButtonTests (ITestOutputHelper output) btn.KeyBindings.Clear (Command.Accept); // After clearing the default keystroke the Space button no longer does anything for the Button - Application.OnKeyDown (new ((KeyCode)' ')); + Application.RaiseKeyDownEvent (new ((KeyCode)' ')); Assert.Equal (1, pressed); // Set a new binding of b for the click (Accept) event btn.KeyBindings.Add (Key.B, Command.HotKey); // b will now trigger the Accept command (when focused or not) // now pressing B should call the button click event - Application.OnKeyDown (Key.B); + Application.RaiseKeyDownEvent (Key.B); Assert.Equal (2, pressed); // now pressing Shift-B should NOT call the button click event - Application.OnKeyDown (Key.B.WithShift); + Application.RaiseKeyDownEvent (Key.B.WithShift); Assert.Equal (2, pressed); // now pressing Alt-B should NOT call the button click event - Application.OnKeyDown (Key.B.WithAlt); + Application.RaiseKeyDownEvent (Key.B.WithAlt); Assert.Equal (2, pressed); // now pressing Shift-Alt-B should NOT call the button click event - Application.OnKeyDown (Key.B.WithAlt.WithShift); + Application.RaiseKeyDownEvent (Key.B.WithAlt.WithShift); Assert.Equal (2, pressed); top.Dispose (); } diff --git a/UnitTests/Views/ColorPickerTests.cs b/UnitTests/Views/ColorPickerTests.cs index 0b5b050c3..57f4144c9 100644 --- a/UnitTests/Views/ColorPickerTests.cs +++ b/UnitTests/Views/ColorPickerTests.cs @@ -64,14 +64,14 @@ public class ColorPickerTests cp.Draw (); - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); cp.Draw (); Assert.Equal (3, r.TrianglePosition); Assert.Equal ("#0F0000", hex.Text); - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); cp.Draw (); @@ -81,7 +81,7 @@ public class ColorPickerTests // Use cursor to move the triangle all the way to the right for (int i = 0; i < 1000; i++) { - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); } cp.Draw (); @@ -713,19 +713,19 @@ public class ColorPickerTests name.Text = ""; Assert.Empty (name.Text); - Application.OnKeyDown (Key.A); - Application.OnKeyDown (Key.Q); + Application.RaiseKeyDownEvent (Key.A); + Application.RaiseKeyDownEvent (Key.Q); Assert.Equal ("aq", name.Text); // Auto complete the color name - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.Equal ("Aquamarine", name.Text); // Tab out of the text field - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.False (name.HasFocus); Assert.NotSame (name, cp.Focused); @@ -761,24 +761,24 @@ public class ColorPickerTests Assert.Empty (hex.Text); Assert.Empty (name.Text); - Application.OnKeyDown ('#'); + Application.RaiseKeyDownEvent ('#'); Assert.Empty (name.Text); //7FFFD4 Assert.Equal ("#", hex.Text); - Application.OnKeyDown ('7'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('D'); + Application.RaiseKeyDownEvent ('7'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('D'); Assert.Empty (name.Text); - Application.OnKeyDown ('4'); + Application.RaiseKeyDownEvent ('4'); Assert.True (hex.HasFocus); // Tab out of the hex field - should wrap to first focusable subview - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.False (hex.HasFocus); Assert.NotSame (hex, cp.Focused); @@ -819,24 +819,24 @@ public class ColorPickerTests Assert.Empty (hex.Text); Assert.Empty (name.Text); - Application.OnKeyDown ('#'); + Application.RaiseKeyDownEvent ('#'); Assert.Empty (name.Text); //7FFFD4 Assert.Equal ("#", hex.Text); - Application.OnKeyDown ('7'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('D'); + Application.RaiseKeyDownEvent ('7'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('D'); Assert.Empty (name.Text); - Application.OnKeyDown ('4'); + Application.RaiseKeyDownEvent ('4'); Assert.True (hex.HasFocus); // Should stay in the hex field (because accept not tab) - Application.OnKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); Assert.True (hex.HasFocus); Assert.Same (hex, cp.Focused); diff --git a/UnitTests/Views/ComboBoxTests.cs b/UnitTests/Views/ComboBoxTests.cs index 92cfb8c51..99a0576a0 100644 --- a/UnitTests/Views/ComboBoxTests.cs +++ b/UnitTests/Views/ComboBoxTests.cs @@ -105,13 +105,13 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.NotNull (cb.Source); Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Null (cb.Source); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -155,7 +155,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -166,7 +166,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -202,7 +202,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal ("One", cb.Text); Assert.True (cb.Subviews [1].NewKeyDownEvent (Key.CursorDown)); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -251,7 +251,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -262,7 +262,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -417,7 +417,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True ( cb.Subviews [1] @@ -441,7 +441,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True ( cb.Subviews [1] @@ -465,7 +465,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True ( cb.Subviews [1] @@ -595,7 +595,7 @@ Three ", Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Three", selected); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); @@ -646,7 +646,7 @@ Three ", attributes ); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Three", selected); Assert.False (cb.IsShow); Assert.Equal (2, cb.SelectedItem); @@ -756,7 +756,7 @@ Three ", Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -767,7 +767,7 @@ Three ", Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -803,7 +803,7 @@ Three ", Assert.Equal ("", cb.Text); Assert.True (cb.Subviews [1].NewKeyDownEvent (Key.CursorDown)); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("", selected); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -834,32 +834,32 @@ Three ", cb.OpenSelectedItem += (s, _) => opened = true; - Assert.False (Application.OnKeyDown (Key.Enter)); + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); Assert.False (opened); cb.Text = "Tw"; - Assert.False (Application.OnKeyDown (Key.Enter)); + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); Assert.True (opened); Assert.Equal ("Tw", cb.Text); Assert.False (cb.IsShow); cb.SetSource (null); Assert.False (cb.IsShow); - Assert.False (Application.OnKeyDown (Key.Enter)); - Assert.True (Application.OnKeyDown (Key.F4)); // with no source also expand empty + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); // with no source also expand empty Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); cb.SetSource (source); cb.Text = ""; - Assert.True (Application.OnKeyDown (Key.F4)); // collapse + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); // collapse Assert.False (cb.IsShow); - Assert.True (Application.OnKeyDown (Key.F4)); // expand + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); // expand Assert.True (cb.IsShow); cb.Collapse (); Assert.False (cb.IsShow); Assert.True (cb.HasFocus); - Assert.True (Application.OnKeyDown (Key.CursorDown)); // losing focus + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); // losing focus Assert.False (cb.IsShow); Assert.False (cb.HasFocus); cb.SetFocus (); @@ -870,27 +870,27 @@ Three ", Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); @@ -904,7 +904,7 @@ One output ); - Assert.True (Application.OnKeyDown (Key.PageDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageDown)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); @@ -919,7 +919,7 @@ Two output ); - Assert.True (Application.OnKeyDown (Key.PageDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageDown)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); @@ -933,43 +933,43 @@ Three ", output ); - Assert.True (Application.OnKeyDown (Key.PageUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageUp)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.PageUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageUp)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.End)); + Assert.True (Application.RaiseKeyDownEvent (Key.End)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.Home)); + Assert.True (Application.RaiseKeyDownEvent (Key.Home)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.End)); + Assert.True (Application.RaiseKeyDownEvent (Key.End)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.Home)); + Assert.True (Application.RaiseKeyDownEvent (Key.Home)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); // losing focus + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); // losing focus Assert.False (cb.HasFocus); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -980,7 +980,7 @@ Three Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.U.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.U.WithCtrl)); Assert.True (cb.HasFocus); Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -1009,7 +1009,7 @@ Three source.Add ("One"); Assert.Equal (1, cb.Source.Count); Assert.Equal (-1, cb.SelectedItem); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); @@ -1020,12 +1020,12 @@ Three Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("T", cb.Text); - Assert.True (Application.OnKeyDown (Key.Enter)); + Assert.True (Application.RaiseKeyDownEvent (Key.Enter)); Assert.False (cb.IsShow); Assert.Equal (2, cb.Source.Count); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("T", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); // retains last accept selected item Assert.Equal ("", cb.Text); // clear text diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index ab9e1448e..3a84d3b56 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -400,9 +400,9 @@ public class ContextMenuTests (ITestOutputHelper output) top.Add (tf); Application.Begin (top); - Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey)); + Assert.True (Application.RaiseKeyDownEvent (ContextMenu.DefaultKey)); Assert.True (tf.ContextMenu.MenuBar!.IsMenuOpen); - Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey)); + Assert.True (Application.RaiseKeyDownEvent (ContextMenu.DefaultKey)); // The last context menu bar opened is always preserved Assert.NotNull (tf.ContextMenu.MenuBar); @@ -1473,9 +1473,9 @@ public class ContextMenuTests (ITestOutputHelper output) Application.Begin (top); Assert.Null (cm.MenuBar); - Assert.False (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.D.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithCtrl)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1485,17 +1485,17 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithCtrl)); Assert.True (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.D.WithCtrl)); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (cm.MenuBar!.IsMenuOpen); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (renameFile); Assert.False (cm.MenuBar.IsMenuOpen); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.D.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.D.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (deleteFile); Assert.False (cm.MenuBar.IsMenuOpen); @@ -1507,9 +1507,9 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; deleteFile = false; - Assert.False (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.D.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithCtrl)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1557,8 +1557,8 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithCtrl)); Assert.Null (cm.MenuBar); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1572,12 +1572,12 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithCtrl)); Assert.True (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (cm.MenuBar!.IsMenuOpen); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (renameFile); Assert.False (cm.MenuBar.IsMenuOpen); @@ -1589,8 +1589,8 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1635,7 +1635,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (menuBar.KeyBindings.Bindings.ContainsKey (Key.N.WithCtrl)); Assert.Null (cm.MenuBar); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newMenuBar); Assert.False (newContextMenu); @@ -1647,7 +1647,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.N.WithCtrl)); Assert.True (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.False (newMenuBar); @@ -1660,7 +1660,7 @@ public class ContextMenuTests (ITestOutputHelper output) newMenuBar = false; newContextMenu = false; - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newMenuBar); Assert.False (newContextMenu); @@ -1693,9 +1693,9 @@ public class ContextMenuTests (ITestOutputHelper output) Application.Begin (top); Assert.Null (cm.MenuBar); - Assert.False (Application.OnKeyDown (Key.N.WithAlt)); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); - Assert.False (Application.OnKeyDown (Key.D.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithAlt)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1717,17 +1717,17 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.D.WithAlt)); Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.D.NoShift)); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); Assert.False (cm.MenuBar!.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (newFile); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (renameFile); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.D.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.D.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (deleteFile); @@ -1742,9 +1742,9 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; deleteFile = false; - Assert.False (Application.OnKeyDown (Key.N.WithAlt)); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); - Assert.False (Application.OnKeyDown (Key.D.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithAlt)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1801,14 +1801,14 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Empty (menus); Assert.Null (cm.MenuBar); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.True (menuBar.IsMenuOpen); Assert.Equal (2, Application.Top!.Subviews.Count); menus = Application.Top!.Subviews.Where (v => v is Menu m && m.Host == menuBar).ToArray (); Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.N.WithAlt)); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); Assert.False (menuBar.IsMenuOpen); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1840,9 +1840,9 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt)); Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.NoShift)); Assert.True (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); Application.MainLoop!.RunIteration (); Assert.True (newFile); @@ -1858,8 +1858,8 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.False (menus [1].KeyBindings.Bindings.ContainsKey (Key.E.NoShift)); Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt)); Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.NoShift)); - Assert.True (Application.OnKeyDown (Key.E.NoShift)); - Assert.True (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.E.NoShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (renameFile); @@ -1876,9 +1876,9 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1923,14 +1923,14 @@ public class ContextMenuTests (ITestOutputHelper output) top.Add (menuBar); Application.Begin (top); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.True (menuBar.IsMenuOpen); cm.Show (menuItems); Assert.False (menuBar.IsMenuOpen); Assert.True (cm.MenuBar!.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.True (menuBar.IsMenuOpen); Assert.False (cm.MenuBar!.IsMenuOpen); diff --git a/UnitTests/Views/DatePickerTests.cs b/UnitTests/Views/DatePickerTests.cs index fd78ac432..75761d94f 100644 --- a/UnitTests/Views/DatePickerTests.cs +++ b/UnitTests/Views/DatePickerTests.cs @@ -82,7 +82,7 @@ public class DatePickerTests Assert.Equal (datePicker.Subviews.First (v => v.Id == "_nextMonthButton"), datePicker.Focused); // Change month to December - Assert.False (Application.OnKeyDown (Key.Enter)); + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); Assert.Equal (12, datePicker.Date.Month); // Next month button is disabled, so focus advanced to edit field diff --git a/UnitTests/Views/LabelTests.cs b/UnitTests/Views/LabelTests.cs index 2e3982fe7..2eb73d34f 100644 --- a/UnitTests/Views/LabelTests.cs +++ b/UnitTests/Views/LabelTests.cs @@ -1341,7 +1341,7 @@ e Application.Top.SetFocus (); Assert.True (otherView.HasFocus); - Assert.True (Application.OnKeyDown (label.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (label.HotKey)); Assert.False (otherView.HasFocus); Assert.False (label.HasFocus); Assert.True (nextView.HasFocus); @@ -1396,7 +1396,7 @@ e Assert.True (view.HasFocus); // No focused view accepts Tab, and there's no other view to focus, so OnKeyDown returns false - Assert.True (Application.OnKeyDown (label.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (label.HotKey)); Assert.True (label.HasFocus); Assert.False (view.HasFocus); diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 849d9b8f4..9d2535e5c 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -2666,7 +2666,7 @@ Edit top.Draw (); TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); - Assert.True (Application.OnKeyDown (menu.Key)); + Assert.True (Application.NewKeyDown (menu.Key)); Assert.False (menu.IsMenuOpen); Assert.True (tf.HasFocus); top.Draw (); @@ -2949,7 +2949,7 @@ Edit top.Add (menu); Application.Begin (top); - Application.OnKeyDown (Key.S.WithCtrl); + Application.NewKeyDown (Key.S.WithCtrl); Application.MainLoop.RunIteration (); Assert.True (saveAction); diff --git a/UnitTests/Views/RadioGroupTests.cs b/UnitTests/Views/RadioGroupTests.cs index 48fc88119..a3e60941f 100644 --- a/UnitTests/Views/RadioGroupTests.cs +++ b/UnitTests/Views/RadioGroupTests.cs @@ -57,7 +57,7 @@ public class RadioGroupTests (ITestOutputHelper output) rg.SetFocus (); Assert.Equal (-1, rg.SelectedItem); - Application.OnKeyDown (Key.Space); + Application.NewKeyDown (Key.Space); Assert.Equal (0, rg.SelectedItem); Application.Top.Dispose (); @@ -105,21 +105,21 @@ public class RadioGroupTests (ITestOutputHelper output) // With HasFocus // Test up/down without Select - Assert.False (Application.OnKeyDown (Key.CursorUp)); // Should not change (should focus prev view if there was one, which there isn't) + Assert.False (Application.NewKeyDown (Key.CursorUp)); // Should not change (should focus prev view if there was one, which there isn't) Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.NewKeyDown (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); // Cursor changed, but selection didnt Assert.Equal (1, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - Assert.False (Application.OnKeyDown (Key.CursorDown)); // Should not change selection (should focus next view if there was one, which there isn't) + Assert.False (Application.NewKeyDown (Key.CursorDown)); // Should not change selection (should focus next view if there was one, which there isn't) Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); @@ -127,7 +127,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Test Select (Space) when Cursor != SelectedItem - Should select cursor - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.NewKeyDown (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (1, selectedItemChangedCount); @@ -135,34 +135,34 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Test Select (Space) when Cursor == SelectedItem - Should cycle - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.NewKeyDown (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (2, selectedItemChangedCount); Assert.Equal (2, selectingCount); Assert.Equal (0, acceptedCount); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.NewKeyDown (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.NewKeyDown (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.NewKeyDown (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Home)); + Assert.True (Application.NewKeyDown (Key.Home)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.NewKeyDown (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.End)); + Assert.True (Application.NewKeyDown (Key.End)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.NewKeyDown (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (7, selectedItemChangedCount); @@ -174,7 +174,7 @@ public class RadioGroupTests (ITestOutputHelper output) rg.HotKey = Key.L; Assert.Equal (Key.L, rg.HotKey); - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.NewKeyDown (rg.HotKey)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (8, selectedItemChangedCount); @@ -182,12 +182,12 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Make Selected != Cursor - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.NewKeyDown (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); // Selected != Cursor - Raise HotKey event - Since we're focused, this should just advance - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.NewKeyDown (rg.HotKey)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (9, selectedItemChangedCount); @@ -239,7 +239,7 @@ public class RadioGroupTests (ITestOutputHelper output) // Selected (0) == Cursor (0) - SetFocus rg.HotKey = Key.L; Assert.Equal (Key.L, rg.HotKey); - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.NewKeyDown (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); @@ -248,14 +248,14 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptCount); // Make Selected != Cursor - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.NewKeyDown (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); otherView.SetFocus (); // Selected != Cursor - SetFocus - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.NewKeyDown (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -263,7 +263,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, selectCount); Assert.Equal (0, acceptCount); - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.NewKeyDown (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -314,7 +314,7 @@ public class RadioGroupTests (ITestOutputHelper output) // Test RadioTitem.HotKey - Should never SetFocus // Selected (0) == Cursor (0) - Assert.True (Application.OnKeyDown (Key.A)); + Assert.True (Application.NewKeyDown (Key.A)); Assert.False (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); @@ -325,14 +325,14 @@ public class RadioGroupTests (ITestOutputHelper output) rg.SetFocus (); // Make Selected != Cursor - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.NewKeyDown (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); otherView.SetFocus (); // Selected != Cursor - Assert.True (Application.OnKeyDown (Key.A)); + Assert.True (Application.NewKeyDown (Key.A)); Assert.False (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -341,7 +341,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptCount); // Selected != Cursor - Should not set focus - Assert.True (Application.OnKeyDown (Key.B)); + Assert.True (Application.NewKeyDown (Key.B)); Assert.False (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -349,7 +349,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (1, selectCount); Assert.Equal (0, acceptCount); - Assert.True (Application.OnKeyDown (Key.B)); + Assert.True (Application.NewKeyDown (Key.B)); Assert.False (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -372,22 +372,22 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.NotEmpty (rg.KeyBindings.GetCommands (KeyCode.L | KeyCode.ShiftMask)); Assert.NotEmpty (rg.KeyBindings.GetCommands (KeyCode.L | KeyCode.AltMask)); - Assert.True (Application.OnKeyDown (Key.T)); + Assert.True (Application.NewKeyDown (Key.T)); Assert.Equal (2, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.L)); + Assert.True (Application.NewKeyDown (Key.L)); Assert.Equal (0, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.J)); + Assert.True (Application.NewKeyDown (Key.J)); Assert.Equal (3, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.R)); + Assert.True (Application.NewKeyDown (Key.R)); Assert.Equal (1, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.T.WithAlt)); + Assert.True (Application.NewKeyDown (Key.T.WithAlt)); Assert.Equal (2, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.L.WithAlt)); + Assert.True (Application.NewKeyDown (Key.L.WithAlt)); Assert.Equal (0, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.J.WithAlt)); + Assert.True (Application.NewKeyDown (Key.J.WithAlt)); Assert.Equal (3, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.NewKeyDown (Key.R.WithAlt)); Assert.Equal (1, rg.SelectedItem); var superView = new View (); diff --git a/UnitTests/Views/ShortcutTests.cs b/UnitTests/Views/ShortcutTests.cs index dc3ab6e1c..711ce243f 100644 --- a/UnitTests/Views/ShortcutTests.cs +++ b/UnitTests/Views/ShortcutTests.cs @@ -667,7 +667,7 @@ public class ShortcutTests var selected = 0; shortcut.Selecting += (s, e) => selected++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAccept, accepted); Assert.Equal (expectedSelect, selected); @@ -719,7 +719,7 @@ public class ShortcutTests var selected = 0; shortcut.Selecting += (s, e) => selected++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAccept, accepted); Assert.Equal (expectedSelect, selected); @@ -751,7 +751,7 @@ public class ShortcutTests var accepted = 0; shortcut.Accepting += (s, e) => accepted++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAccept, accepted); @@ -792,7 +792,7 @@ public class ShortcutTests var action = 0; shortcut.Action += () => action++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAction, action); @@ -831,7 +831,7 @@ public class ShortcutTests var action = 0; shortcut.Action += () => action++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAction, action); diff --git a/UnitTests/Views/StatusBarTests.cs b/UnitTests/Views/StatusBarTests.cs index 2622d807f..f9c6fcd3b 100644 --- a/UnitTests/Views/StatusBarTests.cs +++ b/UnitTests/Views/StatusBarTests.cs @@ -104,7 +104,7 @@ public class StatusBarTests if (iteration == 0) { Assert.Equal ("", msg); - Application.OnKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); } else if (iteration == 1) { diff --git a/UnitTests/Views/TabViewTests.cs b/UnitTests/Views/TabViewTests.cs index 660434b66..dd1d3546d 100644 --- a/UnitTests/Views/TabViewTests.cs +++ b/UnitTests/Views/TabViewTests.cs @@ -398,7 +398,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.SelectedTab.View, top.Focused.MostFocused); // Press the cursor up key to focus the selected tab - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Application.Refresh (); // Is the selected tab focused @@ -416,7 +416,7 @@ public class TabViewTests (ITestOutputHelper output) }; // Press the cursor right key to select the next tab - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); Application.Refresh (); Assert.Equal (tab1, oldChanged); Assert.Equal (tab2, newChanged); @@ -425,7 +425,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the cursor down key. Since the selected tab has no focusable views, the focus should move to the next view in the toplevel - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (btn, top.MostFocused); @@ -439,31 +439,31 @@ public class TabViewTests (ITestOutputHelper output) tv.SelectedTab.View.Add (btnSubView); // Press cursor up. Should focus the subview in the selected tab. - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (btnSubView, top.MostFocused); - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.Equal (tab2, top.MostFocused); // Press the cursor down key twice. - Application.OnKeyDown (Key.CursorDown); - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (btn, top.MostFocused); // Press the cursor down key again will focus next view in the toplevel, whic is the TabView - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (tv, top.Focused); Assert.Equal (tab1, tv.MostFocused); // Press the cursor down key to focus the selected tab view hosting again - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (btnSubView, top.MostFocused); // Press the cursor up key to focus the selected tab - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Application.Refresh (); // Is the selected tab focused @@ -472,7 +472,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the cursor left key to select the previous tab - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Application.Refresh (); Assert.Equal (tab2, oldChanged); Assert.Equal (tab1, newChanged); @@ -481,7 +481,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the end key to select the last tab - Application.OnKeyDown (Key.End); + Application.RaiseKeyDownEvent (Key.End); Application.Refresh (); Assert.Equal (tab1, oldChanged); Assert.Equal (tab2, newChanged); @@ -490,7 +490,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the home key to select the first tab - Application.OnKeyDown (Key.Home); + Application.RaiseKeyDownEvent (Key.Home); Application.Refresh (); Assert.Equal (tab2, oldChanged); Assert.Equal (tab1, newChanged); @@ -499,7 +499,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the page down key to select the next set of tabs - Application.OnKeyDown (Key.PageDown); + Application.RaiseKeyDownEvent (Key.PageDown); Application.Refresh (); Assert.Equal (tab1, oldChanged); Assert.Equal (tab2, newChanged); @@ -508,7 +508,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the page up key to select the previous set of tabs - Application.OnKeyDown (Key.PageUp); + Application.RaiseKeyDownEvent (Key.PageUp); Application.Refresh (); Assert.Equal (tab2, oldChanged); Assert.Equal (tab1, newChanged); diff --git a/UnitTests/Views/TableViewTests.cs b/UnitTests/Views/TableViewTests.cs index 6bb982988..5c6a3c204 100644 --- a/UnitTests/Views/TableViewTests.cs +++ b/UnitTests/Views/TableViewTests.cs @@ -3215,12 +3215,12 @@ A B C tableView.SelectedColumn = 1; // Pressing left should move us to the first column without changing focus - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the leftmost cell a further left press should move focus - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3240,12 +3240,12 @@ A B C tableView.SelectedRow = 1; // First press should move us up - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the top row a further press should move focus - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3264,12 +3264,12 @@ A B C tableView.SelectedColumn = tableView.Table.Columns - 2; // First press should move us to the rightmost column without changing focus - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the rightmost cell, a further right press should move focus - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3289,12 +3289,12 @@ A B C tableView.SelectedRow = tableView.Table.Rows - 2; // First press should move us to the bottommost row without changing focus - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the bottommost cell, a further down press should move focus - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3315,7 +3315,7 @@ A B C tableView.SelectedColumn = 1; // Pressing shift-left should give us a multi selection - Application.OnKeyDown (Key.CursorLeft.WithShift); + Application.RaiseKeyDownEvent (Key.CursorLeft.WithShift); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); Assert.Equal (2, tableView.GetAllSelectedCells ().Count ()); @@ -3323,7 +3323,7 @@ A B C // Because we are now on the leftmost cell a further left press would normally move focus // However there is an ongoing selection so instead the operation clears the selection and // gets swallowed (not resulting in a focus change) - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); // Selection 'clears' just to the single cell and we remain focused Assert.Single (tableView.GetAllSelectedCells ()); @@ -3331,7 +3331,7 @@ A B C Assert.True (tableView.HasFocus); // A further left will switch focus - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index d2f8ba4c5..9fb6d3eac 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -524,7 +524,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.OnKeyDown (Key.Space); + Application.NewKeyDown (Key.Space); Application.Top.Dispose (); Application.ResetState (true); @@ -541,7 +541,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.OnKeyDown (Key.Enter); + Application.NewKeyDown (Key.Enter); Assert.Equal (0, selectingCount); @@ -560,7 +560,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.OnKeyDown (Key.Enter); + Application.NewKeyDown (Key.Enter); Assert.Equal (1, acceptedCount); diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index 12780d219..f5f42b19c 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -299,26 +299,26 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (tf1W1, top.MostFocused); Assert.True (isRunning); - Assert.True (Application.OnKeyDown (Application.QuitKey)); + Assert.True (Application.RaiseKeyDownEvent (Application.QuitKey)); Assert.False (isRunning); - Assert.True (Application.OnKeyDown (Key.Z.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.Z.WithCtrl)); - Assert.True (Application.OnKeyDown (Key.F5)); // refresh + Assert.True (Application.RaiseKeyDownEvent (Key.F5)); // refresh - Assert.True (Application.OnKeyDown (Key.Tab)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.Tab)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text); - Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text); var prevMostFocusedSubview = top.MostFocused; - Assert.True (Application.OnKeyDown (Key.F6)); // move to next TabGroup (win2) + Assert.True (Application.RaiseKeyDownEvent (Key.F6)); // move to next TabGroup (win2) Assert.Equal (win2, top.Focused); - Assert.True (Application.OnKeyDown (Key.F6.WithShift)); // move to prev TabGroup (win1) + Assert.True (Application.RaiseKeyDownEvent (Key.F6.WithShift)); // move to prev TabGroup (win1) Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); // BUGBUG: Should be prevMostFocusedSubview - We need to cache the last focused view in the TabGroup somehow @@ -327,13 +327,13 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (tvW1, top.MostFocused); tf2W1.SetFocus (); - Assert.True (Application.OnKeyDown (Key.Tab)); // tf2W1 is last subview in win1 - tabbing should take us to first subview of win1 + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); // tf2W1 is last subview in win1 - tabbing should take us to first subview of win1 Assert.Equal (win1, top.Focused); Assert.Equal (tf1W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorRight)); // move char to right in tf1W1. We're at last char so nav to next view + Assert.True (Application.RaiseKeyDownEvent (Key.CursorRight)); // move char to right in tf1W1. We're at last char so nav to next view Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorDown)); // move down to next view (tvW1) + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); // move down to next view (tvW1) Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); #if UNIX_KEY_BINDINGS @@ -341,34 +341,34 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (win1, top.GetFocused ()); Assert.Equal (tf2W1, top.MostFocused); #endif - Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); // Ignored. TextView eats shift-tab by default + Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); // Ignored. TextView eats shift-tab by default Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); tvW1.AllowsTab = false; - Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); Assert.Equal (win1, top.Focused); Assert.Equal (tf1W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorLeft)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft)); Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); // nav to win2 - Assert.True (Application.OnKeyDown (Key.F6)); + Assert.True (Application.RaiseKeyDownEvent (Key.F6)); Assert.Equal (win2, top.Focused); Assert.Equal (tf1W2, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.F6.WithShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.F6.WithShift)); Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Application.NextTabGroupKey)); + Assert.True (Application.RaiseKeyDownEvent (Application.NextTabGroupKey)); Assert.Equal (win2, top.Focused); Assert.Equal (tf1W2, top.MostFocused); - Assert.True (Application.OnKeyDown (Application.PrevTabGroupKey)); + Assert.True (Application.RaiseKeyDownEvent (Application.PrevTabGroupKey)); Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); diff --git a/UnitTests/Views/TreeTableSourceTests.cs b/UnitTests/Views/TreeTableSourceTests.cs index 04fcf420e..3db7a2742 100644 --- a/UnitTests/Views/TreeTableSourceTests.cs +++ b/UnitTests/Views/TreeTableSourceTests.cs @@ -187,7 +187,7 @@ public class TreeTableSourceTests : IDisposable Assert.Equal (0, tv.SelectedRow); Assert.Equal (1, tv.SelectedColumn); - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); tv.Draw (); From bc51f8868be4ac4dc24bc474b4bbe01b284503d3 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 14:56:46 -0600 Subject: [PATCH 10/35] KeyDown API usage cleanup --- .../Application/Application.Initialization.cs | 2 +- .../Application/Application.Navigation.cs | 79 ++++++++ Terminal.Gui/View/View.Keyboard.cs | 7 +- Terminal.Gui/Views/TextField.cs | 24 +-- Terminal.Gui/Views/TextView.cs | 174 +++++++++--------- Terminal.Gui/Views/TreeView/TreeView.cs | 5 +- UnitTests/Application/KeyboardTests.cs | 58 +++--- UnitTests/UICatalog/ScenarioTests.cs | 2 +- UnitTests/Views/MenuBarTests.cs | 4 +- UnitTests/Views/RadioGroupTests.cs | 66 +++---- UnitTests/Views/TextFieldTests.cs | 6 +- 11 files changed, 248 insertions(+), 179 deletions(-) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index 640c9b5f5..c8310b780 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -179,7 +179,7 @@ public static partial class Application // Initialization (Init/Shutdown) private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); } - private static void Driver_KeyUp (object? sender, Key e) { OnKeyUp (e); } + private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); } private static void Driver_MouseEvent (object? sender, MouseEvent e) { OnMouseEvent (e); } /// Gets of list of types that are available. diff --git a/Terminal.Gui/Application/Application.Navigation.cs b/Terminal.Gui/Application/Application.Navigation.cs index 440cd4b42..a4f9dcc54 100644 --- a/Terminal.Gui/Application/Application.Navigation.cs +++ b/Terminal.Gui/Application/Application.Navigation.cs @@ -7,4 +7,83 @@ public static partial class Application // Navigation stuff /// Gets the instance for the current . /// public static ApplicationNavigation? Navigation { get; internal set; } + + private static Key _nextTabGroupKey = Key.F6; // Resources/config.json overrides + private static Key _nextTabKey = Key.Tab; // Resources/config.json overrides + private static Key _prevTabGroupKey = Key.F6.WithShift; // Resources/config.json overrides + private static Key _prevTabKey = Key.Tab.WithShift; // Resources/config.json overrides + + /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key NextTabGroupKey + { + get => _nextTabGroupKey; + set + { + if (_nextTabGroupKey != value) + { + ReplaceKey (_nextTabGroupKey, value); + _nextTabGroupKey = value; + } + } + } + + /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key NextTabKey + { + get => _nextTabKey; + set + { + if (_nextTabKey != value) + { + ReplaceKey (_nextTabKey, value); + _nextTabKey = value; + } + } + } + + + /// + /// Raised when the user releases a key. + /// + /// Set to to indicate the key was handled and to prevent + /// additional processing. + /// + /// + /// + /// All drivers support firing the event. Some drivers (Curses) do not support firing the + /// and events. + /// Fired after . + /// + public static event EventHandler? KeyUp; + /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key PrevTabGroupKey + { + get => _prevTabGroupKey; + set + { + if (_prevTabGroupKey != value) + { + ReplaceKey (_prevTabGroupKey, value); + _prevTabGroupKey = value; + } + } + } + + /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key PrevTabKey + { + get => _prevTabKey; + set + { + if (_prevTabKey != value) + { + ReplaceKey (_prevTabKey, value); + _prevTabKey = value; + } + } + } } diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index 992f29e2f..b78eb2804 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -265,7 +265,7 @@ public partial class View // Keyboard APIs /// /// Calling this method for a key bound to the view via an Application-scoped keybinding will have no effect. /// Instead, - /// use . + /// use . /// /// See for an overview of Terminal.Gui keyboard APIs. /// @@ -530,7 +530,6 @@ public partial class View // Keyboard APIs return true; } - // BUGBUG: The proper pattern is for the v-method (OnInvokingKeyBindings) to be called first, then the event InvokingKeyBindings?.Invoke (this, key); if (key.Handled) @@ -538,8 +537,6 @@ public partial class View // Keyboard APIs return true; } - bool? handled; - // After // * If no key binding was found, `InvokeKeyBindings` returns `null`. @@ -548,7 +545,7 @@ public partial class View // Keyboard APIs // `InvokeKeyBindings` returns `false`. Continue passing the event (return `false` from `OnInvokeKeyBindings`).. // * If key bindings were found, and any handled the key (at least one `Command` returned `true`), // `InvokeKeyBindings` returns `true`. Continue passing the event (return `false` from `OnInvokeKeyBindings`). - handled = InvokeCommands (key, scope); + bool? handled = InvokeCommands (key, scope); if (handled is { } && (bool)handled) { diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index cb6d2e82a..94f512ded 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -1013,18 +1013,6 @@ public class TextField : View _isDrawing = false; } - /// - protected override bool OnInvokingKeyBindings (Key a, KeyBindingScope scope) - { - // Give autocomplete first opportunity to respond to key presses - if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (a)) - { - return true; - } - - return base.OnInvokingKeyBindings (a, scope); - } - /// protected override void OnHasFocusChanged (bool newHasFocus, View previousFocusedView, View view) { @@ -1037,6 +1025,18 @@ public class TextField : View // ClearAllSelection (); } + /// + protected override bool OnKeyDown (Key key) + { + // Give autocomplete first opportunity to respond to key presses + if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (key)) + { + return true; + } + + return false; + } + /// protected override bool OnKeyDownNotHandled (Key a) { diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 97ccc47a9..54174c495 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -1,10 +1,8 @@ #nullable enable // TextView.cs: multi-line text editing -using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; -using System.Text.Json.Serialization; using Terminal.Gui.Resources; namespace Terminal.Gui; @@ -106,7 +104,7 @@ internal class TextModel public void LoadCells (List cells, Attribute? attribute) { - _lines = Cell.ToCells ((List)cells); + _lines = Cell.ToCells (cells); SetAttributes (attribute); OnLinesLoaded (); } @@ -180,7 +178,7 @@ internal class TextModel { if (_lines.Count > 0 && pos < _lines.Count) { - _lines [pos] = [..runes]; + _lines [pos] = [.. runes]; } else if (_lines.Count == 0 || (_lines.Count > 0 && pos >= _lines.Count)) { @@ -188,8 +186,6 @@ internal class TextModel } } - - public override string ToString () { var sb = new StringBuilder (); @@ -608,8 +604,7 @@ internal class TextModel internal Size GetDisplaySize () { - Size size = Size.Empty; - + var size = Size.Empty; return size; } @@ -799,7 +794,7 @@ internal class TextModel string GetText (List x) { - string txt = Cell.ToString (x); + var txt = Cell.ToString (x); if (!matchCase) { @@ -872,7 +867,7 @@ internal class TextModel for (int i = start.Y; i < linesCount; i++) { List x = _lines [i]; - string txt = Cell.ToString (x); + var txt = Cell.ToString (x); if (!matchCase) { @@ -912,7 +907,7 @@ internal class TextModel for (int i = linesCount; i >= 0; i--) { List x = _lines [i]; - string txt = Cell.ToString (x); + var txt = Cell.ToString (x); if (!matchCase) { @@ -1075,7 +1070,7 @@ internal class TextModel private string ReplaceText (List source, string textToReplace, string matchText, int col) { - string origTxt = Cell.ToString (source); + var origTxt = Cell.ToString (source); (_, int len) = DisplaySize (source, 0, col, false); (_, int len2) = DisplaySize (source, col, col + matchText.Length, false); (_, int len3) = DisplaySize (source, col + matchText.Length, origTxt.GetRuneCount (), false); @@ -1171,10 +1166,11 @@ internal partial class HistoryText _historyTextItems.Clear (); _idxHistoryText = -1; _originalCellsList.Clear (); + // Save a copy of the original, not the reference foreach (List cells in cellsList) { - _originalCellsList.Add ([..cells]); + _originalCellsList.Add ([.. cells]); } OnChangeText (null); @@ -1678,15 +1674,15 @@ internal class WordWrapManager List line = Model.GetLine (i); List> wrappedLines = ToListRune ( - TextFormatter.Format ( - Cell.ToString (line), - width, - Alignment.Start, - true, - preserveTrailingSpaces, - tabWidth - ) - ); + TextFormatter.Format ( + Cell.ToString (line), + width, + Alignment.Start, + true, + preserveTrailingSpaces, + tabWidth + ) + ); var sumColWidth = 0; for (var j = 0; j < wrappedLines.Count; j++) @@ -1885,7 +1881,6 @@ public class TextView : View private WordWrapManager? _wrapManager; private bool _wrapNeeded; - /// /// Initializes a on the specified area, with dimensions controlled with the X, Y, Width /// and Height properties. @@ -1911,7 +1906,7 @@ public class TextView : View // Things this view knows how to do // Note - NewLine is only bound to Enter if Multiline is true - AddCommand (Command.NewLine, (ctx) => ProcessEnterKey (ctx)); + AddCommand (Command.NewLine, ctx => ProcessEnterKey (ctx)); AddCommand ( Command.PageDown, @@ -2376,7 +2371,7 @@ public class TextView : View KeyBindings.Add (Key.C.WithCtrl, Command.Copy); KeyBindings.Add (Key.W.WithCtrl, Command.Cut); // Move to Unix? - KeyBindings.Add (Key.X.WithCtrl, Command.Cut); + KeyBindings.Add (Key.X.WithCtrl, Command.Cut); KeyBindings.Add (Key.CursorLeft.WithCtrl, Command.WordLeft); @@ -2422,10 +2417,7 @@ public class TextView : View KeyBindings.Add ((KeyCode)ContextMenu.Key, KeyBindingScope.HotKey, Command.Context); } - private void TextView_Added1 (object? sender, SuperViewChangedEventArgs e) - { - throw new NotImplementedException (); - } + private void TextView_Added1 (object? sender, SuperViewChangedEventArgs e) { throw new NotImplementedException (); } // BUGBUG: AllowsReturn is mis-named. It should be EnterKeyAccepts. /// @@ -2435,11 +2427,13 @@ public class TextView : View /// /// /// Setting this property alters . - /// If is set to , then is also set to `true` and + /// If is set to , then is also set to + /// `true` and /// vice-versa. /// /// - /// If is set to , then gets set to . + /// If is set to , then gets set to + /// . /// /// public bool AllowsReturn @@ -2458,6 +2452,7 @@ public class TextView : View if (!_allowsReturn && _multiline) { Multiline = false; + // BUGBUG: Setting properties should not have side-effects like this. Multiline and AllowsTab should be independent. AllowsTab = false; } @@ -2532,7 +2527,6 @@ public class TextView : View } } - /// /// Indicates whatever the text has history changes or not. if the text has history changes /// otherwise. @@ -2604,7 +2598,7 @@ public class TextView : View CurrentRow = 0; _savedHeight = Height; - Height = Dim.Auto (DimAutoStyle.Text, minimumContentDim: 1); + Height = Dim.Auto (DimAutoStyle.Text, 1); if (!IsInitialized) { @@ -2805,7 +2799,6 @@ public class TextView : View } } - /// Allows clearing the items updating the original text. public void ClearHistoryChanges () { _historyText?.Clear (_model.GetAllLines ()); } @@ -2855,7 +2848,7 @@ public class TextView : View line [c] = cell; // Assign the modified copy back } - selectedCellsChanged.Add ([..GetLine (r)]); + selectedCellsChanged.Add ([.. GetLine (r)]); } GetSelectedRegion (); @@ -2906,10 +2899,10 @@ public class TextView : View public void PromptForColors () { if (!ColorPicker.Prompt ( - "Colors", - GetSelectedCellAttribute (), - out Attribute newAttribute - )) + "Colors", + GetSelectedCellAttribute (), + out Attribute newAttribute + )) { return; } @@ -3177,10 +3170,7 @@ public class TextView : View public List GetLine (int line) { return _model.GetLine (line); } /// - public override Attribute GetNormalColor () - { - return GetFocusColor (); - } + public override Attribute GetNormalColor () { return GetFocusColor (); } /// /// Inserts the given text at the current cursor position exactly as if the user had just @@ -3563,7 +3553,6 @@ public class TextView : View ProcessInheritsPreviousColorScheme (CurrentRow, CurrentColumn); ProcessAutocomplete (); - } /// @@ -3628,6 +3617,7 @@ public class TextView : View else { AddRune (col, row, rune); + // Ensures that cols less than 0 to be 1 because it will be converted to a printable rune cols = Math.Max (cols, 1); } @@ -3663,34 +3653,6 @@ public class TextView : View _isDrawing = false; } - /// - protected override bool OnInvokingKeyBindings (Key a, KeyBindingScope scope) - { - if (!a.IsValid) - { - return false; - } - - // Give autocomplete first opportunity to respond to key presses - if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (a)) - { - return true; - } - - return base.OnInvokingKeyBindings (a, scope); - } - - /// - public override bool OnKeyUp (Key key) - { - if (key == Key.Space.WithCtrl) - { - return true; - } - - return false; - } - /// protected override void OnHasFocusChanged (bool newHasFocus, View? previousFocusedView, View? view) { @@ -3698,8 +3660,23 @@ public class TextView : View { Application.UngrabMouse (); } + } - return; + /// + protected override bool OnKeyDown (Key key) + { + if (!key.IsValid) + { + return false; + } + + // Give autocomplete first opportunity to respond to key presses + if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (key)) + { + return true; + } + + return false; } /// @@ -3724,6 +3701,17 @@ public class TextView : View return true; } + /// + public override bool OnKeyUp (Key key) + { + if (key == Key.Space.WithCtrl) + { + return true; + } + + return false; + } + /// Invoke the event with the unwrapped . public virtual void OnUnwrappedCursorPosition (int? cRow = null, int? cCol = null) { @@ -3760,7 +3748,7 @@ public class TextView : View List> addedLine = [new (currentLine), runeList]; _historyText.Add ( - [..addedLine], + [.. addedLine], CursorPosition, HistoryText.LineStatus.Added ); @@ -3862,6 +3850,7 @@ public class TextView : View if (posX > -1 && col >= posX && posX < Viewport.Width && _topRow <= CurrentRow && posY < Viewport.Height) { Move (col, CurrentRow - _topRow); + return new (col, CurrentRow - _topRow); } @@ -4481,12 +4470,12 @@ public class TextView : View } else { - _historyText.Add ([ [.. currentLine]], CursorPosition); + _historyText.Add ([[.. currentLine]], CursorPosition); currentLine.RemoveAt (CurrentColumn); _historyText.Add ( - [ [.. currentLine]], + [[.. currentLine]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -4656,6 +4645,7 @@ public class TextView : View { cells = line.GetRange (startCol, endCol - startCol); cellsList.Add (cells); + return StringFromRunes (cells); } @@ -4668,6 +4658,7 @@ public class TextView : View cellsList.AddRange ([]); cells = model == null ? _model.GetLine (row) : model.GetLine (row); cellsList.Add (cells); + res = res + Environment.NewLine + StringFromRunes (cells); @@ -4703,7 +4694,7 @@ public class TextView : View OnUnwrappedCursorPosition (cRow, cCol); - return GetRegion (out _, sRow: startRow, sCol: startCol, cRow: cRow, cCol: cCol, model: model); + return GetRegion (out _, startRow, startCol, cRow, cCol, model); } private (int Row, int Col) GetUnwrappedPosition (int line, int col) @@ -4897,7 +4888,7 @@ public class TextView : View { _model.AddLine (CurrentRow + i, lines [i]); - addedLines.Add ([..lines [i]]); + addedLines.Add ([.. lines [i]]); } if (rest is { }) @@ -5071,7 +5062,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5111,7 +5102,7 @@ public class TextView : View return; } - _historyText.Add ([ [.. currentLine]], CursorPosition); + _historyText.Add ([[.. currentLine]], CursorPosition); if (currentLine.Count == 0) { @@ -5178,7 +5169,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5202,14 +5193,14 @@ public class TextView : View List currentLine = GetCurrentLine (); - _historyText.Add ([ [.. GetCurrentLine ()]], CursorPosition); + _historyText.Add ([[.. GetCurrentLine ()]], CursorPosition); if (CurrentColumn == 0) { DeleteTextBackwards (); _historyText.ReplaceLast ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5248,7 +5239,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5270,14 +5261,14 @@ public class TextView : View List currentLine = GetCurrentLine (); - _historyText.Add ([ [.. GetCurrentLine ()]], CursorPosition); + _historyText.Add ([[.. GetCurrentLine ()]], CursorPosition); if (currentLine.Count == 0 || CurrentColumn == currentLine.Count) { DeleteTextForwards (); _historyText.ReplaceLast ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5307,7 +5298,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5579,6 +5570,7 @@ public class TextView : View } DoNeededAction (); + return true; } @@ -5919,6 +5911,7 @@ public class TextView : View private bool ProcessMoveDown () { ResetContinuousFindTrack (); + if (_shiftSelecting && IsSelecting) { StopSelecting (); @@ -5961,8 +5954,10 @@ public class TextView : View if (IsSelecting) { StopSelecting (); + return true; } + // do not respond (this lets the key press fall through to navigation system - which usually changes focus backward) return false; } @@ -6001,8 +5996,10 @@ public class TextView : View { // In which case clear StopSelecting (); + return true; } + return false; } @@ -6296,7 +6293,6 @@ public class TextView : View _continuousFind = false; } - private void ResetPosition () { _topRow = _leftColumn = CurrentRow = CurrentColumn = 0; @@ -6461,13 +6457,13 @@ public class TextView : View } } - private void TextView_Initialized (object sender, EventArgs e) { if (Autocomplete.HostControl is null) { Autocomplete.HostControl = this; } + OnContentsChanged (); } diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 59fe8e04f..36a249e8c 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -1189,15 +1189,12 @@ public class TreeView : View, ITreeView where T : class return false; } - // BUGBUG: this should move to OnInvokingKeyBindings // If not a keybinding, is the key a searchable key press? if (CollectionNavigatorBase.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation) { - IReadOnlyCollection> map; - // If there has been a call to InvalidateMap since the last time // we need a new one to reflect the new exposed tree state - map = BuildLineMap (); + IReadOnlyCollection> map = BuildLineMap (); // Find the current selected object within the tree int current = map.IndexOf (b => b.Model == SelectedObject); diff --git a/UnitTests/Application/KeyboardTests.cs b/UnitTests/Application/KeyboardTests.cs index 71b93ecc4..2cbc32288 100644 --- a/UnitTests/Application/KeyboardTests.cs +++ b/UnitTests/Application/KeyboardTests.cs @@ -64,14 +64,14 @@ public class KeyboardTests Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (win2.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); @@ -117,14 +117,14 @@ public class KeyboardTests Assert.False (win2.HasFocus); Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (win.CanFocus); Assert.True (win.HasFocus); Assert.True (win2.CanFocus); @@ -170,31 +170,31 @@ public class KeyboardTests top.Add (view); Application.Begin (top); - Application.NewKeyDown (Key.A); + Application.RaiseKeyDownEvent (Key.A); Assert.False (invoked); Assert.True (view.ApplicationCommand); invoked = false; view.ApplicationCommand = false; Application.KeyBindings.Remove (KeyCode.A); - Application.NewKeyDown (Key.A); // old + Application.RaiseKeyDownEvent (Key.A); // old Assert.False (invoked); Assert.False (view.ApplicationCommand); Application.KeyBindings.Add (Key.A.WithCtrl, view, Command.Save); - Application.NewKeyDown (Key.A); // old + Application.RaiseKeyDownEvent (Key.A); // old Assert.False (invoked); Assert.False (view.ApplicationCommand); - Application.NewKeyDown (Key.A.WithCtrl); // new + Application.RaiseKeyDownEvent (Key.A.WithCtrl); // new Assert.False (invoked); Assert.True (view.ApplicationCommand); invoked = false; - Application.NewKeyDown (Key.H); + Application.RaiseKeyDownEvent (Key.H); Assert.True (invoked); invoked = false; Assert.False (view.HasFocus); - Application.NewKeyDown (Key.F); + Application.RaiseKeyDownEvent (Key.F); Assert.False (invoked); Assert.True (view.ApplicationCommand); @@ -215,7 +215,7 @@ public class KeyboardTests top.Add (view); Application.Begin (top); - Application.NewKeyDown (Key.A.WithCtrl); + Application.RaiseKeyDownEvent (Key.A.WithCtrl); Assert.False (invoked); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); @@ -223,7 +223,7 @@ public class KeyboardTests invoked = false; Assert.False (view.HasFocus); - Application.NewKeyDown (Key.Z); + Application.RaiseKeyDownEvent (Key.Z); Assert.False (invoked); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); @@ -399,7 +399,7 @@ public class KeyboardTests Assert.True (subView1.HasFocus); // Act - Application.NewKeyDown (Application.NextTabGroupKey); + Application.RaiseKeyDownEvent (Application.NextTabGroupKey); // Assert Assert.True (view2.HasFocus); @@ -432,24 +432,24 @@ public class KeyboardTests Assert.True (v1.HasFocus); // Across TabGroups - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v3.HasFocus); - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v1.HasFocus); - Application.NewKeyDown (Key.F6.WithShift); + Application.RaiseKeyDownEvent (Key.F6.WithShift); Assert.True (v3.HasFocus); - Application.NewKeyDown (Key.F6.WithShift); + Application.RaiseKeyDownEvent (Key.F6.WithShift); Assert.True (v1.HasFocus); // Restore? - Application.NewKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.True (v2.HasFocus); - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v3.HasFocus); - Application.NewKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v1.HasFocus); Application.RequestStop (); @@ -485,7 +485,7 @@ public class KeyboardTests view1.SetFocus (); // Act - Application.NewKeyDown (Application.NextTabKey); + Application.RaiseKeyDownEvent (Application.NextTabKey); // Assert Assert.True (view2.HasFocus); @@ -539,7 +539,7 @@ public class KeyboardTests Assert.True (subView1.HasFocus); // Act - Application.NewKeyDown (Application.PrevTabGroupKey); + Application.RaiseKeyDownEvent (Application.PrevTabGroupKey); // Assert Assert.True (view2.HasFocus); @@ -562,7 +562,7 @@ public class KeyboardTests view1.SetFocus (); // Act - Application.NewKeyDown (Application.NextTabKey); + Application.RaiseKeyDownEvent (Application.NextTabKey); // Assert Assert.True (view2.HasFocus); @@ -605,21 +605,21 @@ public class KeyboardTests Key prevKey = Application.QuitKey; - Application.NewKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); Assert.True (isQuiting); isQuiting = false; - Application.NewKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); Assert.True (isQuiting); isQuiting = false; Application.QuitKey = Key.C.WithCtrl; - Application.NewKeyDown (prevKey); // Should not quit + Application.RaiseKeyDownEvent (prevKey); // Should not quit Assert.False (isQuiting); - Application.NewKeyDown (Key.Q.WithCtrl); // Should not quit + Application.RaiseKeyDownEvent (Key.Q.WithCtrl); // Should not quit Assert.False (isQuiting); - Application.NewKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); Assert.True (isQuiting); // Reset the QuitKey to avoid throws errors on another tests @@ -728,7 +728,7 @@ public class KeyboardTests if (Application.IsInitialized) { _output.WriteLine (" Pressing QuitKey"); - Application.NewKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); } } } diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index 4575ea5ba..87735fda6 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -132,7 +132,7 @@ public class ScenarioTests : TestsAllViews { // Press QuitKey //_output.WriteLine ($"Forcing Quit with {Application.QuitKey}"); - Application.NewKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); } } } diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 9d2535e5c..938001fe1 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -2666,7 +2666,7 @@ Edit top.Draw (); TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); - Assert.True (Application.NewKeyDown (menu.Key)); + Assert.True (Application.RaiseKeyDownEvent (menu.Key)); Assert.False (menu.IsMenuOpen); Assert.True (tf.HasFocus); top.Draw (); @@ -2949,7 +2949,7 @@ Edit top.Add (menu); Application.Begin (top); - Application.NewKeyDown (Key.S.WithCtrl); + Application.RaiseKeyDownEvent (Key.S.WithCtrl); Application.MainLoop.RunIteration (); Assert.True (saveAction); diff --git a/UnitTests/Views/RadioGroupTests.cs b/UnitTests/Views/RadioGroupTests.cs index a3e60941f..ad0ccd630 100644 --- a/UnitTests/Views/RadioGroupTests.cs +++ b/UnitTests/Views/RadioGroupTests.cs @@ -57,7 +57,7 @@ public class RadioGroupTests (ITestOutputHelper output) rg.SetFocus (); Assert.Equal (-1, rg.SelectedItem); - Application.NewKeyDown (Key.Space); + Application.RaiseKeyDownEvent (Key.Space); Assert.Equal (0, rg.SelectedItem); Application.Top.Dispose (); @@ -105,21 +105,21 @@ public class RadioGroupTests (ITestOutputHelper output) // With HasFocus // Test up/down without Select - Assert.False (Application.NewKeyDown (Key.CursorUp)); // Should not change (should focus prev view if there was one, which there isn't) + Assert.False (Application.RaiseKeyDownEvent (Key.CursorUp)); // Should not change (should focus prev view if there was one, which there isn't) Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - Assert.True (Application.NewKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); // Cursor changed, but selection didnt Assert.Equal (1, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - Assert.False (Application.NewKeyDown (Key.CursorDown)); // Should not change selection (should focus next view if there was one, which there isn't) + Assert.False (Application.RaiseKeyDownEvent (Key.CursorDown)); // Should not change selection (should focus next view if there was one, which there isn't) Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); @@ -127,7 +127,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Test Select (Space) when Cursor != SelectedItem - Should select cursor - Assert.True (Application.NewKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (1, selectedItemChangedCount); @@ -135,34 +135,34 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Test Select (Space) when Cursor == SelectedItem - Should cycle - Assert.True (Application.NewKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (2, selectedItemChangedCount); Assert.Equal (2, selectingCount); Assert.Equal (0, acceptedCount); - Assert.True (Application.NewKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.NewKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.NewKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.NewKeyDown (Key.Home)); + Assert.True (Application.RaiseKeyDownEvent (Key.Home)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.NewKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.NewKeyDown (Key.End)); + Assert.True (Application.RaiseKeyDownEvent (Key.End)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.NewKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (7, selectedItemChangedCount); @@ -174,7 +174,7 @@ public class RadioGroupTests (ITestOutputHelper output) rg.HotKey = Key.L; Assert.Equal (Key.L, rg.HotKey); - Assert.True (Application.NewKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (8, selectedItemChangedCount); @@ -182,12 +182,12 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Make Selected != Cursor - Assert.True (Application.NewKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); // Selected != Cursor - Raise HotKey event - Since we're focused, this should just advance - Assert.True (Application.NewKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (9, selectedItemChangedCount); @@ -239,7 +239,7 @@ public class RadioGroupTests (ITestOutputHelper output) // Selected (0) == Cursor (0) - SetFocus rg.HotKey = Key.L; Assert.Equal (Key.L, rg.HotKey); - Assert.True (Application.NewKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); @@ -248,14 +248,14 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptCount); // Make Selected != Cursor - Assert.True (Application.NewKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); otherView.SetFocus (); // Selected != Cursor - SetFocus - Assert.True (Application.NewKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -263,7 +263,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, selectCount); Assert.Equal (0, acceptCount); - Assert.True (Application.NewKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -314,7 +314,7 @@ public class RadioGroupTests (ITestOutputHelper output) // Test RadioTitem.HotKey - Should never SetFocus // Selected (0) == Cursor (0) - Assert.True (Application.NewKeyDown (Key.A)); + Assert.True (Application.RaiseKeyDownEvent (Key.A)); Assert.False (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); @@ -325,14 +325,14 @@ public class RadioGroupTests (ITestOutputHelper output) rg.SetFocus (); // Make Selected != Cursor - Assert.True (Application.NewKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); otherView.SetFocus (); // Selected != Cursor - Assert.True (Application.NewKeyDown (Key.A)); + Assert.True (Application.RaiseKeyDownEvent (Key.A)); Assert.False (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -341,7 +341,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptCount); // Selected != Cursor - Should not set focus - Assert.True (Application.NewKeyDown (Key.B)); + Assert.True (Application.RaiseKeyDownEvent (Key.B)); Assert.False (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -349,7 +349,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (1, selectCount); Assert.Equal (0, acceptCount); - Assert.True (Application.NewKeyDown (Key.B)); + Assert.True (Application.RaiseKeyDownEvent (Key.B)); Assert.False (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -372,22 +372,22 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.NotEmpty (rg.KeyBindings.GetCommands (KeyCode.L | KeyCode.ShiftMask)); Assert.NotEmpty (rg.KeyBindings.GetCommands (KeyCode.L | KeyCode.AltMask)); - Assert.True (Application.NewKeyDown (Key.T)); + Assert.True (Application.RaiseKeyDownEvent (Key.T)); Assert.Equal (2, rg.SelectedItem); - Assert.True (Application.NewKeyDown (Key.L)); + Assert.True (Application.RaiseKeyDownEvent (Key.L)); Assert.Equal (0, rg.SelectedItem); - Assert.True (Application.NewKeyDown (Key.J)); + Assert.True (Application.RaiseKeyDownEvent (Key.J)); Assert.Equal (3, rg.SelectedItem); - Assert.True (Application.NewKeyDown (Key.R)); + Assert.True (Application.RaiseKeyDownEvent (Key.R)); Assert.Equal (1, rg.SelectedItem); - Assert.True (Application.NewKeyDown (Key.T.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.T.WithAlt)); Assert.Equal (2, rg.SelectedItem); - Assert.True (Application.NewKeyDown (Key.L.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.L.WithAlt)); Assert.Equal (0, rg.SelectedItem); - Assert.True (Application.NewKeyDown (Key.J.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.J.WithAlt)); Assert.Equal (3, rg.SelectedItem); - Assert.True (Application.NewKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Assert.Equal (1, rg.SelectedItem); var superView = new View (); diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index 9fb6d3eac..0de972262 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -524,7 +524,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.NewKeyDown (Key.Space); + Application.RaiseKeyDownEvent (Key.Space); Application.Top.Dispose (); Application.ResetState (true); @@ -541,7 +541,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.NewKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); Assert.Equal (0, selectingCount); @@ -560,7 +560,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.NewKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); Assert.Equal (1, acceptedCount); From 3f3ceae9c7219206cd03fcc8d5cdbaaf1422bae2 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 16:35:10 -0600 Subject: [PATCH 11/35] API docs --- Terminal.Gui/View/View.Keyboard.cs | 79 ++----- Terminal.Gui/Views/Menu/Menu.cs | 2 +- UICatalog/Scenarios/Keys.cs | 174 ++++++++------- UICatalog/Scenarios/VkeyPacketSimulator.cs | 2 +- UnitTests/Application/KeyboardTests.cs | 32 +-- UnitTests/View/{ => Keyboard}/HotKeyTests.cs | 12 +- UnitTests/View/Keyboard/KeyboardEventTests.cs | 199 ++---------------- .../{ => Keyboard}/ViewKeyBindingTests.cs | 54 ++--- docfx/docs/keyboard.md | 38 ++-- 9 files changed, 215 insertions(+), 377 deletions(-) rename UnitTests/View/{ => Keyboard}/HotKeyTests.cs (97%) rename UnitTests/View/{ => Keyboard}/ViewKeyBindingTests.cs (76%) diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index b78eb2804..10f1f97df 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -255,9 +255,7 @@ public partial class View // Keyboard APIs /// /// If a more focused subview does not handle the key press, this method raises / /// to allow the - /// view to pre-process the key press. If / is not handled - /// / will be raised to invoke any key - /// bindings. + /// view to pre-process the key press. If / is not handled any commands bound to the key will be invoked. /// Then, only if no key bindings are /// handled, / will be raised allowing the view to /// process the key press. @@ -292,8 +290,8 @@ public partial class View // Keyboard APIs // During (this is what can be cancelled) - // TODO: NewKeyDownEvent returns bool. It should be bool? so state of RaiseInvokingKeyBindingsAndInvokeCommands can be reflected up stack - if (RaiseInvokingKeyBindingsAndInvokeCommands (key) is true || key.Handled) + // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommands can be reflected up stack + if (InvokeCommandsBoundToKey (key) is true || key.Handled) { return true; } @@ -336,7 +334,7 @@ public partial class View // Keyboard APIs /// /// Called when the user presses a key, allowing subscribers to pre-process the key down event. Called - /// before and are raised. Set + /// before key bindings are invoked and is raised. Set /// /// to true to /// stop the key from being processed further. @@ -357,7 +355,7 @@ public partial class View // Keyboard APIs /// /// Raised when the user presses a key, allowing subscribers to pre-process the key down event. Called - /// before and are raised. Set + /// before key bindings are invoked and is raised. Set /// /// to true to /// stop the key from being processed further. @@ -508,8 +506,7 @@ public partial class View // Keyboard APIs private Dictionary CommandImplementations { get; } = new (); /// - /// INTERNAL API: Raises the event and invokes the commands bound to - /// . + /// INTERNAL API: Invokes any commands bound to on this view, adornments, and subviews. /// /// /// @@ -517,28 +514,13 @@ public partial class View // Keyboard APIs /// continue. /// if a command was invoked and was not handled (or cancelled); input processing should /// continue. - /// if was handled or a command was invoked and handled (or + /// if at least one command was invoked and handled (or /// cancelled); input processing should stop. /// - internal bool? RaiseInvokingKeyBindingsAndInvokeCommands (Key key) + internal bool? InvokeCommandsBoundToKey (Key key) { KeyBindingScope scope = KeyBindingScope.Focused | KeyBindingScope.HotKey; - // During - if (OnInvokingKeyBindings (key, scope)) - { - return true; - } - - InvokingKeyBindings?.Invoke (this, key); - - if (key.Handled) - { - return true; - } - - // After - // * If no key binding was found, `InvokeKeyBindings` returns `null`. // Continue passing the event (return `false` from `OnInvokeKeyBindings`). // * If key bindings were found, but none handled the key (all `Command`s returned `false`), @@ -547,29 +529,29 @@ public partial class View // Keyboard APIs // `InvokeKeyBindings` returns `true`. Continue passing the event (return `false` from `OnInvokeKeyBindings`). bool? handled = InvokeCommands (key, scope); - if (handled is { } && (bool)handled) + if (handled is true) { // Stop processing if any key binding handled the key. // DO NOT stop processing if there are no matching key bindings or none of the key bindings handled the key return handled; } - if (Margin is { } && ProcessAdornmentKeyBindings (Margin, key, scope, ref handled)) + if (Margin is { } && InvokeCommandsBoundToKeyOnAdornment (Margin, key, scope, ref handled)) { return true; } - if (Padding is { } && ProcessAdornmentKeyBindings (Padding, key, scope, ref handled)) + if (Padding is { } && InvokeCommandsBoundToKeyOnAdornment (Padding, key, scope, ref handled)) { return true; } - if (Border is { } && ProcessAdornmentKeyBindings (Border, key, scope, ref handled)) + if (Border is { } && InvokeCommandsBoundToKeyOnAdornment (Border, key, scope, ref handled)) { return true; } - if (ProcessSubViewKeyBindings (key, scope, ref handled)) + if (InvokeCommandsBoundToKeyOnSubviews (key, scope, ref handled)) { return true; } @@ -577,32 +559,9 @@ public partial class View // Keyboard APIs return handled; } - /// - /// Called when a key is pressed that may be mapped to a key binding. Set to true to - /// stop the key from being processed by other views. - /// - /// - /// See for an overview of Terminal.Gui keyboard APIs. - /// - /// Contains the details about the key that produced the event. - /// The scope. - /// - /// if the event was raised and was not handled (or cancelled); input processing should - /// continue. - /// if the event was raised and handled (or cancelled); input processing should stop. - /// - protected virtual bool OnInvokingKeyBindings (Key key, KeyBindingScope scope) { return false; } - - // TODO: This does not carry KeyBindingScope, but OnInvokingKeyBindings does - /// - /// Raised when a key is pressed that may be mapped to a key binding. Set to true to - /// stop the key from being processed by other views. - /// - public event EventHandler? InvokingKeyBindings; - - private bool ProcessAdornmentKeyBindings (Adornment adornment, Key key, KeyBindingScope scope, ref bool? handled) + private static bool InvokeCommandsBoundToKeyOnAdornment (Adornment adornment, Key key, KeyBindingScope scope, ref bool? handled) { - bool? adornmentHandled = adornment.RaiseInvokingKeyBindingsAndInvokeCommands (key); + bool? adornmentHandled = adornment.InvokeCommandsBoundToKey (key); if (adornmentHandled is true) { @@ -616,7 +575,7 @@ public partial class View // Keyboard APIs foreach (View subview in adornment.Subviews) { - bool? subViewHandled = subview.RaiseInvokingKeyBindingsAndInvokeCommands (key); + bool? subViewHandled = subview.InvokeCommandsBoundToKey (key); if (subViewHandled is { }) { @@ -632,7 +591,7 @@ public partial class View // Keyboard APIs return false; } - private bool ProcessSubViewKeyBindings (Key key, KeyBindingScope scope, ref bool? handled, bool invoke = true) + private bool InvokeCommandsBoundToKeyOnSubviews (Key key, KeyBindingScope scope, ref bool? handled, bool invoke = true) { // Now, process any key bindings in the subviews that are tagged to KeyBindingScope.HotKey. foreach (View subview in Subviews) @@ -654,7 +613,7 @@ public partial class View // Keyboard APIs return true; } - bool? subViewHandled = subview.RaiseInvokingKeyBindingsAndInvokeCommands (key); + bool? subViewHandled = subview.InvokeCommandsBoundToKey (key); if (subViewHandled is { }) { @@ -667,7 +626,7 @@ public partial class View // Keyboard APIs } } - bool recurse = subview.ProcessSubViewKeyBindings (key, scope, ref handled, invoke); + bool recurse = subview.InvokeCommandsBoundToKeyOnSubviews (key, scope, ref handled, invoke); if (recurse || (handled is { } && (bool)handled)) { diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index b3429b190..b961f68bc 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -309,7 +309,7 @@ internal sealed class Menu : View protected override bool OnKeyDownNotHandled (Key keyEvent) { // We didn't handle the key, pass it on to host - return _host.RaiseInvokingKeyBindingsAndInvokeCommands (keyEvent) == true; + return _host.InvokeCommandsBoundToKey (keyEvent) == true; } private void Current_TerminalResized (object? sender, SizeChangedEventArgs e) diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index a96f256bb..7851d342d 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -10,109 +10,136 @@ public class Keys : Scenario public override void Main () { Application.Init (); - ObservableCollection keyPressedList = []; - ObservableCollection invokingKeyBindingsList = new (); + ObservableCollection keyDownList = []; + ObservableCollection keyDownNotHandledList = new (); var win = new Window { Title = GetQuitKeyAndName () }; - var editLabel = new Label { X = 0, Y = 0, Text = "Type text here:" }; - win.Add (editLabel); - var edit = new TextField { X = Pos.Right (editLabel) + 1, Y = Pos.Top (editLabel), Width = Dim.Fill (2) }; + var label = new Label + { + X = 0, + Y = 0, + Text = "_Type text here:" + }; + win.Add (label); + + var edit = new TextField + { + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Width = Dim.Fill (2), + Height = 1, + }; win.Add (edit); - edit.KeyDown += (s, a) => { keyPressedList.Add (a.ToString ()); }; - - edit.InvokingKeyBindings += (s, a) => - { - if (edit.KeyBindings.TryGet (a, out KeyBinding binding)) - { - invokingKeyBindingsList.Add ($"{a}: {string.Join (",", binding.Commands)}"); - } - }; - - // Last KeyPress: ______ - var keyPressedLabel = new Label + label = new Label { - X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 1, Text = "Last TextView.KeyPressed:" + X = 0, + Y = Pos.Bottom (label), + Text = "Last _Application.KeyDown:" }; - win.Add (keyPressedLabel); - var labelTextViewKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) }; - win.Add (labelTextViewKeypress); - - edit.KeyDown += (s, e) => labelTextViewKeypress.Text = e.ToString (); - - keyPressedLabel = new Label + win.Add (label); + var labelAppKeypress = new Label { - X = Pos.Left (keyPressedLabel), Y = Pos.Bottom (keyPressedLabel), Text = "Last Application.KeyDown:" + X = Pos.Right (label) + 1, + Y = Pos.Top (label) }; - win.Add (keyPressedLabel); - var labelAppKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) }; win.Add (labelAppKeypress); Application.KeyDown += (s, e) => labelAppKeypress.Text = e.ToString (); - // Key stroke log: - var keyLogLabel = new Label - { - X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 4, Text = "Application Key Events:" - }; - win.Add (keyLogLabel); - int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length; - var yOffset = 1; - ObservableCollection keyEventlist = new (); - - var keyEventListView = new ListView + label = new () { X = 0, - Y = Pos.Top (keyLogLabel) + yOffset, - Width = "Key Down:".Length + maxKeyString, + Y = Pos.Bottom (label), + Text = "_Last TextField.KeyDown:" + }; + win.Add (label); + + var lastTextFieldKeyDownLabel = new Label + { + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Height = 1, + }; + win.Add (lastTextFieldKeyDownLabel); + + edit.KeyDown += (s, e) => lastTextFieldKeyDownLabel.Text = e.ToString (); + + // Application key event log: + label = new Label + { + X = 0, + Y = Pos.Bottom (label) + 1, + Text = "Application Key Events:" + }; + win.Add (label); + int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length; + + ObservableCollection keyEventList = new (); + + var appKeyEventListView = new ListView + { + X = 0, + Y = Pos.Bottom (label), + Width = "KeyDown:".Length + maxKeyString, Height = Dim.Fill (), - Source = new ListWrapper (keyEventlist) + Source = new ListWrapper (keyEventList) }; - keyEventListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; - win.Add (keyEventListView); + appKeyEventListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; + win.Add (appKeyEventListView); - // OnKeyPressed - var onKeyPressedLabel = new Label + // View key events... + edit.KeyDown += (s, a) => { keyDownList.Add (a.ToString ()); }; + + edit.KeyDownNotHandled += (s, a) => + { + if (edit.KeyBindings.TryGet (a, out KeyBinding binding)) + { + keyDownNotHandledList.Add ($"{a}: {string.Join (",", binding.Commands)}"); + } + }; + + // KeyDown + label = new Label { - X = Pos.Right (keyEventListView) + 1, Y = Pos.Top (editLabel) + 4, Text = "TextView KeyDown:" + X = Pos.Right (appKeyEventListView) + 1, + Y = Pos.Top (label), + Text = "TextView Key Down:" }; - win.Add (onKeyPressedLabel); + win.Add (label); - yOffset = 1; - - var onKeyPressedListView = new ListView + var onKeyDownListView = new ListView { - X = Pos.Left (onKeyPressedLabel), - Y = Pos.Top (onKeyPressedLabel) + yOffset, + X = Pos.Left (label), + Y = Pos.Bottom (label), Width = maxKeyString, Height = Dim.Fill (), - Source = new ListWrapper (keyPressedList) + Source = new ListWrapper (keyDownList) }; - onKeyPressedListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; - win.Add (onKeyPressedListView); + onKeyDownListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; + win.Add (onKeyDownListView); - // OnInvokeKeyBindings - var onInvokingKeyBindingsLabel = new Label + // KeyDownNotHandled + label = new Label { - X = Pos.Right (onKeyPressedListView) + 1, - Y = Pos.Top (editLabel) + 4, - Text = "TextView InvokingKeyBindings:" + X = Pos.Right (onKeyDownListView) + 1, + Y = Pos.Top (label), + Text = "TextView KeyDownNotHandled:" }; - win.Add (onInvokingKeyBindingsLabel); + win.Add (label); - var onInvokingKeyBindingsListView = new ListView + var onKeyDownNotHandledListView = new ListView { - X = Pos.Left (onInvokingKeyBindingsLabel), - Y = Pos.Top (onInvokingKeyBindingsLabel) + yOffset, - Width = Dim.Fill (1), + X = Pos.Left (label), + Y = Pos.Bottom (label), + Width = maxKeyString, Height = Dim.Fill (), - Source = new ListWrapper (invokingKeyBindingsList) + Source = new ListWrapper (keyDownNotHandledList) }; - onInvokingKeyBindingsListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; - win.Add (onInvokingKeyBindingsListView); + onKeyDownNotHandledListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; + win.Add (onKeyDownNotHandledListView); - //Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up"); @@ -120,10 +147,9 @@ public class Keys : Scenario { // BUGBUG: KeyEvent.ToString is badly broken var msg = $"Key{updown,-7}: {args}"; - keyEventlist.Add (msg); - keyEventListView.MoveDown (); - onKeyPressedListView.MoveDown (); - onInvokingKeyBindingsListView.MoveDown (); + keyEventList.Add (msg); + appKeyEventListView.MoveDown (); + onKeyDownNotHandledListView.MoveDown (); } Application.Run (win); diff --git a/UICatalog/Scenarios/VkeyPacketSimulator.cs b/UICatalog/Scenarios/VkeyPacketSimulator.cs index 059203ea7..1659eaebc 100644 --- a/UICatalog/Scenarios/VkeyPacketSimulator.cs +++ b/UICatalog/Scenarios/VkeyPacketSimulator.cs @@ -148,7 +148,7 @@ public class VkeyPacketSimulator : Scenario } }; - tvInput.InvokingKeyBindings += (s, e) => + tvInput.KeyDownNotHandled += (s, e) => { Key ev = e; diff --git a/UnitTests/Application/KeyboardTests.cs b/UnitTests/Application/KeyboardTests.cs index 2cbc32288..ba472d3ab 100644 --- a/UnitTests/Application/KeyboardTests.cs +++ b/UnitTests/Application/KeyboardTests.cs @@ -163,39 +163,39 @@ public class KeyboardTests public void KeyBinding_OnKeyDown () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); Application.RaiseKeyDownEvent (Key.A); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); - invoked = false; + keyWasHandled = false; view.ApplicationCommand = false; Application.KeyBindings.Remove (KeyCode.A); Application.RaiseKeyDownEvent (Key.A); // old - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Application.KeyBindings.Add (Key.A.WithCtrl, view, Command.Save); Application.RaiseKeyDownEvent (Key.A); // old - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Application.RaiseKeyDownEvent (Key.A.WithCtrl); // new - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); - invoked = false; + keyWasHandled = false; Application.RaiseKeyDownEvent (Key.H); - Assert.True (invoked); + Assert.False (keyWasHandled); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); Application.RaiseKeyDownEvent (Key.F); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); Assert.True (view.HotKeyCommand); @@ -208,23 +208,23 @@ public class KeyboardTests public void KeyBinding_OnKeyDown_Negative () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); Application.RaiseKeyDownEvent (Key.A.WithCtrl); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); Application.RaiseKeyDownEvent (Key.Z); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); diff --git a/UnitTests/View/HotKeyTests.cs b/UnitTests/View/Keyboard/HotKeyTests.cs similarity index 97% rename from UnitTests/View/HotKeyTests.cs rename to UnitTests/View/Keyboard/HotKeyTests.cs index a3edaaf6c..4c1e7812c 100644 --- a/UnitTests/View/HotKeyTests.cs +++ b/UnitTests/View/Keyboard/HotKeyTests.cs @@ -95,7 +95,7 @@ public class HotKeyTests { var view = new View (); view.KeyBindings.Add (Key.A, Command.HotKey); // implies KeyBindingScope.Focused - so this should not be invoked - view.InvokingKeyBindings += (s, e) => { Assert.Fail (); }; + view.KeyDownNotHandled += (s, e) => { Assert.Fail (); }; var superView = new View (); superView.Add (view); @@ -109,8 +109,11 @@ public class HotKeyTests { var view = new View (); view.KeyBindings.Add (Key.A, KeyBindingScope.HotKey, Command.HotKey); - bool invoked = false; - view.InvokingKeyBindings += (s, e) => { invoked = true; }; + bool hotKeyInvoked = false; + view.HandlingHotKey += (s, e) => { hotKeyInvoked = true; }; + + bool notHandled = false; + view.KeyDownNotHandled += (s, e) => { notHandled = true; }; var superView = new View (); superView.Add (view); @@ -118,7 +121,8 @@ public class HotKeyTests var ke = Key.A; superView.NewKeyDownEvent (ke); - Assert.True (invoked); + Assert.False (notHandled); + Assert.True (hotKeyInvoked); } diff --git a/UnitTests/View/Keyboard/KeyboardEventTests.cs b/UnitTests/View/Keyboard/KeyboardEventTests.cs index 6b484ec58..12cffb9a7 100644 --- a/UnitTests/View/Keyboard/KeyboardEventTests.cs +++ b/UnitTests/View/Keyboard/KeyboardEventTests.cs @@ -7,8 +7,8 @@ namespace Terminal.Gui.ViewTests; public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { /// - /// This tests that when a new key down event is sent to the view will fire the 3 key-down related - /// events: KeyDown, InvokingKeyBindings, and ProcessKeyDown. Note that KeyUp is independent. + /// This tests that when a new key down event is sent to the view will fire the key-down related + /// events: KeyDown and KeyDownNotHandled. Note that KeyUp is independent. /// [Theory] [MemberData (nameof (AllViewTypes))] @@ -33,27 +33,18 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews keyDown = true; }; - var invokingKeyBindings = false; - - view.InvokingKeyBindings += (s, a) => - { - a.Handled = false; // don't handle it so the other events are called - invokingKeyBindings = true; - }; - - var keyDownProcessed = false; + var keyDownNotHandled = false; view.KeyDownNotHandled += (s, a) => { a.Handled = true; - keyDownProcessed = true; + keyDownNotHandled = true; }; // Key.Empty is invalid, but it's used here to test that the event is fired Assert.True (view.NewKeyDownEvent (Key.Empty)); // this will be true because the ProcessKeyDown event handled it Assert.True (keyDown); - Assert.True (invokingKeyBindings); - Assert.True (keyDownProcessed); + Assert.True (keyDownNotHandled); view.Dispose (); } @@ -96,7 +87,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews public void NewKeyDownUpEvents_Events_Are_Raised_With_Only_Key_Modifiers (bool shift, bool alt, bool control) { var keyDown = false; - var keyPressed = false; + var keyDownNotHandled = false; var keyUp = false; var view = new OnNewKeyTestView (); @@ -112,7 +103,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyDownCalled); keyDown = true; }; - view.KeyDownNotHandled += (s, e) => { keyPressed = true; }; + view.KeyDownNotHandled += (s, e) => { keyDownNotHandled = true; }; view.KeyUp += (s, e) => { @@ -125,11 +116,6 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews keyUp = true; }; - //view.ProcessKeyDownEvent (new (Key.Null | (shift ? Key.ShiftMask : 0) | (alt ? Key.AltMask : 0) | (control ? Key.CtrlMask : 0))); - //Assert.True (keyDown); - //Assert.True (view.OnKeyDownWasCalled); - //Assert.True (view.OnProcessKeyDownWasCalled); - view.NewKeyDownEvent ( new ( KeyCode.Null @@ -138,7 +124,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews | (control ? KeyCode.CtrlMask : 0) ) ); - Assert.True (keyPressed); + Assert.True (keyDownNotHandled); Assert.True (view.OnKeyDownCalled); Assert.True (view.OnProcessKeyDownCalled); @@ -154,107 +140,11 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyUpCalled); } - [Fact] - public void NewKeyDownEvent_InvokingKeyBindings_Handled_Cancels () - { - var view = new View (); - var keyPressInvoked = false; - var invokingKeyBindingsInvoked = false; - var processKeyPressInvoked = false; - var setHandledTo = false; - - view.KeyDown += (s, e) => - { - keyPressInvoked = true; - Assert.False (e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.InvokingKeyBindings += (s, e) => - { - invokingKeyBindingsInvoked = true; - e.Handled = setHandledTo; - Assert.Equal (setHandledTo, e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.KeyDownNotHandled += (s, e) => - { - processKeyPressInvoked = true; - processKeyPressInvoked = true; - Assert.False (e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.NewKeyDownEvent (Key.N); - Assert.True (keyPressInvoked); - Assert.True (invokingKeyBindingsInvoked); - Assert.True (processKeyPressInvoked); - - keyPressInvoked = false; - invokingKeyBindingsInvoked = false; - processKeyPressInvoked = false; - setHandledTo = true; - view.NewKeyDownEvent (Key.N); - Assert.True (keyPressInvoked); - Assert.True (invokingKeyBindingsInvoked); - Assert.False (processKeyPressInvoked); - } - - [Fact] - public void NewKeyDownEvent_InvokingKeyBindings_Handled_True_Stops_Processing () - { - var keyDown = false; - var invokingKeyBindings = false; - var keyPressed = false; - - var view = new OnNewKeyTestView (); - Assert.True (view.CanFocus); - view.CancelVirtualMethods = false; - - view.KeyDown += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyDown); - Assert.True (view.OnKeyDownCalled); - e.Handled = false; - keyDown = true; - }; - - view.InvokingKeyBindings += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.True (view.OnInvokingKeyBindingsCalled); - e.Handled = true; - invokingKeyBindings = true; - }; - - view.KeyDownNotHandled += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnProcessKeyDownCalled); - e.Handled = true; - keyPressed = true; - }; - - view.NewKeyDownEvent (Key.A); - Assert.True (keyDown); - Assert.True (invokingKeyBindings); - Assert.False (keyPressed); - - Assert.True (view.OnKeyDownCalled); - Assert.True (view.OnInvokingKeyBindingsCalled); - Assert.False (view.OnProcessKeyDownCalled); - } - [Fact] public void NewKeyDownEvent_Handled_True_Stops_Processing () { var keyDown = false; - var invokingKeyBindings = false; - var keyPressed = false; + var keyDownNotHandled = false; var view = new OnNewKeyTestView (); Assert.True (view.CanFocus); @@ -269,31 +159,21 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews keyDown = true; }; - view.InvokingKeyBindings += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsCalled); - e.Handled = true; - invokingKeyBindings = true; - }; view.KeyDownNotHandled += (s, e) => { Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); + Assert.False (keyDownNotHandled); Assert.False (view.OnProcessKeyDownCalled); e.Handled = true; - keyPressed = true; + keyDownNotHandled = true; }; view.NewKeyDownEvent (Key.A); Assert.True (keyDown); - Assert.False (invokingKeyBindings); - Assert.False (keyPressed); + Assert.False (keyDownNotHandled); Assert.True (view.OnKeyDownCalled); - Assert.False (view.OnInvokingKeyBindingsCalled); Assert.False (view.OnProcessKeyDownCalled); } @@ -301,8 +181,7 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews public void NewKeyDownEvent_KeyDown_Handled_Stops_Processing () { var view = new View (); - var invokingKeyBindingsInvoked = false; - var processKeyPressInvoked = false; + var keyDownNotHandled = false; var setHandledTo = false; view.KeyDown += (s, e) => @@ -312,38 +191,27 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.Equal (KeyCode.N, e.KeyCode); }; - view.InvokingKeyBindings += (s, e) => - { - invokingKeyBindingsInvoked = true; - Assert.False (e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - view.KeyDownNotHandled += (s, e) => { - processKeyPressInvoked = true; + keyDownNotHandled = true; Assert.False (e.Handled); Assert.Equal (KeyCode.N, e.KeyCode); }; view.NewKeyDownEvent (Key.N); - Assert.True (invokingKeyBindingsInvoked); - Assert.True (processKeyPressInvoked); + Assert.True (keyDownNotHandled); - invokingKeyBindingsInvoked = false; - processKeyPressInvoked = false; + keyDownNotHandled = false; setHandledTo = true; view.NewKeyDownEvent (Key.N); - Assert.False (invokingKeyBindingsInvoked); - Assert.False (processKeyPressInvoked); + Assert.False (keyDownNotHandled); } [Fact] public void NewKeyDownEvent_ProcessKeyDown_Handled_Stops_Processing () { var keyDown = false; - var invokingKeyBindings = false; - var processKeyDown = false; + var keyDownNotHandled = false; var view = new OnNewKeyTestView (); Assert.True (view.CanFocus); @@ -358,31 +226,20 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews keyDown = true; }; - view.InvokingKeyBindings += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (processKeyDown); - Assert.True (view.OnInvokingKeyBindingsCalled); - e.Handled = false; - invokingKeyBindings = true; - }; - view.KeyDownNotHandled += (s, e) => { Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (processKeyDown); + Assert.False (keyDownNotHandled); Assert.True (view.OnProcessKeyDownCalled); e.Handled = true; - processKeyDown = true; + keyDownNotHandled = true; }; view.NewKeyDownEvent (Key.A); Assert.True (keyDown); - Assert.True (invokingKeyBindings); - Assert.True (processKeyDown); + Assert.True (keyDownNotHandled); Assert.True (view.OnKeyDownCalled); - Assert.True (view.OnInvokingKeyBindingsCalled); Assert.True (view.OnProcessKeyDownCalled); } @@ -409,7 +266,6 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews Assert.True (view.OnKeyUpCalled); Assert.False (view.OnKeyDownCalled); - Assert.False (view.OnInvokingKeyBindingsCalled); Assert.False (view.OnProcessKeyDownCalled); } @@ -417,12 +273,12 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews [InlineData (null, null)] [InlineData (true, true)] [InlineData (false, false)] - public void RaiseInvokingKeyBindingsAndInvokeCommands_Returns_Nullable_Properly (bool? toReturn, bool? expected) + public void InvokeCommandsBoundToKey_Returns_Nullable_Properly (bool? toReturn, bool? expected) { var view = new KeyBindingsTestView (); view.CommandReturns = toReturn; - bool? result = view.RaiseInvokingKeyBindingsAndInvokeCommands (Key.A); + bool? result = view.InvokeCommandsBoundToKey (Key.A); Assert.Equal (expected, result); } @@ -444,20 +300,11 @@ public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews { public OnNewKeyTestView () { CanFocus = true; } public bool CancelVirtualMethods { set; private get; } - public bool OnInvokingKeyBindingsCalled { get; set; } public bool OnKeyDownCalled { get; set; } public bool OnProcessKeyDownCalled { get; set; } public bool OnKeyUpCalled { get; set; } public override string Text { get; set; } - protected override bool OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) - { - - OnInvokingKeyBindingsCalled = true; - - return CancelVirtualMethods; - } - protected override bool OnKeyDown (Key keyEvent) { OnKeyDownCalled = true; diff --git a/UnitTests/View/ViewKeyBindingTests.cs b/UnitTests/View/Keyboard/ViewKeyBindingTests.cs similarity index 76% rename from UnitTests/View/ViewKeyBindingTests.cs rename to UnitTests/View/Keyboard/ViewKeyBindingTests.cs index 05471e4b5..b1483c4da 100644 --- a/UnitTests/View/ViewKeyBindingTests.cs +++ b/UnitTests/View/Keyboard/ViewKeyBindingTests.cs @@ -11,37 +11,38 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void Focus_KeyBinding () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); Application.RaiseKeyDownEvent (Key.A); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); - invoked = false; + keyWasHandled = false; Application.RaiseKeyDownEvent (Key.H); - Assert.True (invoked); + Assert.True (view.HotKeyCommand); + Assert.False (keyWasHandled); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); Application.RaiseKeyDownEvent (Key.F); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.FocusedCommand); - invoked = false; + keyWasHandled = false; view.CanFocus = true; view.SetFocus (); Assert.True (view.HasFocus); Application.RaiseKeyDownEvent (Key.F); - Assert.True (invoked); + Assert.True (view.FocusedCommand); + Assert.False (keyWasHandled); // Command was invoked, but wasn't handled Assert.True (view.ApplicationCommand); Assert.True (view.HotKeyCommand); - Assert.True (view.FocusedCommand); top.Dispose (); } @@ -50,23 +51,23 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void Focus_KeyBinding_Negative () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); Application.RaiseKeyDownEvent (Key.Z); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); Application.RaiseKeyDownEvent (Key.F); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); @@ -78,28 +79,29 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void HotKey_KeyBinding () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); - invoked = false; + keyWasHandled = false; Application.RaiseKeyDownEvent (Key.H); - Assert.True (invoked); Assert.True (view.HotKeyCommand); + Assert.False (keyWasHandled); view.HotKey = KeyCode.Z; - invoked = false; + keyWasHandled = false; view.HotKeyCommand = false; Application.RaiseKeyDownEvent (Key.H); // old hot key - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.HotKeyCommand); Application.RaiseKeyDownEvent (Key.Z); // new hot key - Assert.True (invoked); Assert.True (view.HotKeyCommand); + Assert.False (keyWasHandled); + top.Dispose (); } @@ -108,18 +110,18 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void HotKey_KeyBinding_Negative () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); Application.RaiseKeyDownEvent (Key.Z); - Assert.False (invoked); + Assert.False (keyWasHandled); Assert.False (view.HotKeyCommand); - invoked = false; + keyWasHandled = false; Application.RaiseKeyDownEvent (Key.F); Assert.False (view.HotKeyCommand); top.Dispose (); diff --git a/docfx/docs/keyboard.md b/docfx/docs/keyboard.md index 8b29a1a6d..ddace3282 100644 --- a/docfx/docs/keyboard.md +++ b/docfx/docs/keyboard.md @@ -59,22 +59,25 @@ The Command can be invoked even if the `View` that defines them is not focused o ### **Handling Keyboard Events** -Keyboard events are retrieved from [Console Drivers](drivers.md) and passed on -to the [Application](~/api/Terminal.Gui.Application.yml) class by the [Main Loop](mainloop.md). +Keyboard events are retrieved from [Console Drivers](drivers.md) each iteration of the [Application](~/api/Terminal.Gui.Application.yml) [Main Loop](mainloop.md). The console driver raises the @Terminal.Gui.ConsoleDriver.KeyDown and @Terminal.Gui.ConsoleDriver.KeyUp events which invoke @Terminal.Gui.Application.RaiseKeyDown(Terminal.Gui.Key) and @Terminal.Gui.Application.RaiseKeyUp(Terminal.Gui.Key) respectively. -[Application](~/api/Terminal.Gui.Application.yml) then determines the current [Toplevel](~/api/Terminal.Gui.Toplevel.yml) view -(either the default created by calling @Terminal.Gui.Application.Init(Terminal.Gui.ConsoleDriver,System.String), or the one set by calling `Application.Run`). The mouse event, using [Viewport-relative coordinates](xref:Terminal.Gui.View.Viewport) is then passed to the @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) method of the current [Toplevel](~/api/Terminal.Gui.Toplevel.yml) view. + NOTE: Not all drivers/platforms support sensing distinct KeyUp events. These drivers will simulate KeyUp events by raising @Terminal.Gui.ConsoleDriver.KeyUp after @Terminal.Gui.ConsoleDriver.KeyDown. -If the view is enabled, the @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) method will do the following: +@Terminal.Gui.Application.RaiseKeyDown(Terminal.Gui.Key) raises @Terminal.Gui.Application.KeyDown and then calls @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) on all toplevel Views. If no View handles the key event, any Application-scoped key bindings will be invoked. -1) If the view has a subview that has focus, 'ProcessKeyDown' on the focused view will be called. If the focused view handles the key press, processing stops. -2) If there is no focused sub-view, or the focused sub-view does not handle the key press, @Terminal.Gui.View.OnKeyDown(Terminal.Gui.Key) will be called. If the view handles the key press, processing stops. -3) If the view does not handle the key press, @Terminal.Gui.TextField.OnInvokingKeyBindings(Terminal.Gui.Key,Terminal.Gui.KeyBindingScope) will be called. This method calls @Terminal.Gui.View.InvokeKeyBindings(Terminal.Gui.Key,Terminal.Gui.KeyBindingScope) to invoke any keys bound to commands. If the key is bound and any of it's command handlers return true, processing stops. -4) If the key is not bound, or the bound command handlers do not return true, @Terminal.Gui.View.OnProcessKeyDown(Terminal.Gui.Key) is called. If the view handles the key press, processing stops. +@Terminal.Gui.Application.RaiseKeyDown(Terminal.Gui.Key) raises @Terminal.Gui.Application.KeyDown and then calls @Terminal.Gui.View.NewKeyUpEvent(Terminal.Gui.Key) on all toplevel Views. + +If a view is enabled, the @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) method will do the following: + +1) If the view has a subview that has focus, 'NewKeyDown' on the focused view will be called. This is recursive. If the most-focused view handles the key press, processing stops. +2) If there is no most-focused sub-view, or a most-focused sub-view does not handle the key press, @Terminal.Gui.View.OnKeyDown(Terminal.Gui.Key) will be called. If the view handles the key press, processing stops. +3) If @Terminal.Gui.View.OnKeyDown(Terminal.Gui.Key) does not handle the event. @Terminal.Gui.View.KeyDown will be raised. +4) If the view does not handle the key down event, any bindings for the key will be invoked (see @Terminal.Gui.View.KeyBindings). If the key is bound and any of it's command handlers return true, processing stops. +5) If the key is not bound, or the bound command handlers do not return true, @Terminal.Gui.View.OnKeyDownNotHandled(Terminal.Gui.Key) is called. ## **Application Key Handling** -To define application key handling logic for an entire application in cases where the methods listed above are not suitable, use the `Application.OnKeyDown` event. +To define application key handling logic for an entire application in cases where the methods listed above are not suitable, use the @Terminal.Gui.Application.KeyDown event. ## **Key Down/Up Events** @@ -90,17 +93,14 @@ To define application key handling logic for an entire application in cases wher - `NewKeyDownEvent` is called on the most-focused SubView (if any) that has focus. If that call returns true, the method returns. - Calls `OnKeyDown`. - **During** - - Assuming `OnKeyDown` call returns false (indicating the key wasn't handled) - - `OnInvokingKeyBindings` is called to invoke any bound commands. - - `OnInvokingKeyBindings` fires the `InvokingKeyBindings` event + - Assuming `OnKeyDown` call returns false (indicating the key wasn't handled) any commands bound to the key will be invoked. - **After** - - Assuming `OnInvokingKeyBindings` returns false (indicating the key wasn't handled) - - `OnProcessKeyDown` is called to process the key. - - `OnProcessKeyDown` fires the `ProcessKeyDown` event + - Assuming no keybinding was found or all invoked commands were not handled: + - `OnKeyDownNotHandled` is called to process the key. + - `KeyDownNotHandled` is raised. -- Subclasses of `View` can (rarely) override `OnKeyDown` to see keys before they are processed by `OnInvokingKeyBindings` and `OnProcessKeyDown -- Subclasses of `View` can (rarely) override `OnInvokingKeyBindings` to see keys before they are processed by `OnProcessKeyDown` -- Subclasses of `View` can (often) override `OnProcessKeyDown` to do normal key processing. +- Subclasses of `View` can (rarely) override `OnKeyDown` (or subscribe to `KeyDown`) to see keys before they are processed +- Subclasses of `View` can (often) override `OnKeyDownNotHandled` to do key processing for keys that were not previously handled. `TextField` and `TextView` are examples. ## ConsoleDriver From 89d8b74c3d9e0e134e5fd5ac8aa2ee1729906861 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 16:48:28 -0600 Subject: [PATCH 12/35] Key API simplification --- Terminal.Gui/View/View.Keyboard.cs | 4 +--- Terminal.Gui/View/View.Layout.cs | 1 - Terminal.Gui/Views/ListView.cs | 2 +- UICatalog/Scenarios/Keys.cs | 5 +---- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index 10f1f97df..1ebc77df0 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -73,7 +73,7 @@ public partial class View // Keyboard APIs /// If the hot key is changed, the event is fired. /// Set to to disable the hot key. /// - public virtual Key HotKey + public Key HotKey { get => _hotKey; set @@ -684,8 +684,6 @@ public partial class View // Keyboard APIs /// protected bool? InvokeCommands (Key key, KeyBindingScope scope) { - bool? toReturn = null; - if (!KeyBindings.TryGet (key, scope, out KeyBinding binding)) { return null; diff --git a/Terminal.Gui/View/View.Layout.cs b/Terminal.Gui/View/View.Layout.cs index 2d8fdfeda..318b5c993 100644 --- a/Terminal.Gui/View/View.Layout.cs +++ b/Terminal.Gui/View/View.Layout.cs @@ -28,7 +28,6 @@ public partial class View // Layout APIs /// The target y location. /// The new x location that will ensure will be fully visible. /// The new y location that will ensure will be fully visible. - /// The new top most statusBar /// /// Either (if does not have a Super View) or /// 's SuperView. This can be used to ensure LayoutSubviews is called on the correct View. diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index f7e65f843..0a768584a 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -806,7 +806,7 @@ public class ListView : View, IDesignable protected override bool OnKeyDown (Key a) { // Enable user to find & select an item by typing text - if (CollectionNavigatorBase.IsCompatibleKey (a) && (!AllowsMarking && a == Key.Space)) + if (CollectionNavigatorBase.IsCompatibleKey (a) || (!AllowsMarking && a == Key.Space)) { int? newItem = KeystrokeNavigator?.GetNextMatchingItem (SelectedItem, (char)a); diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index 7851d342d..e758af366 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -94,10 +94,7 @@ public class Keys : Scenario edit.KeyDownNotHandled += (s, a) => { - if (edit.KeyBindings.TryGet (a, out KeyBinding binding)) - { - keyDownNotHandledList.Add ($"{a}: {string.Join (",", binding.Commands)}"); - } + keyDownNotHandledList.Add ($"{a}"); }; // KeyDown From b766e4efdde100a9fae3eb11c114cf6e54c3966d Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 17:30:30 -0600 Subject: [PATCH 13/35] Fixed listView issue. Added ability to mark/unmark all to ListView --- Terminal.Gui/Views/ListView.cs | 57 ++++++++++++++++++++++++++++++-- UnitTests/Views/ListViewTests.cs | 16 ++++----- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 0a768584a..1fa76e540 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -147,7 +147,7 @@ public class ListView : View, IDesignable if (OnOpenSelectedItem ()) { - return true; + return true; } return false; @@ -189,6 +189,7 @@ public class ListView : View, IDesignable return !SetFocus (); }); + AddCommand (Command.SelectAll, (ctx) => MarkAll((bool)ctx.KeyBinding?.Context!)); // Default keybindings for all ListViews KeyBindings.Add (Key.CursorUp, Command.Up); @@ -205,6 +206,13 @@ public class ListView : View, IDesignable KeyBindings.Add (Key.Home, Command.Start); KeyBindings.Add (Key.End, Command.End); + + // Key.Space is already bound to Command.Select; this gives us select then move down + KeyBindings.Add (Key.Space.WithShift, [Command.Select, Command.Down]); + + // Use the form of Add that lets us pass context to the handler + KeyBindings.Add (Key.A.WithCtrl, new KeyBinding ([Command.SelectAll], KeyBindingScope.Focused, true)); + KeyBindings.Add (Key.U.WithCtrl, new KeyBinding ([Command.SelectAll], KeyBindingScope.Focused, false)); } /// Gets or sets whether this allows items to be marked. @@ -370,6 +378,31 @@ public class ListView : View, IDesignable } } + /// + /// If and are both , + /// marks all items. + /// + /// marks all items; otherwise unmarks all items. + /// if marking was successful. + public bool MarkAll (bool mark) + { + if (!_allowsMarking) + { + return false; + } + + if (AllowsMultipleSelection) + { + for (var i = 0; i < Source.Count; i++) + { + Source.SetMark (i, mark); + } + return true; + } + + return false; + } + /// /// If and are both , /// unmarks all marked items other than . @@ -805,8 +838,28 @@ public class ListView : View, IDesignable /// protected override bool OnKeyDown (Key a) { + // If marking is enabled and the user presses the space key don't let CollectionNavigator + // at it + if (AllowsMarking) + { + var keys = KeyBindings.GetKeysFromCommands (Command.Select); + + if (keys.Contains (a)) + { + return false; + } + + keys = KeyBindings.GetKeysFromCommands ([Command.Select, Command.Down]); + + if (keys.Contains (a)) + { + return false; + } + + } + // Enable user to find & select an item by typing text - if (CollectionNavigatorBase.IsCompatibleKey (a) || (!AllowsMarking && a == Key.Space)) + if (CollectionNavigatorBase.IsCompatibleKey (a)) { int? newItem = KeystrokeNavigator?.GetNextMatchingItem (SelectedItem, (char)a); diff --git a/UnitTests/Views/ListViewTests.cs b/UnitTests/Views/ListViewTests.cs index 7714c8204..3da369db1 100644 --- a/UnitTests/Views/ListViewTests.cs +++ b/UnitTests/Views/ListViewTests.cs @@ -522,7 +522,7 @@ Item 6", } [Fact] - public void ListViewSelectThenDown () + public void AllowsMarking_True_SpaceWithShift_SelectsThenDown () { var lv = new ListView { Source = new ListWrapper (["One", "Two", "Three"]) }; lv.AllowsMarking = true; @@ -537,12 +537,8 @@ Item 6", Assert.False (lv.Source.IsMarked (1)); Assert.False (lv.Source.IsMarked (2)); - lv.KeyBindings.Add (Key.Space.WithShift, Command.Select, Command.Down); - - Key key = Key.Space.WithShift; - // view should indicate that it has accepted and consumed the event - Assert.True (lv.NewKeyDownEvent (key)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); // first item should now be selected Assert.Equal (0, lv.SelectedItem); @@ -553,7 +549,7 @@ Item 6", Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (key)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); // second item should now be selected Assert.Equal (1, lv.SelectedItem); @@ -564,21 +560,21 @@ Item 6", Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (key)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); Assert.Equal (2, lv.SelectedItem); Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (key)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); Assert.Equal (2, lv.SelectedItem); // cannot move down any further Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); Assert.True (lv.Source.IsMarked (2)); // but can toggle marked // Press key combo again - Assert.True (lv.NewKeyDownEvent (key)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); Assert.Equal (2, lv.SelectedItem); // cannot move down any further Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); From 053da7ed254a3af42c1dee1ff412c92017aa774a Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 18:15:49 -0600 Subject: [PATCH 14/35] Application.Mouse cleanup --- Terminal.Gui/Application/Application.Mouse.cs | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index ab1cf428d..051e9f4fd 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -1,6 +1,5 @@ #nullable enable using System.ComponentModel; -using System.Diagnostics; namespace Terminal.Gui; @@ -45,12 +44,12 @@ public static partial class Application // Mouse handling /// View that will receive all mouse events until is invoked. public static void GrabMouse (View? view) { - if (view is null || OnGrabbingMouse (view)) + if (view is null || RaiseGrabbingMouseEvent (view)) { return; } - OnGrabbedMouse (view); + RaiseGrabbedMouseEvent (view); MouseGrabView = view; } @@ -66,16 +65,16 @@ public static partial class Application // Mouse handling ObjectDisposedException.ThrowIf (MouseGrabView.WasDisposed, MouseGrabView); #endif - if (!OnUnGrabbingMouse (MouseGrabView)) + if (!RaiseUnGrabbingMouseEvent (MouseGrabView)) { View view = MouseGrabView; MouseGrabView = null; - OnUnGrabbedMouse (view); + RaiseUnGrabbedMouseEvent (view); } } /// A delegate callback throws an exception. - private static bool OnGrabbingMouse (View? view) + private static bool RaiseGrabbingMouseEvent (View? view) { if (view is null) { @@ -89,7 +88,7 @@ public static partial class Application // Mouse handling } /// A delegate callback throws an exception. - private static bool OnUnGrabbingMouse (View? view) + private static bool RaiseUnGrabbingMouseEvent (View? view) { if (view is null) { @@ -103,7 +102,7 @@ public static partial class Application // Mouse handling } /// A delegate callback throws an exception. - private static void OnGrabbedMouse (View? view) + private static void RaiseGrabbedMouseEvent (View? view) { if (view is null) { @@ -114,7 +113,7 @@ public static partial class Application // Mouse handling } /// A delegate callback throws an exception. - private static void OnUnGrabbedMouse (View? view) + private static void RaiseUnGrabbedMouseEvent (View? view) { if (view is null) { @@ -124,20 +123,14 @@ public static partial class Application // Mouse handling UnGrabbedMouse?.Invoke (view, new (view)); } - /// Event fired when a mouse move or click occurs. Coordinates are screen relative. - /// - /// - /// Use this event to receive mouse events in screen coordinates. Use to - /// receive mouse events relative to a . - /// - /// The will contain the that contains the mouse coordinates. - /// - public static event EventHandler? MouseEvent; - /// Called when a mouse event is raised by the driver. + /// + /// INTERNAL API: Called when a mouse event is raised by the driver. Determines the view under the mouse and + /// calls the appropriate View mouse event handlers. + /// /// This method can be used to simulate a mouse event, e.g. in unit tests. /// The mouse event with coordinates relative to the screen. - internal static void OnMouseEvent (MouseEvent mouseEvent) + internal static void RaiseMouseEvent (MouseEvent mouseEvent) { _lastMousePosition = mouseEvent.ScreenPosition; @@ -224,7 +217,7 @@ public static partial class Application // Mouse handling { // The mouse was outside any View's Viewport. - // Debug.Fail ("This should never happen. If it does please file an Issue!!"); + // Debug.Fail ("This should never happen. If it does please file an Issue!!"); return; } @@ -261,6 +254,25 @@ public static partial class Application // Mouse handling } } + /// + /// Raised when a mouse event occurs. Can be cancelled by setting to . + /// + /// + /// + /// coordinates are screen-relative. + /// + /// + /// will be the deepest view under the under the mouse. + /// + /// + /// coordinates are view-relative. + /// + /// + /// Use this evento to handle mouse events at the application level, before View-specific handling. + /// + /// + public static event EventHandler? MouseEvent; + internal static bool HandleMouseGrab (View? deepestViewUnderMouse, MouseEvent mouseEvent) { if (MouseGrabView is { }) @@ -303,7 +315,6 @@ public static partial class Application // Mouse handling internal static readonly List _cachedViewsUnderMouse = new (); - // TODO: Refactor MouseEnter/LeaveEvents to not take MouseEvent param. /// /// INTERNAL: Raises the MouseEnter and MouseLeave events for the views that are under the mouse. /// From a9e1f2a2cba9ac35d3670acce9cf1e3f363d3cad Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 18:30:21 -0600 Subject: [PATCH 15/35] View.Mouse cleanup - WIP --- .../Application/Application.Initialization.cs | 2 +- Terminal.Gui/Application/Application.Mouse.cs | 2 +- Terminal.Gui/Input/Mouse.cs | 2 +- Terminal.Gui/View/View.Mouse.cs | 46 +++++++++---------- UnitTests/Application/ApplicationTests.cs | 6 +-- .../Mouse/ApplicationMouseTests.cs | 16 +++---- UnitTests/Input/EscSeqUtilsTests.cs | 4 +- UnitTests/View/Mouse/MouseTests.cs | 4 +- UnitTests/Views/ColorPickerTests.cs | 4 +- UnitTests/Views/ContextMenuTests.cs | 22 ++++----- UnitTests/Views/LabelTests.cs | 6 +-- UnitTests/Views/ListViewTests.cs | 10 ++-- UnitTests/Views/MenuBarTests.cs | 10 ++-- UnitTests/Views/ScrollBarViewTests.cs | 4 +- UnitTests/Views/ShortcutTests.cs | 8 ++-- UnitTests/Views/TabViewTests.cs | 18 ++++---- UnitTests/Views/TextFieldTests.cs | 6 +-- UnitTests/Views/ToplevelTests.cs | 44 +++++++++--------- 18 files changed, 107 insertions(+), 107 deletions(-) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index c8310b780..c1058f838 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -180,7 +180,7 @@ public static partial class Application // Initialization (Init/Shutdown) private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); } private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); } - private static void Driver_MouseEvent (object? sender, MouseEvent e) { OnMouseEvent (e); } + private static void Driver_MouseEvent (object? sender, MouseEvent e) { RaiseMouseEvent (e); } /// Gets of list of types that are available. /// diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index 051e9f4fd..9ac7df27a 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -201,7 +201,7 @@ public static partial class Application // Mouse handling View = deepestViewUnderMouse }; } - else if (deepestViewUnderMouse.ViewportToScreen (Rectangle.Empty with { Size = deepestViewUnderMouse.Viewport.Size }).Contains (mouseEvent.Position)) + else if (deepestViewUnderMouse.ViewportToScreen (Rectangle.Empty with { Size = deepestViewUnderMouse.Viewport.Size }).Contains (mouseEvent.ScreenPosition)) { Point viewportLocation = deepestViewUnderMouse.ScreenToViewport (mouseEvent.ScreenPosition); diff --git a/Terminal.Gui/Input/Mouse.cs b/Terminal.Gui/Input/Mouse.cs index 3c8c98e91..8069a339d 100644 --- a/Terminal.Gui/Input/Mouse.cs +++ b/Terminal.Gui/Input/Mouse.cs @@ -129,7 +129,7 @@ public class MouseEvent /// mouse has moved. /// /// - /// Calculated and processed in . + /// Calculated and processed in . /// /// public Point ScreenPosition { get; set; } diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 2fc180ece..48a3ea126 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -11,7 +11,7 @@ public partial class View // Mouse APIs private ColorScheme? _savedNonHoverColorScheme; /// - /// INTERNAL Called by when the mouse moves over the View's . + /// INTERNAL Called by when the mouse moves over the View's . /// will /// be raised when the mouse is no longer over the . If another View occludes this View, the /// that View will also receive MouseEnter/Leave events. @@ -126,7 +126,7 @@ public partial class View // Mouse APIs public event EventHandler? MouseEnter; /// - /// INTERNAL Called by when the mouse leaves , or is occluded + /// INTERNAL Called by when the mouse leaves , or is occluded /// by another non-SubView. /// /// @@ -196,16 +196,15 @@ public partial class View // Mouse APIs #region Low Level Mouse Events - /// Event fired when a mouse event occurs. - /// - /// - /// The coordinates are relative to . - /// - /// - public event EventHandler? MouseEvent; + /// Gets or sets whether the wants continuous button pressed events. + public virtual bool WantContinuousButtonPressed { get; set; } + + /// Gets or sets whether the wants mouse position reports. + /// if mouse position reports are wanted; otherwise, . + public virtual bool WantMousePositionReports { get; set; } /// - /// Processes a . This method is called by when a mouse + /// Processes a new . This method is called by when a mouse /// event occurs. /// /// @@ -213,15 +212,15 @@ public partial class View // Mouse APIs /// A view must be both enabled and visible to receive mouse events. /// /// - /// This method calls to process the event. If the event is not handled, and one of the - /// mouse buttons was clicked, it calls to process the click. + /// This method raises /; if not handled, and one of the + /// mouse buttons was clicked, the / event will be raised /// /// /// See for more information. /// /// - /// If is , the event - /// will be invoked repeatedly while the button is pressed. + /// If is , the / event + /// will be raised on any new mouse event where indicates a button is pressed. /// /// /// @@ -297,13 +296,6 @@ public partial class View // Mouse APIs return false; } - /// Gets or sets whether the wants continuous button pressed events. - public virtual bool WantContinuousButtonPressed { get; set; } - - /// Gets or sets whether the wants mouse position reports. - /// if mouse position reports are wanted; otherwise, . - public virtual bool WantMousePositionReports { get; set; } - /// Called when a mouse event occurs within the view's . /// /// @@ -312,7 +304,7 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - protected internal virtual bool OnMouseEvent (MouseEvent mouseEvent) + protected virtual bool OnMouseEvent (MouseEvent mouseEvent) { var args = new MouseEventEventArgs (mouseEvent); @@ -321,11 +313,19 @@ public partial class View // Mouse APIs return args.Handled; } + /// Raised when a mouse event occurs. + /// + /// + /// The coordinates are relative to . + /// + /// + public event EventHandler? MouseEvent; + #endregion Low Level Mouse Events #region Mouse Click Events - /// Event fired when a mouse click occurs. + /// Raised when a mouse click occurs. /// /// /// diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index 81209dddb..215e7e050 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -856,7 +856,7 @@ public class ApplicationTests } else if (iteration < 3) { - Application.OnMouseEvent (new () { Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { Flags = MouseFlags.ReportMousePosition }); Assert.False (top.NeedsDisplay); Assert.False (top.SubViewNeedsDisplay); Assert.False (top.LayoutNeeded); @@ -895,12 +895,12 @@ public class ApplicationTests // Don't use visuals to test as style of border can change over time. Assert.Equal (new (0, 0), w.Frame.Location); - Application.OnMouseEvent (new () { Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { Flags = MouseFlags.Button1Pressed }); Assert.Equal (w.Border, Application.MouseGrabView); Assert.Equal (new (0, 0), w.Frame.Location); // Move down and to the right. - Application.OnMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); Assert.Equal (new (1, 1), w.Frame.Location); Application.End (rs); diff --git a/UnitTests/Application/Mouse/ApplicationMouseTests.cs b/UnitTests/Application/Mouse/ApplicationMouseTests.cs index c5a86a85c..963807695 100644 --- a/UnitTests/Application/Mouse/ApplicationMouseTests.cs +++ b/UnitTests/Application/Mouse/ApplicationMouseTests.cs @@ -54,7 +54,7 @@ public class ApplicationMouseTests Application.MouseEvent += OnApplicationOnMouseEvent; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (expectedClicked, clicked); Application.MouseEvent -= OnApplicationOnMouseEvent; } @@ -129,7 +129,7 @@ public class ApplicationMouseTests top.Add (view); Application.Begin (top); - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (expectedClicked, clicked); top.Dispose (); } @@ -227,7 +227,7 @@ public class ApplicationMouseTests clicked = true; }; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (expectedClicked, clicked); Application.Top.Dispose (); Application.ResetState (ignoreDisposed: true); @@ -261,7 +261,7 @@ public class ApplicationMouseTests Assert.True (tf.HasFocus); Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); Assert.Equal (sv, Application.MouseGrabView); @@ -275,15 +275,15 @@ public class ApplicationMouseTests // another toplevel (Dialog) was opened Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (40, 12), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (40, 12), Flags = MouseFlags.ReportMousePosition }); Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); Assert.Null (Application.MouseGrabView); @@ -402,7 +402,7 @@ public class ApplicationMouseTests Assert.True (view.WasDisposed); #endif - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); Assert.Null (Application.MouseGrabView); Assert.Equal (0, count); top.Dispose (); diff --git a/UnitTests/Input/EscSeqUtilsTests.cs b/UnitTests/Input/EscSeqUtilsTests.cs index 3ac8e4c60..9b811f002 100644 --- a/UnitTests/Input/EscSeqUtilsTests.cs +++ b/UnitTests/Input/EscSeqUtilsTests.cs @@ -696,7 +696,7 @@ public class EscSeqUtilsTests top.Add (view); Application.Begin (top); - Application.OnMouseEvent (new() { Position = new (0, 0), Flags = 0 }); + Application.RaiseMouseEvent (new() { Position = new (0, 0), Flags = 0 }); ClearAll (); @@ -753,7 +753,7 @@ public class EscSeqUtilsTests // set Application.WantContinuousButtonPressedView to null view.WantContinuousButtonPressed = false; - Application.OnMouseEvent (new() { Position = new (0, 0), Flags = 0 }); + Application.RaiseMouseEvent (new() { Position = new (0, 0), Flags = 0 }); Application.RequestStop (); } diff --git a/UnitTests/View/Mouse/MouseTests.cs b/UnitTests/View/Mouse/MouseTests.cs index 8c021e3c4..87f3e71b5 100644 --- a/UnitTests/View/Mouse/MouseTests.cs +++ b/UnitTests/View/Mouse/MouseTests.cs @@ -106,9 +106,9 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews Application.Begin (top); Assert.Equal (new Point (4, 4), testView.Frame.Location); - Application.OnMouseEvent (new () { ScreenPosition = new (xy, xy), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (xy, xy), Flags = MouseFlags.Button1Pressed }); - Application.OnMouseEvent (new () { ScreenPosition = new (xy + 1, xy + 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (xy + 1, xy + 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); Assert.Equal (expectedMoved, new Point (5, 5) == testView.Frame.Location); top.Dispose (); diff --git a/UnitTests/Views/ColorPickerTests.cs b/UnitTests/Views/ColorPickerTests.cs index 57f4144c9..73fe010be 100644 --- a/UnitTests/Views/ColorPickerTests.cs +++ b/UnitTests/Views/ColorPickerTests.cs @@ -434,7 +434,7 @@ public class ColorPickerTests cp.Draw (); // Click on Green bar - Application.OnMouseEvent (new () + Application.RaiseMouseEvent (new () { Flags = MouseFlags.Button1Pressed, ScreenPosition = new (0, 1) @@ -453,7 +453,7 @@ public class ColorPickerTests Assert.IsAssignableFrom (cp.Focused); // Click on Blue bar - Application.OnMouseEvent (new () + Application.RaiseMouseEvent (new () { Flags = MouseFlags.Button1Pressed, ScreenPosition = new (0, 2) diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index 3a84d3b56..098ee3aac 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -148,7 +148,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (8, 2), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (8, 2), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -231,7 +231,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rsDialog, ref firstIteration); @@ -287,7 +287,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1235,7 +1235,7 @@ public class ContextMenuTests (ITestOutputHelper output) ); // X=5 is the border and so need to use at least one more - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.Button1Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1253,7 +1253,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 12), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 12), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1327,7 +1327,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1344,7 +1344,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 14), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 14), Flags = MouseFlags.ReportMousePosition }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1362,7 +1362,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1399,7 +1399,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Empty (Application._cachedViewsUnderMouse); // Right click on tf2 to open context menu - Application.OnMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button3Clicked }); Assert.False (tf1.HasFocus); Assert.False (tf2.HasFocus); Assert.Equal (5, win.Subviews.Count); @@ -1409,7 +1409,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (tf2, Application._cachedViewsUnderMouse.LastOrDefault ()); // Click on tf1 to focus it, which cause context menu being closed - Application.OnMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Clicked }); Assert.True (tf1.HasFocus); Assert.False (tf2.HasFocus); Assert.Equal (4, win.Subviews.Count); @@ -1421,7 +1421,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (tf1, Application._cachedViewsUnderMouse.LastOrDefault ()); // Click on tf2 to focus it - Application.OnMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked }); Assert.False (tf1.HasFocus); Assert.True (tf2.HasFocus); Assert.Equal (4, win.Subviews.Count); diff --git a/UnitTests/Views/LabelTests.cs b/UnitTests/Views/LabelTests.cs index 2eb73d34f..80f1e2b7c 100644 --- a/UnitTests/Views/LabelTests.cs +++ b/UnitTests/Views/LabelTests.cs @@ -1364,7 +1364,7 @@ e Application.Top.SetFocus (); // click on label - Application.OnMouseEvent (new () { ScreenPosition = label.Frame.Location, Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = label.Frame.Location, Flags = MouseFlags.Button1Clicked }); Assert.False (label.HasFocus); Assert.True (nextView.HasFocus); @@ -1442,12 +1442,12 @@ e Assert.True (otherView.HasFocus); // label can focus, so clicking on it set focus - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); Assert.True (label.HasFocus); Assert.False (otherView.HasFocus); // click on view - Application.OnMouseEvent (new () { ScreenPosition = new (0, 1), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 1), Flags = MouseFlags.Button1Clicked }); Assert.False (label.HasFocus); Assert.True (otherView.HasFocus); diff --git a/UnitTests/Views/ListViewTests.cs b/UnitTests/Views/ListViewTests.cs index 3da369db1..1f5553c2c 100644 --- a/UnitTests/Views/ListViewTests.cs +++ b/UnitTests/Views/ListViewTests.cs @@ -737,11 +737,11 @@ Item 6", └─────┘", output); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); Assert.Equal ("", selected); Assert.Equal (-1, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Clicked @@ -749,7 +749,7 @@ Item 6", Assert.Equal ("One", selected); Assert.Equal (0, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 2), Flags = MouseFlags.Button1Clicked @@ -757,7 +757,7 @@ Item 6", Assert.Equal ("Two", selected); Assert.Equal (1, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked @@ -765,7 +765,7 @@ Item 6", Assert.Equal ("Three", selected); Assert.Equal (2, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 4), Flags = MouseFlags.Button1Clicked diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 938001fe1..7ef68bfe2 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -243,7 +243,7 @@ public class MenuBarTests (ITestOutputHelper output) top.Add (menu, btn); Application.Begin (top); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 4), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 4), Flags = MouseFlags.Button1Clicked }); Assert.True (btnClicked); top.Dispose (); } @@ -613,7 +613,7 @@ public class MenuBarTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); firstIteration = false; @@ -646,7 +646,7 @@ public class MenuBarTests (ITestOutputHelper output) { menu.OpenMenu (); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rsDialog, ref firstIteration); @@ -809,7 +809,7 @@ public class MenuBarTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); firstIteration = false; @@ -831,7 +831,7 @@ public class MenuBarTests (ITestOutputHelper output) { menu.OpenMenu (); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); diff --git a/UnitTests/Views/ScrollBarViewTests.cs b/UnitTests/Views/ScrollBarViewTests.cs index 989962d00..01b9e7a49 100644 --- a/UnitTests/Views/ScrollBarViewTests.cs +++ b/UnitTests/Views/ScrollBarViewTests.cs @@ -1176,7 +1176,7 @@ This is a test ", _output ); - Application.OnMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); Assert.Null (Application.MouseGrabView); Assert.True (clicked); @@ -1200,7 +1200,7 @@ This is a test ", _output ); - Application.OnMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); Assert.Null (Application.MouseGrabView); Assert.True (clicked); diff --git a/UnitTests/Views/ShortcutTests.cs b/UnitTests/Views/ShortcutTests.cs index 711ce243f..160f57439 100644 --- a/UnitTests/Views/ShortcutTests.cs +++ b/UnitTests/Views/ShortcutTests.cs @@ -424,7 +424,7 @@ public class ShortcutTests var accepted = 0; shortcut.Accepting += (s, e) => accepted++; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (x, 0), @@ -484,7 +484,7 @@ public class ShortcutTests Application.Top.SetRelativeLayout (new (100, 100)); Application.Top.LayoutSubviews (); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (mouseX, 0), @@ -541,7 +541,7 @@ public class ShortcutTests var accepted = 0; shortcut.Accepting += (s, e) => { accepted++; }; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (mouseX, 0), @@ -616,7 +616,7 @@ public class ShortcutTests e.Cancel = true; }; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (mouseX, 0), diff --git a/UnitTests/Views/TabViewTests.cs b/UnitTests/Views/TabViewTests.cs index dd1d3546d..9d769addc 100644 --- a/UnitTests/Views/TabViewTests.cs +++ b/UnitTests/Views/TabViewTests.cs @@ -144,21 +144,21 @@ public class TabViewTests (ITestOutputHelper output) for (var i = 0; i < 100; i++) { args = new () { ScreenPosition = new (i, 1), Flags = MouseFlags.ReportMousePosition }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab1, tv.SelectedTab); } args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Equal (tab1, clicked); Assert.Equal (tab1, tv.SelectedTab); // Click to tab2 args = new () { ScreenPosition = new (6, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Equal (tab2, clicked); Assert.Equal (tab2, tv.SelectedTab); @@ -171,7 +171,7 @@ public class TabViewTests (ITestOutputHelper output) }; args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); // Tab 1 was clicked but event handler blocked navigation @@ -179,7 +179,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab2, tv.SelectedTab); args = new () { ScreenPosition = new (12, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); // Clicking beyond last tab should raise event with null Tab @@ -234,7 +234,7 @@ public class TabViewTests (ITestOutputHelper output) // Click the right arrow var args = new MouseEvent { ScreenPosition = new (6, 2), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab1, oldChanged); @@ -254,7 +254,7 @@ public class TabViewTests (ITestOutputHelper output) // Click the left arrow args = new () { ScreenPosition = new (0, 2), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab2, oldChanged); @@ -325,7 +325,7 @@ public class TabViewTests (ITestOutputHelper output) // Click the right arrow var args = new MouseEvent { ScreenPosition = new (7, 3), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab1, oldChanged); @@ -347,7 +347,7 @@ public class TabViewTests (ITestOutputHelper output) // Click the left arrow args = new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab2, oldChanged); diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index 0de972262..40b3b8378 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -1180,13 +1180,13 @@ public class TextFieldTests (ITestOutputHelper output) var mouseEvent = new MouseEvent { Flags = MouseFlags.Button1Clicked, View = tf }; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (1, clickCounter); // Get a fresh instance that represents a right click. // Should be ignored because of SuppressRightClick callback mouseEvent = new () { Flags = MouseFlags.Button3Clicked, View = tf }; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (1, clickCounter); Application.MouseEvent -= HandleRightClick; @@ -1199,7 +1199,7 @@ public class TextFieldTests (ITestOutputHelper output) // This call causes the context menu to pop, and MouseEvent() returns true. // Thus, the clickCounter is NOT incremented. // Which is correct, because the user did NOT click with the left mouse button. - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (1, clickCounter); top.Dispose (); diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index f5f42b19c..cbf11e4b2 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -440,7 +440,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); // Grab the mouse - Application.OnMouseEvent (new () { ScreenPosition = new (3, 2), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (3, 2), Flags = MouseFlags.Button1Pressed }); Assert.Equal (Application.Top!.Border, Application.MouseGrabView); Assert.Equal (new (2, 2, 10, 3), Application.Top.Frame); @@ -450,7 +450,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (Application.Top!.Border, Application.MouseGrabView); // Drag to left - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (2, 2), Flags = MouseFlags.Button1Pressed @@ -473,7 +473,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (Application.Top!.Border, Application.MouseGrabView); // Drag up - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (2, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -496,7 +496,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (Application.Top!.Border, Application.MouseGrabView); // Ungrab the mouse - Application.OnMouseEvent (new () { ScreenPosition = new (2, 1), Flags = MouseFlags.Button1Released }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (2, 1), Flags = MouseFlags.Button1Released }); Application.Refresh (); Assert.Null (Application.MouseGrabView); @@ -545,7 +545,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); // Grab the mouse - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X, win.Frame.Y), Flags = MouseFlags.Button1Pressed @@ -561,7 +561,7 @@ public partial class ToplevelTests (ITestOutputHelper output) movex = 1; movey = 0; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), Flags = @@ -586,7 +586,7 @@ public partial class ToplevelTests (ITestOutputHelper output) movex = 0; movey = -1; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), Flags = @@ -611,7 +611,7 @@ public partial class ToplevelTests (ITestOutputHelper output) movex = 0; movey = 0; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), @@ -743,18 +743,18 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 200, 100), scrollView.Subviews [0].Frame); Assert.Equal (new (3, 3, 194, 94), win.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (6, 6), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (6, 6), Flags = MouseFlags.Button1Pressed }); Assert.Equal (win.Border, Application.MouseGrabView); Assert.Equal (new (3, 3, 194, 94), win.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (9, 9), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (9, 9), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); Assert.Equal (win.Border, Application.MouseGrabView); top.SetNeedsLayout (); top.LayoutSubviews (); Assert.Equal (new (6, 6, 191, 91), win.Frame); Application.Refresh (); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (5, 5), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -765,12 +765,12 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (2, 2, 195, 95), win.Frame); Application.Refresh (); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.Button1Released }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.Button1Released }); // ScrollView always grab the mouse when the container's subview OnMouseEnter don't want grab the mouse Assert.Equal (scrollView, Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (4, 4), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (4, 4), Flags = MouseFlags.ReportMousePosition }); Assert.Equal (scrollView, Application.MouseGrabView); top.Dispose (); } @@ -790,11 +790,11 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); Assert.Equal (window.Border, Application.MouseGrabView); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (-11, -4), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -807,7 +807,7 @@ public partial class ToplevelTests (ITestOutputHelper output) // Changes Top size to same size as Dialog more menu and scroll bar ((FakeDriver)Application.Driver!).SetBufferSize (20, 3); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (-1, -1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -820,7 +820,7 @@ public partial class ToplevelTests (ITestOutputHelper output) // Changes Top size smaller than Dialog size ((FakeDriver)Application.Driver!).SetBufferSize (19, 2); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (-1, -1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -830,7 +830,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 19, 2), top.Frame); Assert.Equal (new (-1, -1, 20, 3), window.Frame); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (18, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -841,7 +841,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (18, 1, 20, 3), window.Frame); // On a real app we can't go beyond the SuperView bounds - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (19, 2), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -882,7 +882,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); Assert.Equal (new (0, 0, 10, 3), window.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -890,7 +890,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 10, 3), window.Frame); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -984,7 +984,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (2, 1, 15, 10), testWindow.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 2), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 2), Flags = MouseFlags.Button1Clicked }); Application.Refresh (); From a19781c53b66a47241a2f10c05b323bd147955a3 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 14 Oct 2024 20:25:24 -0600 Subject: [PATCH 16/35] View.Mouse cleanup - WIP2 --- .../Autocomplete/PopupAutocomplete.PopUp.cs | 2 +- Terminal.Gui/View/Adornment/Border.cs | 4 +-- Terminal.Gui/View/Adornment/Padding.cs | 2 +- Terminal.Gui/View/View.Mouse.cs | 31 ++++++++++++++----- Terminal.Gui/Views/ColorBar.cs | 5 ++- Terminal.Gui/Views/ComboBox.cs | 4 +-- Terminal.Gui/Views/DateField.cs | 2 +- Terminal.Gui/Views/HexView.cs | 2 +- Terminal.Gui/Views/ListView.cs | 2 +- Terminal.Gui/Views/Menu/Menu.cs | 2 +- Terminal.Gui/Views/Menu/MenuBar.cs | 2 +- Terminal.Gui/Views/ScrollBarView.cs | 2 +- Terminal.Gui/Views/ScrollView.cs | 12 +++---- Terminal.Gui/Views/Slider.cs | 2 +- Terminal.Gui/Views/TabView.cs | 2 +- Terminal.Gui/Views/TableView/TableView.cs | 7 +++-- Terminal.Gui/Views/TextField.cs | 4 +-- Terminal.Gui/Views/TextValidateField.cs | 2 +- Terminal.Gui/Views/TextView.cs | 4 +-- Terminal.Gui/Views/TileView.cs | 2 +- Terminal.Gui/Views/TimeField.cs | 2 +- Terminal.Gui/Views/TreeView/TreeView.cs | 4 +-- UICatalog/Scenarios/LineDrawing.cs | 8 +++-- UnitTests/Views/ColorPickerTests.cs | 8 ++--- 24 files changed, 68 insertions(+), 49 deletions(-) diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs index 622e6620b..e53cbc0aa 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs @@ -25,6 +25,6 @@ public abstract partial class PopupAutocomplete _autoComplete.RenderOverlay (_autoComplete.LastPopupPos.Value); } - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) { return _autoComplete.OnMouseEvent (mouseEvent); } + protected override bool OnMouseEvent (MouseEvent mouseEvent) { return _autoComplete.OnMouseEvent (mouseEvent); } } } diff --git a/Terminal.Gui/View/Adornment/Border.cs b/Terminal.Gui/View/Adornment/Border.cs index 082df687f..73f1aa68f 100644 --- a/Terminal.Gui/View/Adornment/Border.cs +++ b/Terminal.Gui/View/Adornment/Border.cs @@ -262,9 +262,9 @@ public class Border : Adornment private Point _startGrabPoint; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEvent mouseEvent) { - if (base.OnMouseEvent (mouseEvent)) + if (base.RaiseMouseEvent (mouseEvent)) { return true; } diff --git a/Terminal.Gui/View/Adornment/Padding.cs b/Terminal.Gui/View/Adornment/Padding.cs index 8f51a4f9b..5eb1eda72 100644 --- a/Terminal.Gui/View/Adornment/Padding.cs +++ b/Terminal.Gui/View/Adornment/Padding.cs @@ -50,7 +50,7 @@ public class Padding : Adornment /// /// /// , if the event was handled, otherwise. - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEvent mouseEvent) { if (Parent is null) { diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 48a3ea126..91ca12bdb 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -212,14 +212,14 @@ public partial class View // Mouse APIs /// A view must be both enabled and visible to receive mouse events. /// /// - /// This method raises /; if not handled, and one of the + /// This method raises /; if not handled, and one of the /// mouse buttons was clicked, the / event will be raised /// /// /// See for more information. /// /// - /// If is , the / event + /// If is , the / event /// will be raised on any new mouse event where indicates a button is pressed. /// /// @@ -245,7 +245,7 @@ public partial class View // Mouse APIs } // Cancellable event - if (OnMouseEvent (mouseEvent)) + if (RaiseMouseEvent (mouseEvent)) { // Technically mouseEvent.Handled should already be true if implementers of OnMouseEvent // follow the rules. But we'll update it just in case. @@ -296,6 +296,25 @@ public partial class View // Mouse APIs return false; } + /// + /// Raises the / event. + /// + /// + /// , if the event was handled, otherwise. + public bool RaiseMouseEvent (MouseEvent mouseEvent) + { + var args = new MouseEventEventArgs (mouseEvent); + + if (OnMouseEvent (mouseEvent) || mouseEvent.Handled == true) + { + return true; + } + + MouseEvent?.Invoke (this, args); + + return args.Handled; + } + /// Called when a mouse event occurs within the view's . /// /// @@ -306,11 +325,7 @@ public partial class View // Mouse APIs /// , if the event was handled, otherwise. protected virtual bool OnMouseEvent (MouseEvent mouseEvent) { - var args = new MouseEventEventArgs (mouseEvent); - - MouseEvent?.Invoke (this, args); - - return args.Handled; + return false; } /// Raised when a mouse event occurs. diff --git a/Terminal.Gui/Views/ColorBar.cs b/Terminal.Gui/Views/ColorBar.cs index 066ad72b2..ea6197959 100644 --- a/Terminal.Gui/Views/ColorBar.cs +++ b/Terminal.Gui/Views/ColorBar.cs @@ -110,7 +110,7 @@ internal abstract class ColorBar : View, IColorBar public event EventHandler>? ValueChanged; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEvent mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { @@ -123,10 +123,9 @@ internal abstract class ColorBar : View, IColorBar mouseEvent.Handled = true; SetFocus (); - return true; } - return base.OnMouseEvent (mouseEvent); + return mouseEvent.Handled; } /// diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 3f92174c8..5f2cf7a0a 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -253,7 +253,7 @@ public class ComboBox : View, IDesignable public event EventHandler Expanded; /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { if (me.Position.X == Viewport.Right - 1 && me.Position.Y == Viewport.Top @@ -837,7 +837,7 @@ public class ComboBox : View, IDesignable } // BUGBUG: OnMouseEvent is internal! - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { var res = false; bool isMousePositionValid = IsMousePositionValid (me); diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 49da4f100..c2a2acbed 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -114,7 +114,7 @@ public class DateField : TextField } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEvent ev) { bool result = base.OnMouseEvent (ev); diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index a5a213b82..a6e838233 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -250,7 +250,7 @@ public class HexView : View, IDesignable public event EventHandler Edited; /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 1fa76e540..e1f3a4f19 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -472,7 +472,7 @@ public class ListView : View, IDesignable } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index b961f68bc..b5dc0abb2 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -806,7 +806,7 @@ internal sealed class Menu : View _host.SetNeedsDisplay (); } - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { if (!_host._handled && !_host.HandleGrabView (me, this)) { diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs index 731edc11c..06f63a1b4 100644 --- a/Terminal.Gui/Views/Menu/MenuBar.cs +++ b/Terminal.Gui/Views/Menu/MenuBar.cs @@ -1400,7 +1400,7 @@ public class MenuBar : View, IDesignable } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected bool OnMouseEvent (MouseEvent me) { if (!_handled && !HandleGrabView (me, this)) { diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs index ce7bd62eb..53da7b181 100644 --- a/Terminal.Gui/Views/ScrollBarView.cs +++ b/Terminal.Gui/Views/ScrollBarView.cs @@ -270,7 +270,7 @@ public class ScrollBarView : View public event EventHandler ChangedPosition; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEvent mouseEvent) { if (mouseEvent.Flags != MouseFlags.Button1Pressed && mouseEvent.Flags != MouseFlags.Button1DoubleClicked diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 9ad1a75f1..e419904b6 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -406,7 +406,7 @@ public class ScrollView : View } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { if (!Enabled) { @@ -416,19 +416,19 @@ public class ScrollView : View if (me.Flags == MouseFlags.WheeledDown && ShowVerticalScrollIndicator) { - ScrollDown (1); + return ScrollDown (1); } else if (me.Flags == MouseFlags.WheeledUp && ShowVerticalScrollIndicator) { - ScrollUp (1); + return ScrollUp (1); } else if (me.Flags == MouseFlags.WheeledRight && _showHorizontalScrollIndicator) { - ScrollRight (1); + return ScrollRight (1); } else if (me.Flags == MouseFlags.WheeledLeft && ShowVerticalScrollIndicator) { - ScrollLeft (1); + return ScrollLeft (1); } else if (me.Position.X == _vertical.Frame.X && ShowVerticalScrollIndicator) { @@ -443,7 +443,7 @@ public class ScrollView : View Application.UngrabMouse (); } - return base.OnMouseEvent (me); + return me.Handled; } /// diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index 4c331251b..d68cffa17 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -1282,7 +1282,7 @@ public class Slider : View, IOrientation private Point? _moveRenderPosition; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEvent mouseEvent) { // Note(jmperricone): Maybe we click to focus the cursor, and on next click we set the option. // That will make OptionFocused Event more relevant. diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 3e63dde53..9d770ffdc 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -569,7 +569,7 @@ public class TabView : View Add (_rightScrollIndicator, _leftScrollIndicator); } - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { Tab hit = me.View is Tab ? (Tab)me.View : null; diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 5da0b11e3..b8bb1ca39 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -801,7 +801,7 @@ public class TableView : View } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) @@ -892,6 +892,7 @@ public class TableView : View } Update (); + me.Handled = true; } } @@ -902,11 +903,11 @@ public class TableView : View if (hit is { }) { - OnCellActivated (new CellActivatedEventArgs (Table, hit.Value.X, hit.Value.Y)); + return OnCellActivated (new CellActivatedEventArgs (Table, hit.Value.X, hit.Value.Y)); } } - return base.OnMouseEvent (me); + return me.Handled; } /// diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 94f512ded..e49470f0a 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -798,7 +798,7 @@ public class TextField : View } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEvent ev) { if (!ev.Flags.HasFlag (MouseFlags.Button1Pressed) && !ev.Flags.HasFlag (MouseFlags.ReportMousePosition) @@ -807,7 +807,7 @@ public class TextField : View && !ev.Flags.HasFlag (MouseFlags.Button1TripleClicked) && !ev.Flags.HasFlag (ContextMenu.MouseFlags)) { - return base.OnMouseEvent (ev); + return false; } if (!CanFocus) diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index c6927b5e3..d526513f6 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -531,7 +531,7 @@ namespace Terminal.Gui } /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEvent mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 54174c495..8290caaf0 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3274,7 +3274,7 @@ public class TextView : View } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEvent ev) { if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked) && !ev.Flags.HasFlag (MouseFlags.Button1Pressed) @@ -3288,7 +3288,7 @@ public class TextView : View && !ev.Flags.HasFlag (MouseFlags.Button1TripleClicked) && !ev.Flags.HasFlag (ContextMenu!.MouseFlags)) { - return base.OnMouseEvent (ev); + return false; } if (!CanFocus) diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index ec117c652..8702243f9 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -910,7 +910,7 @@ public class TileView : View } } - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEvent mouseEvent) { if (!dragPosition.HasValue && mouseEvent.Flags == MouseFlags.Button1Pressed) { diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index 687a8cd71..63736c7da 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -163,7 +163,7 @@ public class TimeField : TextField } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEvent ev) { bool result = base.OnMouseEvent (ev); diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 36a249e8c..b59b5ed6b 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -990,7 +990,7 @@ public class TreeView : View, ITreeView where T : class // BUGBUG: OnMouseEvent is internal. TreeView should not be overriding. /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { // If it is not an event we care about if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) @@ -1001,7 +1001,7 @@ public class TreeView : View, ITreeView where T : class && !me.Flags.HasFlag (MouseFlags.WheeledLeft)) { // do nothing - return base.OnMouseEvent (me); + return false; } if (!HasFocus && CanFocus) diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index d2fdb7800..b173dd7bc 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -96,6 +96,8 @@ internal class DrawLineTool : ITool area.SetNeedsDisplay (); } } + + mouseEvent.Handled = true; } } @@ -325,7 +327,7 @@ public class DrawingArea : View { CurrentTool.OnMouseEvent (this, mouseEvent); - return base.OnMouseEvent (mouseEvent); + return mouseEvent.Handled; } internal void AddLayer () @@ -441,9 +443,11 @@ public class AttributeView : View { ClickedInBackground (); } + + mouseEvent.Handled = true; } - return base.OnMouseEvent (mouseEvent); + return mouseEvent.Handled; } private bool IsForegroundPoint (int x, int y) { return ForegroundPoints.Contains ((x, y)); } diff --git a/UnitTests/Views/ColorPickerTests.cs b/UnitTests/Views/ColorPickerTests.cs index 73fe010be..754e9e206 100644 --- a/UnitTests/Views/ColorPickerTests.cs +++ b/UnitTests/Views/ColorPickerTests.cs @@ -120,7 +120,7 @@ public class ColorPickerTests Assert.IsAssignableFrom (cp.Focused); - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, @@ -132,7 +132,7 @@ public class ColorPickerTests Assert.Equal (3, r.TrianglePosition); Assert.Equal ("#0F0000", hex.Text); - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, @@ -269,7 +269,7 @@ public class ColorPickerTests cp.Draw (); // Click at the end of the Red bar - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, @@ -303,7 +303,7 @@ public class ColorPickerTests cp.Draw (); // Click beyond the bar - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, From 1abe3182b665f57fdaf4bb5608e08b2d1cb34068 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 06:52:05 -0600 Subject: [PATCH 17/35] View.Mouse cleanup - WIP3 --- Terminal.Gui/Input/MouseEventEventArgs.cs | 4 ++-- Terminal.Gui/View/Adornment/Border.cs | 5 ----- Terminal.Gui/View/View.Mouse.cs | 16 ++++++---------- Terminal.Gui/Views/Bar.cs | 2 +- Terminal.Gui/Views/Button.cs | 2 +- Terminal.Gui/Views/ColorPicker.16.cs | 2 +- Terminal.Gui/Views/ComboBox.cs | 9 +-------- Terminal.Gui/Views/DateField.cs | 6 ++---- Terminal.Gui/Views/FileDialog.cs | 6 +++--- Terminal.Gui/Views/FrameView.cs | 2 +- Terminal.Gui/Views/Label.cs | 2 +- Terminal.Gui/Views/RadioGroup.cs | 2 +- Terminal.Gui/Views/ScrollBarView.cs | 2 +- Terminal.Gui/Views/TabView.cs | 2 +- .../TableView/CheckBoxTableSourceWrapper.cs | 2 +- Terminal.Gui/Views/TableView/TreeTableSource.cs | 2 +- Terminal.Gui/Views/TimeField.cs | 6 ++---- Terminal.Gui/Views/Toplevel.cs | 2 +- UICatalog/Scenarios/ASCIICustomButton.cs | 4 ++-- UICatalog/Scenarios/Bars.cs | 2 +- UICatalog/Scenarios/CharacterMap.cs | 4 ++-- UICatalog/Scenarios/ContentScrolling.cs | 2 +- UICatalog/Scenarios/TableEditor.cs | 2 +- UICatalog/Scenarios/TreeViewFileSystem.cs | 2 +- 24 files changed, 35 insertions(+), 55 deletions(-) diff --git a/Terminal.Gui/Input/MouseEventEventArgs.cs b/Terminal.Gui/Input/MouseEventEventArgs.cs index 89fc168a7..79aaff00d 100644 --- a/Terminal.Gui/Input/MouseEventEventArgs.cs +++ b/Terminal.Gui/Input/MouseEventEventArgs.cs @@ -5,11 +5,11 @@ /// the wrapped class and is used for the events defined on and subclasses /// of View (e.g. and ). /// -public class MouseEventEventArgs : EventArgs +public class MouseEventArgs : EventArgs { /// Constructs. /// The mouse event. - public MouseEventEventArgs (MouseEvent me) { MouseEvent = me; } + public MouseEventArgs (MouseEvent me) { MouseEvent = me; } /// /// Indicates if the current mouse event has already been processed and the driver should stop notifying any other diff --git a/Terminal.Gui/View/Adornment/Border.cs b/Terminal.Gui/View/Adornment/Border.cs index 73f1aa68f..a9c87919a 100644 --- a/Terminal.Gui/View/Adornment/Border.cs +++ b/Terminal.Gui/View/Adornment/Border.cs @@ -264,11 +264,6 @@ public class Border : Adornment /// protected override bool OnMouseEvent (MouseEvent mouseEvent) { - if (base.RaiseMouseEvent (mouseEvent)) - { - return true; - } - // BUGBUG: See https://github.com/gui-cs/Terminal.Gui/issues/3312 if (!_dragPosition.HasValue && mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) // HACK: Prevents Window from being draggable if it's Top diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 91ca12bdb..e6d81687c 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -245,15 +245,11 @@ public partial class View // Mouse APIs } // Cancellable event - if (RaiseMouseEvent (mouseEvent)) + if (RaiseMouseEvent (mouseEvent) || mouseEvent.Handled) { - // Technically mouseEvent.Handled should already be true if implementers of OnMouseEvent - // follow the rules. But we'll update it just in case. - return mouseEvent.Handled = true; + return true; } - // BUGBUG: MouseEvent should be fired from here. Fix this in https://github.com/gui-cs/Terminal.Gui/issues/3029 - // Post-Conditions if (HighlightStyle != HighlightStyle.None || (WantContinuousButtonPressed && WantMousePositionReports)) { @@ -303,7 +299,7 @@ public partial class View // Mouse APIs /// , if the event was handled, otherwise. public bool RaiseMouseEvent (MouseEvent mouseEvent) { - var args = new MouseEventEventArgs (mouseEvent); + var args = new MouseEventArgs (mouseEvent); if (OnMouseEvent (mouseEvent) || mouseEvent.Handled == true) { @@ -334,7 +330,7 @@ public partial class View // Mouse APIs /// The coordinates are relative to . /// /// - public event EventHandler? MouseEvent; + public event EventHandler? MouseEvent; #endregion Low Level Mouse Events @@ -351,7 +347,7 @@ public partial class View // Mouse APIs /// The coordinates are relative to . /// /// - public event EventHandler? MouseClick; + public event EventHandler? MouseClick; /// Invokes the MouseClick event. /// @@ -361,7 +357,7 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - protected bool OnMouseClick (MouseEventEventArgs args) + protected bool OnMouseClick (MouseEventArgs args) { // BUGBUG: This should be named NewMouseClickEvent. Fix this in https://github.com/gui-cs/Terminal.Gui/issues/3029 diff --git a/Terminal.Gui/Views/Bar.cs b/Terminal.Gui/Views/Bar.cs index ddaa44436..8e570eaf9 100644 --- a/Terminal.Gui/Views/Bar.cs +++ b/Terminal.Gui/Views/Bar.cs @@ -45,7 +45,7 @@ public class Bar : View, IOrientation, IDesignable } } - private void OnMouseEvent (object? sender, MouseEventEventArgs e) + private void OnMouseEvent (object? sender, MouseEventArgs e) { NavigationDirection direction = NavigationDirection.Backward; diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index e29043ed9..f642f23d9 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -125,7 +125,7 @@ public class Button : View, IDesignable } } - private void Button_MouseClick (object sender, MouseEventEventArgs e) + private void Button_MouseClick (object sender, MouseEventArgs e) { if (e.Handled) { diff --git a/Terminal.Gui/Views/ColorPicker.16.cs b/Terminal.Gui/Views/ColorPicker.16.cs index c0ae78717..b3a294369 100644 --- a/Terminal.Gui/Views/ColorPicker.16.cs +++ b/Terminal.Gui/Views/ColorPicker.16.cs @@ -181,7 +181,7 @@ public class ColorPicker16 : View // TODO: Decouple Cursor from SelectedColor so that mouse press-and-hold can show the color under the cursor. - private void ColorPicker_MouseClick (object sender, MouseEventEventArgs me) + private void ColorPicker_MouseClick (object sender, MouseEventArgs me) { // if (CanFocus) { diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 5f2cf7a0a..f1aaf3f9c 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -836,17 +836,10 @@ public class ComboBox : View, IDesignable set => _hideDropdownListOnClick = WantContinuousButtonPressed = value; } - // BUGBUG: OnMouseEvent is internal! protected override bool OnMouseEvent (MouseEvent me) { - var res = false; bool isMousePositionValid = IsMousePositionValid (me); - if (isMousePositionValid) - { - res = base.OnMouseEvent (me); - } - if (HideDropdownListOnClick && me.Flags == MouseFlags.Button1Clicked) { if (!isMousePositionValid && !_isFocusing) @@ -879,7 +872,7 @@ public class ComboBox : View, IDesignable return true; } - return res; + return false; } public override void OnDrawContent (Rectangle viewport) diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index c2a2acbed..0abc62984 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -116,14 +116,12 @@ public class DateField : TextField /// protected override bool OnMouseEvent (MouseEvent ev) { - bool result = base.OnMouseEvent (ev); - - if (result && SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) + if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { AdjCursorPosition (ev.Position.X); } - return result; + return ev.Handled; } /// Event firing method for the event. diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 78ed5b584..95d7330a8 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -1007,7 +1007,7 @@ public class FileDialog : Dialog } } - private void OnTableViewMouseClick (object sender, MouseEventEventArgs e) + private void OnTableViewMouseClick (object sender, MouseEventArgs e) { Point? clickedCell = _tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? clickedCol); @@ -1198,7 +1198,7 @@ public class FileDialog : Dialog private FileSystemInfoStats RowToStats (int rowIndex) { return State?.Children [rowIndex]; } - private void ShowCellContextMenu (Point? clickedCell, MouseEventEventArgs e) + private void ShowCellContextMenu (Point? clickedCell, MouseEventArgs e) { if (clickedCell is null) { @@ -1222,7 +1222,7 @@ public class FileDialog : Dialog contextMenu.Show (menuItems); } - private void ShowHeaderContextMenu (int clickedCol, MouseEventEventArgs e) + private void ShowHeaderContextMenu (int clickedCol, MouseEventArgs e) { string sort = GetProposedNewSortOrder (clickedCol, out bool isAsc); diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs index f8b1ffc8b..de2f86215 100644 --- a/Terminal.Gui/Views/FrameView.cs +++ b/Terminal.Gui/Views/FrameView.cs @@ -22,7 +22,7 @@ public class FrameView : View MouseClick += FrameView_MouseClick; } - private void FrameView_MouseClick (object sender, MouseEventEventArgs e) + private void FrameView_MouseClick (object sender, MouseEventArgs e) { // base sets focus on HotKey e.Handled = InvokeCommand (Command.HotKey, ctx: new (Command.HotKey, key: null, data: this)) == true; diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index 3a76a8a71..07eca7983 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -32,7 +32,7 @@ public class Label : View, IDesignable } // TODO: base raises Select, but we want to raise HotKey. This can be simplified? - private void Label_MouseClick (object sender, MouseEventEventArgs e) + private void Label_MouseClick (object sender, MouseEventArgs e) { if (!CanFocus) { diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index 5cfd9f72b..c45ae6e47 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -220,7 +220,7 @@ public class RadioGroup : View, IDesignable, IOrientation /// public bool DoubleClickAccepts { get; set; } = true; - private void RadioGroup_MouseClick (object? sender, MouseEventEventArgs e) + private void RadioGroup_MouseClick (object? sender, MouseEventArgs e) { if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) { diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs index 53da7b181..5eb955fb2 100644 --- a/Terminal.Gui/Views/ScrollBarView.cs +++ b/Terminal.Gui/Views/ScrollBarView.cs @@ -777,7 +777,7 @@ public class ScrollBarView : View // } //} - private void ContentBottomRightCorner_MouseClick (object sender, MouseEventEventArgs me) + private void ContentBottomRightCorner_MouseClick (object sender, MouseEventArgs me) { if (me.MouseEvent.Flags == MouseFlags.WheeledDown || me.MouseEvent.Flags == MouseFlags.WheeledUp diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 9d770ffdc..8de57757a 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -508,7 +508,7 @@ public class TabView : View return Style.ShowTopLine ? 3 : 2; } - private void Tab_MouseClick (object sender, MouseEventEventArgs e) + private void Tab_MouseClick (object sender, MouseEventArgs e) { e.Handled = _tabsBar.NewMouseEvent (e.MouseEvent) == true; } diff --git a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs index 8be294c1a..d0f7fed26 100644 --- a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs +++ b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs @@ -150,7 +150,7 @@ public abstract class CheckBoxTableSourceWrapperBase : ITableSource tableView.SetNeedsDisplay (); } - private void TableView_MouseClick (object sender, MouseEventEventArgs e) + private void TableView_MouseClick (object sender, MouseEventArgs e) { // we only care about clicks (not movements) if (!e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) diff --git a/Terminal.Gui/Views/TableView/TreeTableSource.cs b/Terminal.Gui/Views/TableView/TreeTableSource.cs index f2cab6509..88ab0cb3a 100644 --- a/Terminal.Gui/Views/TableView/TreeTableSource.cs +++ b/Terminal.Gui/Views/TableView/TreeTableSource.cs @@ -166,7 +166,7 @@ public class TreeTableSource : IEnumerableTableSource, IDisposable where T } } - private void Table_MouseClick (object sender, MouseEventEventArgs e) + private void Table_MouseClick (object sender, MouseEventArgs e) { Point? hit = _tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? headerIfAny, out int? offsetX); diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index 63736c7da..d32ea9d22 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -165,15 +165,13 @@ public class TimeField : TextField /// protected override bool OnMouseEvent (MouseEvent ev) { - bool result = base.OnMouseEvent (ev); - - if (result && SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) + if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { int point = ev.Position.X; AdjCursorPosition (point); } - return result; + return ev.Handled; } /// diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index cfcdcc14d..ddee6b041 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -62,7 +62,7 @@ public partial class Toplevel : View /// public bool Modal { get; set; } - private void Toplevel_MouseClick (object? sender, MouseEventEventArgs e) { e.Handled = InvokeCommand (Command.HotKey) == true; } + private void Toplevel_MouseClick (object? sender, MouseEventArgs e) { e.Handled = InvokeCommand (Command.HotKey) == true; } #endregion diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs index 661efd80d..c1a906a4d 100644 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ b/UICatalog/Scenarios/ASCIICustomButton.cs @@ -127,7 +127,7 @@ public class ASCIICustomButtonTest : Scenario } public event Action PointerEnter; - private void This_MouseClick (object sender, MouseEventEventArgs obj) { NewMouseEvent (obj.MouseEvent); } + private void This_MouseClick (object sender, MouseEventArgs obj) { NewMouseEvent (obj.MouseEvent); } } public class ScrollViewTestWindow : Window @@ -310,7 +310,7 @@ public class ASCIICustomButtonTest : Scenario } } - private void Button_MouseClick (object sender, MouseEventEventArgs obj) + private void Button_MouseClick (object sender, MouseEventArgs obj) { if (obj.MouseEvent.Flags == MouseFlags.WheeledDown) { diff --git a/UICatalog/Scenarios/Bars.cs b/UICatalog/Scenarios/Bars.cs index 63fdbd85f..23b13cee5 100644 --- a/UICatalog/Scenarios/Bars.cs +++ b/UICatalog/Scenarios/Bars.cs @@ -187,7 +187,7 @@ public class Bars : Scenario menuLikeExamples.MouseClick += MenuLikeExamplesMouseClick; - void MenuLikeExamplesMouseClick (object sender, MouseEventEventArgs e) + void MenuLikeExamplesMouseClick (object sender, MouseEventArgs e) { if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) { diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs index 5e246f9df..caebcb406 100644 --- a/UICatalog/Scenarios/CharacterMap.cs +++ b/UICatalog/Scenarios/CharacterMap.cs @@ -527,7 +527,7 @@ internal class CharMap : View Padding.Add (up, down, left, right); } - private void Handle_MouseEvent (object sender, MouseEventEventArgs e) + private void Handle_MouseEvent (object sender, MouseEventArgs e) { if (e.MouseEvent.Flags == MouseFlags.WheeledDown) { @@ -839,7 +839,7 @@ internal class CharMap : View private void CopyCodePoint () { Clipboard.Contents = $"U+{SelectedCodePoint:x5}"; } private void CopyGlyph () { Clipboard.Contents = $"{new Rune (SelectedCodePoint)}"; } - private void Handle_MouseClick (object sender, MouseEventEventArgs args) + private void Handle_MouseClick (object sender, MouseEventArgs args) { MouseEvent me = args.MouseEvent; diff --git a/UICatalog/Scenarios/ContentScrolling.cs b/UICatalog/Scenarios/ContentScrolling.cs index 028717fcd..8c97d3e2a 100644 --- a/UICatalog/Scenarios/ContentScrolling.cs +++ b/UICatalog/Scenarios/ContentScrolling.cs @@ -52,7 +52,7 @@ public class ContentScrolling : Scenario MouseEvent += VirtualDemoView_MouseEvent; } - private void VirtualDemoView_MouseEvent (object sender, MouseEventEventArgs e) + private void VirtualDemoView_MouseEvent (object sender, MouseEventArgs e) { if (e.MouseEvent.Flags == MouseFlags.WheeledDown) { diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index d127f8610..eaeab748e 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -1254,7 +1254,7 @@ public class TableEditor : Scenario _tableView.Update (); } - private void ShowHeaderContextMenu (int clickedCol, MouseEventEventArgs e) + private void ShowHeaderContextMenu (int clickedCol, MouseEventArgs e) { if (HasCheckboxes () && clickedCol == 0) { diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index 590af81b1..ae288a5df 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -484,7 +484,7 @@ public class TreeViewFileSystem : Scenario } } - private void TreeViewFiles_MouseClick (object sender, MouseEventEventArgs obj) + private void TreeViewFiles_MouseClick (object sender, MouseEventArgs obj) { // if user right clicks if (obj.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) From 0a6ba8315bad9c268b168a8a384c528ebce510dd Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 06:56:53 -0600 Subject: [PATCH 18/35] View.Mouse cleanup - Fixed combobox --- Terminal.Gui/Views/ComboBox.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index f1aaf3f9c..e7702519d 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -840,6 +840,14 @@ public class ComboBox : View, IDesignable { bool isMousePositionValid = IsMousePositionValid (me); + var res = false; + + if (isMousePositionValid) + { + // We're derived from ListView and it overrides OnMouseEvent, so we need to call it + res = base.OnMouseEvent (me); + } + if (HideDropdownListOnClick && me.Flags == MouseFlags.Button1Clicked) { if (!isMousePositionValid && !_isFocusing) @@ -872,7 +880,7 @@ public class ComboBox : View, IDesignable return true; } - return false; + return res; } public override void OnDrawContent (Rectangle viewport) From 681dd9bd8ede1c33aeab90edf35032f07457af6c Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 07:04:51 -0600 Subject: [PATCH 19/35] View.Mouse cleanup - Fixed combobox --- Terminal.Gui/Views/Menu/Menu.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index b5dc0abb2..9f672ec23 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -1,5 +1,7 @@ #nullable enable +using static System.Formats.Asn1.AsnWriter; + namespace Terminal.Gui; /// From 2e37ca35923e04c953304450d11c42255c54add2 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 07:07:28 -0600 Subject: [PATCH 20/35] View.Mouse cleanup - Fixed MenuBar --- Terminal.Gui/Views/Menu/MenuBar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs index 06f63a1b4..8dbcfe29b 100644 --- a/Terminal.Gui/Views/Menu/MenuBar.cs +++ b/Terminal.Gui/Views/Menu/MenuBar.cs @@ -1400,7 +1400,7 @@ public class MenuBar : View, IDesignable } /// - protected bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEvent me) { if (!_handled && !HandleGrabView (me, this)) { From 8807e485c3425334b0b493c66c61f71821023ffa Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 07:11:38 -0600 Subject: [PATCH 21/35] View.Mouse cleanup - Fixed TableView --- Terminal.Gui/Views/TableView/TableView.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index b8bb1ca39..b2fc063dd 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -892,7 +892,6 @@ public class TableView : View } Update (); - me.Handled = true; } } From 1363995326b28dc22c0bdeab5816137f414c0816 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 07:40:42 -0600 Subject: [PATCH 22/35] Merged MouseEvent and MouseEventEventArgs into MouseEventArgs --- .../Application/Application.Initialization.cs | 2 +- Terminal.Gui/Application/Application.Mouse.cs | 18 +++---- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 4 +- .../CursesDriver/CursesDriver.cs | 2 +- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 6 +-- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 10 ++-- Terminal.Gui/Input/MouseEventArgs.cs | 31 +++++++++++ Terminal.Gui/Input/MouseEventEventArgs.cs | 32 ----------- .../Input/{Mouse.cs => MouseFlags.cs} | 51 +----------------- .../Text/Autocomplete/AppendAutocomplete.cs | 2 +- .../Text/Autocomplete/AutocompleteBase.cs | 2 +- .../Text/Autocomplete/IAutocomplete.cs | 2 +- .../Autocomplete/PopupAutocomplete.PopUp.cs | 2 +- .../Text/Autocomplete/PopupAutocomplete.cs | 4 +- Terminal.Gui/View/Adornment/Border.cs | 4 +- Terminal.Gui/View/Adornment/Padding.cs | 2 +- Terminal.Gui/View/View.Mouse.cs | 32 ++++++----- Terminal.Gui/Views/Bar.cs | 8 +-- Terminal.Gui/Views/ColorBar.cs | 2 +- Terminal.Gui/Views/ColorPicker.16.cs | 2 +- Terminal.Gui/Views/ComboBox.cs | 6 +-- Terminal.Gui/Views/DateField.cs | 2 +- Terminal.Gui/Views/FileDialog.cs | 12 ++--- Terminal.Gui/Views/HexView.cs | 2 +- Terminal.Gui/Views/ListView.cs | 2 +- Terminal.Gui/Views/Menu/Menu.cs | 6 +-- Terminal.Gui/Views/Menu/MenuBar.cs | 8 +-- Terminal.Gui/Views/RadioGroup.cs | 8 +-- Terminal.Gui/Views/ScrollBarView.cs | 14 ++--- Terminal.Gui/Views/ScrollView.cs | 2 +- Terminal.Gui/Views/Slider.cs | 4 +- Terminal.Gui/Views/TabMouseEventArgs.cs | 6 +-- Terminal.Gui/Views/TabView.cs | 4 +- .../TableView/CheckBoxTableSourceWrapper.cs | 4 +- Terminal.Gui/Views/TableView/TableView.cs | 4 +- .../Views/TableView/TreeTableSource.cs | 2 +- Terminal.Gui/Views/TextField.cs | 4 +- Terminal.Gui/Views/TextValidateField.cs | 2 +- Terminal.Gui/Views/TextView.cs | 4 +- Terminal.Gui/Views/TileView.cs | 2 +- Terminal.Gui/Views/TimeField.cs | 2 +- Terminal.Gui/Views/TreeView/TreeView.cs | 2 +- UICatalog/Scenarios/ASCIICustomButton.cs | 6 +-- UICatalog/Scenarios/AdornmentsEditor.cs | 2 +- UICatalog/Scenarios/ArrangementEditor.cs | 2 +- UICatalog/Scenarios/Bars.cs | 14 ++--- UICatalog/Scenarios/CharacterMap.cs | 18 +++---- UICatalog/Scenarios/ContentScrolling.cs | 8 +-- UICatalog/Scenarios/ContextMenus.cs | 6 +-- UICatalog/Scenarios/LineDrawing.cs | 8 +-- UICatalog/Scenarios/ListColumns.cs | 2 +- UICatalog/Scenarios/Mouse.cs | 6 +-- UICatalog/Scenarios/TableEditor.cs | 8 +-- UICatalog/Scenarios/TreeViewFileSystem.cs | 8 +-- .../Mouse/ApplicationMouseEnterLeaveTests.cs | 6 +-- .../Mouse/ApplicationMouseTests.cs | 16 +++--- UnitTests/Input/ResponderTests.cs | 2 +- UnitTests/View/Mouse/MouseEnterLeaveTests.cs | 10 ++-- UnitTests/View/Mouse/MouseTests.cs | 22 ++++---- UnitTests/Views/ButtonTests.cs | 10 ++-- UnitTests/Views/ComboBoxTests.cs | 54 +++++++++---------- UnitTests/Views/ContextMenuTests.cs | 36 ++++++------- UnitTests/Views/ScrollBarViewTests.cs | 4 +- UnitTests/Views/TabViewTests.cs | 6 +-- UnitTests/Views/TextFieldTests.cs | 6 +-- UnitTests/Views/TextValidateFieldTests.cs | 2 +- UnitTests/Views/TextViewTests.cs | 34 ++++++------ UnitTests/Views/TreeTableSourceTests.cs | 8 +-- UnitTests/Views/TreeViewTests.cs | 8 +-- docfx/docs/mouse.md | 4 +- 70 files changed, 292 insertions(+), 344 deletions(-) create mode 100644 Terminal.Gui/Input/MouseEventArgs.cs delete mode 100644 Terminal.Gui/Input/MouseEventEventArgs.cs rename Terminal.Gui/Input/{Mouse.cs => MouseFlags.cs} (59%) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index c1058f838..02351612f 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -180,7 +180,7 @@ public static partial class Application // Initialization (Init/Shutdown) private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); } private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); } - private static void Driver_MouseEvent (object? sender, MouseEvent e) { RaiseMouseEvent (e); } + private static void Driver_MouseEvent (object? sender, MouseEventArgs e) { RaiseMouseEvent (e); } /// Gets of list of types that are available. /// diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index 9ac7df27a..47714c03f 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -130,7 +130,7 @@ public static partial class Application // Mouse handling /// /// This method can be used to simulate a mouse event, e.g. in unit tests. /// The mouse event with coordinates relative to the screen. - internal static void RaiseMouseEvent (MouseEvent mouseEvent) + internal static void RaiseMouseEvent (MouseEventArgs mouseEvent) { _lastMousePosition = mouseEvent.ScreenPosition; @@ -187,7 +187,7 @@ public static partial class Application // Mouse handling } // Create a view-relative mouse event to send to the view that is under the mouse. - MouseEvent? viewMouseEvent; + MouseEventArgs? viewMouseEvent; if (deepestViewUnderMouse is Adornment adornment) { @@ -255,25 +255,25 @@ public static partial class Application // Mouse handling } /// - /// Raised when a mouse event occurs. Can be cancelled by setting to . + /// Raised when a mouse event occurs. Can be cancelled by setting to . /// /// /// - /// coordinates are screen-relative. + /// coordinates are screen-relative. /// /// - /// will be the deepest view under the under the mouse. + /// will be the deepest view under the under the mouse. /// /// - /// coordinates are view-relative. + /// coordinates are view-relative. /// /// /// Use this evento to handle mouse events at the application level, before View-specific handling. /// /// - public static event EventHandler? MouseEvent; + public static event EventHandler? MouseEvent; - internal static bool HandleMouseGrab (View? deepestViewUnderMouse, MouseEvent mouseEvent) + internal static bool HandleMouseGrab (View? deepestViewUnderMouse, MouseEventArgs mouseEvent) { if (MouseGrabView is { }) { @@ -288,7 +288,7 @@ public static partial class Application // Mouse handling // The coordinates are relative to the Bounds of the view that grabbed the mouse. Point frameLoc = MouseGrabView.ScreenToViewport (mouseEvent.ScreenPosition); - var viewRelativeMouseEvent = new MouseEvent + var viewRelativeMouseEvent = new MouseEventArgs { Position = frameLoc, Flags = mouseEvent.Flags, diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 9f2a45465..7d6de3834 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -588,11 +588,11 @@ public abstract class ConsoleDriver public void OnKeyUp (Key a) { KeyUp?.Invoke (this, a); } /// Event fired when a mouse event occurs. - public event EventHandler? MouseEvent; + public event EventHandler? MouseEvent; /// Called when a mouse event occurs. Fires the event. /// - public void OnMouseEvent (MouseEvent a) + public void OnMouseEvent (MouseEventArgs a) { // Ensure ScreenPosition is set a.ScreenPosition = a.Position; diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 0b11949a9..b806457d4 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -1004,7 +1004,7 @@ internal class CursesDriver : ConsoleDriver _lastMouseFlags = mouseFlag; - var me = new MouseEvent { Flags = mouseFlag, Position = pos }; + var me = new MouseEventArgs { Flags = mouseFlag, Position = pos }; //Debug.WriteLine ($"CursesDriver: ({me.Position}) - {me.Flags}"); OnMouseEvent (me); diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 1298c1c35..8aaddc321 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1154,7 +1154,7 @@ internal class NetDriver : ConsoleDriver break; case EventType.Mouse: - MouseEvent me = ToDriverMouse (inputEvent.MouseEvent); + MouseEventArgs me = ToDriverMouse (inputEvent.MouseEvent); //Debug.WriteLine ($"NetDriver: ({me.X},{me.Y}) - {me.Flags}"); OnMouseEvent (me); @@ -1393,7 +1393,7 @@ internal class NetDriver : ConsoleDriver } } - private MouseEvent ToDriverMouse (NetEvents.MouseEvent me) + private MouseEventArgs ToDriverMouse (NetEvents.MouseEvent me) { //System.Diagnostics.Debug.WriteLine ($"X: {me.Position.X}; Y: {me.Position.Y}; ButtonState: {me.ButtonState}"); @@ -1539,7 +1539,7 @@ internal class NetDriver : ConsoleDriver mouseFlag |= MouseFlags.ButtonAlt; } - return new MouseEvent { Position = me.Position, Flags = mouseFlag }; + return new MouseEventArgs { Position = me.Position, Flags = mouseFlag }; } #endregion Mouse Handling diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 2a9bef081..fd5c6901c 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -1483,7 +1483,7 @@ internal class WindowsDriver : ConsoleDriver break; case WindowsConsole.EventType.Mouse: - MouseEvent me = ToDriverMouse (inputEvent.MouseEvent); + MouseEventArgs me = ToDriverMouse (inputEvent.MouseEvent); if (me is null || me.Flags == MouseFlags.None) { @@ -1827,9 +1827,9 @@ internal class WindowsDriver : ConsoleDriver } await Task.Delay (delay); - var me = new MouseEvent + var me = new MouseEventArgs { - Position = _pointMove, + ScreenPosition = _pointMove, Flags = mouseFlag }; @@ -1883,7 +1883,7 @@ internal class WindowsDriver : ConsoleDriver } [CanBeNull] - private MouseEvent ToDriverMouse (WindowsConsole.MouseEventRecord mouseEvent) + private MouseEventArgs ToDriverMouse (WindowsConsole.MouseEventRecord mouseEvent) { var mouseFlag = MouseFlags.AllEvents; @@ -2127,7 +2127,7 @@ internal class WindowsDriver : ConsoleDriver //System.Diagnostics.Debug.WriteLine ( // $"point.X:{(point is { } ? ((Point)point).X : -1)};point.Y:{(point is { } ? ((Point)point).Y : -1)}"); - return new MouseEvent + return new MouseEventArgs { Position = new (mouseEvent.MousePosition.X, mouseEvent.MousePosition.Y), Flags = mouseFlag diff --git a/Terminal.Gui/Input/MouseEventArgs.cs b/Terminal.Gui/Input/MouseEventArgs.cs new file mode 100644 index 000000000..90b746d5f --- /dev/null +++ b/Terminal.Gui/Input/MouseEventArgs.cs @@ -0,0 +1,31 @@ +using System.ComponentModel; + +namespace Terminal.Gui; + +/// +/// Specifies the event arguments for . This is a higher-level construct than +/// the wrapped class and is used for the events defined on and subclasses +/// of View (e.g. and ). +/// +public class MouseEventArgs : HandledEventArgs +{ + /// + /// Flags indicating the state of the mouse buttons and the type of event that occurred. + /// + public MouseFlags Flags { get; set; } + + /// + /// The screen-relative mouse position. + /// + public Point ScreenPosition { get; set; } + + /// The deepest View who's screen coordinates are . + public View View { get; set; } + + /// The position of the mouse in 's Viewport-relative coordinates. + public Point Position { get; set; } + + /// Returns a that represents the current . + /// A that represents the current . + public override string ToString () { return $"({Position}):{Flags}"; } +} diff --git a/Terminal.Gui/Input/MouseEventEventArgs.cs b/Terminal.Gui/Input/MouseEventEventArgs.cs deleted file mode 100644 index 79aaff00d..000000000 --- a/Terminal.Gui/Input/MouseEventEventArgs.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Terminal.Gui; - -/// -/// Specifies the event arguments for . This is a higher-level construct than -/// the wrapped class and is used for the events defined on and subclasses -/// of View (e.g. and ). -/// -public class MouseEventArgs : EventArgs -{ - /// Constructs. - /// The mouse event. - public MouseEventArgs (MouseEvent me) { MouseEvent = me; } - - /// - /// Indicates if the current mouse event has already been processed and the driver should stop notifying any other - /// event subscriber. It's important to set this value to true specially when updating any View's layout from inside the - /// subscriber method. - /// - /// - /// This property forwards to the property and is provided as a convenience and - /// for backwards compatibility - /// - public bool Handled - { - get => MouseEvent.Handled; - set => MouseEvent.Handled = value; - } - - // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. - /// The for the event. - public MouseEvent MouseEvent { get; set; } -} diff --git a/Terminal.Gui/Input/Mouse.cs b/Terminal.Gui/Input/MouseFlags.cs similarity index 59% rename from Terminal.Gui/Input/Mouse.cs rename to Terminal.Gui/Input/MouseFlags.cs index 8069a339d..e77175f75 100644 --- a/Terminal.Gui/Input/Mouse.cs +++ b/Terminal.Gui/Input/MouseFlags.cs @@ -1,12 +1,12 @@ namespace Terminal.Gui; -/// Mouse flags reported in . +/// Mouse flags reported in . /// They just happen to map to the ncurses ones. [Flags] public enum MouseFlags { /// - /// No mouse event. This is the default value for when no mouse event is being reported. + /// No mouse event. This is the default value for when no mouse event is being reported. /// None = 0, @@ -97,50 +97,3 @@ public enum MouseFlags /// Mask that captures all the events. AllEvents = 0x7ffffff } - -// TODO: Merge MouseEvent and MouseEventEventArgs into a single class. - -/// -/// Conveys the details of mouse events, such as coordinates and button state, from -/// ConsoleDrivers up to and Views. -/// -/// -/// The class includes the event which takes a -/// MouseEvent argument. -/// -public class MouseEvent -{ - /// Flags indicating the kind of mouse event that is being posted. - public MouseFlags Flags { get; set; } - - /// The View at the location for the mouse event. - public View View { get; set; } - - /// The position of the mouse in -relative coordinates. - public Point Position { get; set; } - - /// - /// The screen-relative mouse position. - /// - /// - /// - /// is -relative. When the mouse is grabbed by a view, - /// provides the mouse position screen-relative coordinates, enabling the grabbed view to know how much the - /// mouse has moved. - /// - /// - /// Calculated and processed in . - /// - /// - public Point ScreenPosition { get; set; } - - /// - /// Indicates if the current mouse event has been processed. Set this value to to indicate the mouse - /// event was handled. - /// - public bool Handled { get; set; } - - /// Returns a that represents the current . - /// A that represents the current . - public override string ToString () { return $"({Position}):{Flags}"; } -} diff --git a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs index 2fa920e70..9602776f5 100644 --- a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs @@ -59,7 +59,7 @@ public class AppendAutocomplete : AutocompleteBase } /// - public override bool OnMouseEvent (MouseEvent me, bool fromHost = false) { return false; } + public override bool OnMouseEvent (MouseEventArgs me, bool fromHost = false) { return false; } /// public override bool ProcessKey (Key a) diff --git a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs index 39d725ca4..ad51d5e22 100644 --- a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs +++ b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs @@ -49,7 +49,7 @@ public abstract class AutocompleteBase : IAutocomplete public virtual AutocompleteContext Context { get; set; } /// - public abstract bool OnMouseEvent (MouseEvent me, bool fromHost = false); + public abstract bool OnMouseEvent (MouseEventArgs me, bool fromHost = false); /// public abstract bool ProcessKey (Key a); diff --git a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs index 6305386bd..88d3a8026 100644 --- a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs @@ -45,7 +45,7 @@ public interface IAutocomplete /// The mouse event. /// If was called from the popup or from the host. /// trueif the mouse can be handled falseotherwise. - bool OnMouseEvent (MouseEvent me, bool fromHost = false); + bool OnMouseEvent (MouseEventArgs me, bool fromHost = false); /// Gets or sets where the popup will be displayed. bool PopupInsideContainer { get; set; } diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs index e53cbc0aa..39bdd7522 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs @@ -25,6 +25,6 @@ public abstract partial class PopupAutocomplete _autoComplete.RenderOverlay (_autoComplete.LastPopupPos.Value); } - protected override bool OnMouseEvent (MouseEvent mouseEvent) { return _autoComplete.OnMouseEvent (mouseEvent); } + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { return _autoComplete.OnMouseEvent (mouseEvent); } } } diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs index c17695ee7..4f332bd54 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs @@ -105,7 +105,7 @@ public abstract partial class PopupAutocomplete : AutocompleteBase /// The mouse event. /// If was called from the popup or from the host. /// trueif the mouse can be handled falseotherwise. - public override bool OnMouseEvent (MouseEvent me, bool fromHost = false) + public override bool OnMouseEvent (MouseEventArgs me, bool fromHost = false) { if (fromHost) { @@ -488,7 +488,7 @@ public abstract partial class PopupAutocomplete : AutocompleteBase /// Render the current selection in the Autocomplete context menu by the mouse reporting. /// - protected void RenderSelectedIdxByMouse (MouseEvent me) + protected void RenderSelectedIdxByMouse (MouseEventArgs me) { if (SelectedIdx != me.Position.Y - ScrollOffset) { diff --git a/Terminal.Gui/View/Adornment/Border.cs b/Terminal.Gui/View/Adornment/Border.cs index a9c87919a..add7527e6 100644 --- a/Terminal.Gui/View/Adornment/Border.cs +++ b/Terminal.Gui/View/Adornment/Border.cs @@ -262,7 +262,7 @@ public class Border : Adornment private Point _startGrabPoint; /// - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { // BUGBUG: See https://github.com/gui-cs/Terminal.Gui/issues/3312 if (!_dragPosition.HasValue && mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) @@ -1365,7 +1365,7 @@ public class Border : Adornment KeyBindings.Add (Key.Tab.WithShift, KeyBindingScope.HotKey, Command.BackTab); } - private void ApplicationOnMouseEvent (object? sender, MouseEvent e) + private void ApplicationOnMouseEvent (object? sender, MouseEventArgs e) { if (e.Flags != MouseFlags.Button1Clicked) { diff --git a/Terminal.Gui/View/Adornment/Padding.cs b/Terminal.Gui/View/Adornment/Padding.cs index 5eb1eda72..7dbc1cd70 100644 --- a/Terminal.Gui/View/Adornment/Padding.cs +++ b/Terminal.Gui/View/Adornment/Padding.cs @@ -50,7 +50,7 @@ public class Padding : Adornment /// /// /// , if the event was handled, otherwise. - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (Parent is null) { diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index e6d81687c..8ff82b164 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -220,12 +220,12 @@ public partial class View // Mouse APIs /// /// /// If is , the / event - /// will be raised on any new mouse event where indicates a button is pressed. + /// will be raised on any new mouse event where indicates a button is pressed. /// /// /// /// if the event was handled, otherwise. - public bool? NewMouseEvent (MouseEvent mouseEvent) + public bool? NewMouseEvent (MouseEventArgs mouseEvent) { // Pre-conditions if (!Enabled) @@ -286,7 +286,7 @@ public partial class View // Mouse APIs // If it's a click, and we didn't handle it, then we need to generate a click event // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent and // it did not handle the press/release/clicked events via HandlePress/HandleRelease/HandleClicked - return OnMouseClick (new (mouseEvent)); + return OnMouseClick (mouseEvent); } return false; @@ -297,18 +297,16 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - public bool RaiseMouseEvent (MouseEvent mouseEvent) + public bool RaiseMouseEvent (MouseEventArgs mouseEvent) { - var args = new MouseEventArgs (mouseEvent); - if (OnMouseEvent (mouseEvent) || mouseEvent.Handled == true) { return true; } - MouseEvent?.Invoke (this, args); + MouseEvent?.Invoke (this, mouseEvent); - return args.Handled; + return mouseEvent.Handled; } /// Called when a mouse event occurs within the view's . @@ -319,7 +317,7 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - protected virtual bool OnMouseEvent (MouseEvent mouseEvent) + protected virtual bool OnMouseEvent (MouseEventArgs mouseEvent) { return false; } @@ -341,7 +339,7 @@ public partial class View // Mouse APIs /// /// /// Fired when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. + /// to see which button was clicked. /// /// /// The coordinates are relative to . @@ -353,7 +351,7 @@ public partial class View // Mouse APIs /// /// /// Called when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. + /// to see which button was clicked. /// /// /// , if the event was handled, otherwise. @@ -383,7 +381,7 @@ public partial class View // Mouse APIs // Always invoke Select command on MouseClick // By default, this will raise Selecting/OnSelecting - Subclasses can override this via AddCommand (Command.Select ...). - args.Handled = InvokeCommand (Command.Select, ctx: new (Command.Select, key: null, data: args.MouseEvent)) == true; + args.Handled = InvokeCommand (Command.Select, ctx: new (Command.Select, key: null, data: args)) == true; return args.Handled; } @@ -397,7 +395,7 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - internal bool WhenGrabbedHandleClicked (MouseEvent mouseEvent) + internal bool WhenGrabbedHandleClicked (MouseEventArgs mouseEvent) { if (Application.MouseGrabView == this && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) @@ -416,7 +414,7 @@ public partial class View // Mouse APIs // If mouse is still in bounds, generate a click if (!WantMousePositionReports && Viewport.Contains (mouseEvent.Position)) { - return OnMouseClick (new (mouseEvent)); + return OnMouseClick (mouseEvent); } return mouseEvent.Handled = true; @@ -434,7 +432,7 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - internal bool WhenGrabbedHandleReleased (MouseEvent mouseEvent) + internal bool WhenGrabbedHandleReleased (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) || mouseEvent.Flags.HasFlag (MouseFlags.Button2Released) @@ -463,7 +461,7 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - private bool WhenGrabbedHandlePressed (MouseEvent mouseEvent) + private bool WhenGrabbedHandlePressed (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed) @@ -505,7 +503,7 @@ public partial class View // Mouse APIs if (WantContinuousButtonPressed && Application.MouseGrabView == this) { // If this is not the first pressed event, generate a click - return OnMouseClick (new (mouseEvent)); + return OnMouseClick (mouseEvent); } return mouseEvent.Handled = true; diff --git a/Terminal.Gui/Views/Bar.cs b/Terminal.Gui/Views/Bar.cs index 8e570eaf9..1511cd68a 100644 --- a/Terminal.Gui/Views/Bar.cs +++ b/Terminal.Gui/Views/Bar.cs @@ -49,23 +49,23 @@ public class Bar : View, IOrientation, IDesignable { NavigationDirection direction = NavigationDirection.Backward; - if (e.MouseEvent.Flags == MouseFlags.WheeledDown) + if (e.Flags == MouseFlags.WheeledDown) { e.Handled = true; } - if (e.MouseEvent.Flags == MouseFlags.WheeledUp) + if (e.Flags == MouseFlags.WheeledUp) { direction = NavigationDirection.Forward; e.Handled = true; } - if (e.MouseEvent.Flags == MouseFlags.WheeledRight) + if (e.Flags == MouseFlags.WheeledRight) { e.Handled = true; } - if (e.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (e.Flags == MouseFlags.WheeledLeft) { direction = NavigationDirection.Forward; e.Handled = true; diff --git a/Terminal.Gui/Views/ColorBar.cs b/Terminal.Gui/Views/ColorBar.cs index ea6197959..581606d17 100644 --- a/Terminal.Gui/Views/ColorBar.cs +++ b/Terminal.Gui/Views/ColorBar.cs @@ -110,7 +110,7 @@ internal abstract class ColorBar : View, IColorBar public event EventHandler>? ValueChanged; /// - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { diff --git a/Terminal.Gui/Views/ColorPicker.16.cs b/Terminal.Gui/Views/ColorPicker.16.cs index b3a294369..c1cb72cc2 100644 --- a/Terminal.Gui/Views/ColorPicker.16.cs +++ b/Terminal.Gui/Views/ColorPicker.16.cs @@ -185,7 +185,7 @@ public class ColorPicker16 : View { // if (CanFocus) { - Cursor = new (me.MouseEvent.Position.X / _boxWidth, me.MouseEvent.Position.Y / _boxHeight); + Cursor = new (me.Position.X / _boxWidth, me.Position.Y / _boxHeight); SetFocus (); me.Handled = true; } diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index e7702519d..996056068 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -253,7 +253,7 @@ public class ComboBox : View, IDesignable public event EventHandler Expanded; /// - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (me.Position.X == Viewport.Right - 1 && me.Position.Y == Viewport.Top @@ -836,7 +836,7 @@ public class ComboBox : View, IDesignable set => _hideDropdownListOnClick = WantContinuousButtonPressed = value; } - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { bool isMousePositionValid = IsMousePositionValid (me); @@ -985,7 +985,7 @@ public class ComboBox : View, IDesignable return res; } - private bool IsMousePositionValid (MouseEvent me) + private bool IsMousePositionValid (MouseEventArgs me) { if (me.Position.X >= 0 && me.Position.X < Frame.Width && me.Position.Y >= 0 && me.Position.Y < Frame.Height) { diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 0abc62984..0c8b253c2 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -114,7 +114,7 @@ public class DateField : TextField } /// - protected override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 95d7330a8..874e76dec 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -1009,16 +1009,16 @@ public class FileDialog : Dialog private void OnTableViewMouseClick (object sender, MouseEventArgs e) { - Point? clickedCell = _tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? clickedCol); + Point? clickedCell = _tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? clickedCol); if (clickedCol is { }) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button1Clicked)) { // left click in a header SortColumn (clickedCol.Value); } - else if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + else if (e.Flags.HasFlag (MouseFlags.Button3Clicked)) { // right click in a header ShowHeaderContextMenu (clickedCol.Value, e); @@ -1026,7 +1026,7 @@ public class FileDialog : Dialog } else { - if (clickedCell is { } && e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + if (clickedCell is { } && e.Flags.HasFlag (MouseFlags.Button3Clicked)) { // right click in rest of table ShowCellContextMenu (clickedCell, e); @@ -1207,7 +1207,7 @@ public class FileDialog : Dialog var contextMenu = new ContextMenu { - Position = new Point (e.MouseEvent.Position.X + 1, e.MouseEvent.Position.Y + 1) + Position = new Point (e.Position.X + 1, e.Position.Y + 1) }; var menuItems = new MenuBarItem ( @@ -1228,7 +1228,7 @@ public class FileDialog : Dialog var contextMenu = new ContextMenu { - Position = new Point (e.MouseEvent.Position.X + 1, e.MouseEvent.Position.Y + 1) + Position = new Point (e.Position.X + 1, e.Position.Y + 1) }; var menuItems = new MenuBarItem ( diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index a6e838233..e1cca01ed 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -250,7 +250,7 @@ public class HexView : View, IDesignable public event EventHandler Edited; /// - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index e1f3a4f19..564b1cfed 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -472,7 +472,7 @@ public class ListView : View, IDesignable } /// - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index 9f672ec23..a8c50755b 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -337,7 +337,7 @@ internal sealed class Menu : View } } - private void Application_RootMouseEvent (object? sender, MouseEvent a) + private void Application_RootMouseEvent (object? sender, MouseEventArgs a) { if (a.View is { } and (MenuBar or not Menu)) { @@ -353,7 +353,7 @@ internal sealed class Menu : View Point boundsPoint = view.ScreenToViewport (new (a.Position.X, a.Position.Y)); - var me = new MouseEvent + var me = new MouseEventArgs { Position = boundsPoint, Flags = a.Flags, @@ -808,7 +808,7 @@ internal sealed class Menu : View _host.SetNeedsDisplay (); } - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!_host._handled && !_host.HandleGrabView (me, this)) { diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs index 8dbcfe29b..a15d1e463 100644 --- a/Terminal.Gui/Views/Menu/MenuBar.cs +++ b/Terminal.Gui/Views/Menu/MenuBar.cs @@ -137,7 +137,7 @@ public class MenuBar : View, IDesignable }); AddCommand (Command.Select, ctx => { - if (ctx.Data is MouseEvent) + if (ctx.Data is MouseEventArgs) { // HACK: Work around the fact that View.MouseClick always invokes Select return false; @@ -1400,7 +1400,7 @@ public class MenuBar : View, IDesignable } /// - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!_handled && !HandleGrabView (me, this)) { @@ -1513,7 +1513,7 @@ public class MenuBar : View, IDesignable internal bool _isContextMenuLoading; private MenuBarItem [] _menus = []; - internal bool HandleGrabView (MouseEvent me, View current) + internal bool HandleGrabView (MouseEventArgs me, View current) { if (Application.MouseGrabView is { }) { @@ -1541,7 +1541,7 @@ public class MenuBar : View, IDesignable Application.UngrabMouse (); View v = me.View; Application.GrabMouse (v); - MouseEvent nme; + MouseEventArgs nme; if (me.Position.Y > -1) { diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index c45ae6e47..f929d0ce5 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -222,10 +222,10 @@ public class RadioGroup : View, IDesignable, IOrientation private void RadioGroup_MouseClick (object? sender, MouseEventArgs e) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button1Clicked)) { - int viewportX = e.MouseEvent.Position.X; - int viewportY = e.MouseEvent.Position.Y; + int viewportX = e.Position.X; + int viewportY = e.Position.Y; int pos = Orientation == Orientation.Horizontal ? viewportX : viewportY; @@ -249,7 +249,7 @@ public class RadioGroup : View, IDesignable, IOrientation return; } - if (DoubleClickAccepts && e.MouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked)) + if (DoubleClickAccepts && e.Flags.HasFlag (MouseFlags.Button1DoubleClicked)) { // NOTE: Drivers ALWAYS generate a Button1Clicked event before Button1DoubleClicked // NOTE: So, we've already selected an item. diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs index 5eb955fb2..f6e8da296 100644 --- a/Terminal.Gui/Views/ScrollBarView.cs +++ b/Terminal.Gui/Views/ScrollBarView.cs @@ -270,7 +270,7 @@ public class ScrollBarView : View public event EventHandler ChangedPosition; /// - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags != MouseFlags.Button1Pressed && mouseEvent.Flags != MouseFlags.Button1DoubleClicked @@ -779,14 +779,14 @@ public class ScrollBarView : View private void ContentBottomRightCorner_MouseClick (object sender, MouseEventArgs me) { - if (me.MouseEvent.Flags == MouseFlags.WheeledDown - || me.MouseEvent.Flags == MouseFlags.WheeledUp - || me.MouseEvent.Flags == MouseFlags.WheeledRight - || me.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (me.Flags == MouseFlags.WheeledDown + || me.Flags == MouseFlags.WheeledUp + || me.Flags == MouseFlags.WheeledRight + || me.Flags == MouseFlags.WheeledLeft) { - NewMouseEvent (me.MouseEvent); + NewMouseEvent (me); } - else if (me.MouseEvent.Flags == MouseFlags.Button1Clicked) + else if (me.Flags == MouseFlags.Button1Clicked) { Host.SetFocus (); } diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index e419904b6..35d4409e5 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -406,7 +406,7 @@ public class ScrollView : View } /// - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!Enabled) { diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index d68cffa17..af2ff1366 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -1282,7 +1282,7 @@ public class Slider : View, IOrientation private Point? _moveRenderPosition; /// - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { // Note(jmperricone): Maybe we click to focus the cursor, and on next click we set the option. // That will make OptionFocused Event more relevant. @@ -1382,7 +1382,7 @@ public class Slider : View, IOrientation mouseEvent.Handled = true; // BUGBUG: OnMouseClick is/should be internal. - return OnMouseClick (new (mouseEvent)); + return OnMouseClick (mouseEvent); } return false; diff --git a/Terminal.Gui/Views/TabMouseEventArgs.cs b/Terminal.Gui/Views/TabMouseEventArgs.cs index 6b91a3531..707f68211 100644 --- a/Terminal.Gui/Views/TabMouseEventArgs.cs +++ b/Terminal.Gui/Views/TabMouseEventArgs.cs @@ -6,17 +6,17 @@ public class TabMouseEventArgs : EventArgs /// Creates a new instance of the class. /// that the mouse was over when the event occurred. /// The mouse activity being reported - public TabMouseEventArgs (Tab tab, MouseEvent mouseEvent) + public TabMouseEventArgs (Tab tab, MouseEventArgs mouseEvent) { Tab = tab; MouseEvent = mouseEvent; } /// - /// Gets the actual mouse event. Use to cancel this event and perform custom + /// Gets the actual mouse event. Use to cancel this event and perform custom /// behavior (e.g. show a context menu). /// - public MouseEvent MouseEvent { get; } + public MouseEventArgs MouseEvent { get; } /// Gets the (if any) that the mouse was over when the occurred. /// This will be null if the click is after last tab or before first. diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 8de57757a..62f403364 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -510,7 +510,7 @@ public class TabView : View private void Tab_MouseClick (object sender, MouseEventArgs e) { - e.Handled = _tabsBar.NewMouseEvent (e.MouseEvent) == true; + e.Handled = _tabsBar.NewMouseEvent (e) == true; } private void UnSetCurrentTabs () @@ -569,7 +569,7 @@ public class TabView : View Add (_rightScrollIndicator, _leftScrollIndicator); } - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { Tab hit = me.View is Tab ? (Tab)me.View : null; diff --git a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs index d0f7fed26..abbb2c704 100644 --- a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs +++ b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs @@ -153,12 +153,12 @@ public abstract class CheckBoxTableSourceWrapperBase : ITableSource private void TableView_MouseClick (object sender, MouseEventArgs e) { // we only care about clicks (not movements) - if (!e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (!e.Flags.HasFlag (MouseFlags.Button1Clicked)) { return; } - Point? hit = tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? headerIfAny); + Point? hit = tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? headerIfAny); if (headerIfAny.HasValue && headerIfAny.Value == 0) { diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index b2fc063dd..ee39726c9 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -801,7 +801,7 @@ public class TableView : View } /// - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) @@ -1646,7 +1646,7 @@ public class TableView : View return colStyle is { } ? colStyle.GetRepresentation (value) : value.ToString (); } - private bool HasControlOrAlt (MouseEvent me) { return me.Flags.HasFlag (MouseFlags.ButtonAlt) || me.Flags.HasFlag (MouseFlags.ButtonCtrl); } + private bool HasControlOrAlt (MouseEventArgs me) { return me.Flags.HasFlag (MouseFlags.ButtonAlt) || me.Flags.HasFlag (MouseFlags.ButtonCtrl); } /// /// Returns true if the given indexes a visible column otherwise false. Returns diff --git a/Terminal.Gui/Views/TableView/TreeTableSource.cs b/Terminal.Gui/Views/TableView/TreeTableSource.cs index 88ab0cb3a..c3458b32d 100644 --- a/Terminal.Gui/Views/TableView/TreeTableSource.cs +++ b/Terminal.Gui/Views/TableView/TreeTableSource.cs @@ -168,7 +168,7 @@ public class TreeTableSource : IEnumerableTableSource, IDisposable where T private void Table_MouseClick (object sender, MouseEventArgs e) { - Point? hit = _tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? headerIfAny, out int? offsetX); + Point? hit = _tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? headerIfAny, out int? offsetX); if (hit is null || headerIfAny is { } || !IsInTreeColumn (hit.Value.X, false) || offsetX is null) { diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index e49470f0a..b9f601493 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -798,7 +798,7 @@ public class TextField : View } /// - protected override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { if (!ev.Flags.HasFlag (MouseFlags.Button1Pressed) && !ev.Flags.HasFlag (MouseFlags.ReportMousePosition) @@ -1645,7 +1645,7 @@ public class TextField : View return 0; //offB; } - private int PositionCursor (MouseEvent ev) { return PositionCursor (TextModel.GetColFromX (_text, ScrollOffset, ev.Position.X), false); } + private int PositionCursor (MouseEventArgs ev) { return PositionCursor (TextModel.GetColFromX (_text, ScrollOffset, ev.Position.X), false); } private int PositionCursor (int x, bool getX = true) { diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index d526513f6..289855c30 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -531,7 +531,7 @@ namespace Terminal.Gui } /// - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 8290caaf0..7400fe2c4 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3274,7 +3274,7 @@ public class TextView : View } /// - protected override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked) && !ev.Flags.HasFlag (MouseFlags.Button1Pressed) @@ -5875,7 +5875,7 @@ public class TextView : View KillWordForward (); } - private void ProcessMouseClick (MouseEvent ev, out List line) + private void ProcessMouseClick (MouseEventArgs ev, out List line) { List? r = null; diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index 8702243f9..6ad42ce98 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -910,7 +910,7 @@ public class TileView : View } } - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (!dragPosition.HasValue && mouseEvent.Flags == MouseFlags.Button1Pressed) { diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index d32ea9d22..e520e479c 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -163,7 +163,7 @@ public class TimeField : TextField } /// - protected override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index b59b5ed6b..9b1bfce44 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -990,7 +990,7 @@ public class TreeView : View, ITreeView where T : class // BUGBUG: OnMouseEvent is internal. TreeView should not be overriding. /// - protected override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { // If it is not an event we care about if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs index c1a906a4d..45889f3e8 100644 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ b/UICatalog/Scenarios/ASCIICustomButton.cs @@ -127,7 +127,7 @@ public class ASCIICustomButtonTest : Scenario } public event Action PointerEnter; - private void This_MouseClick (object sender, MouseEventArgs obj) { NewMouseEvent (obj.MouseEvent); } + private void This_MouseClick (object sender, MouseEventArgs obj) { NewMouseEvent (obj); } } public class ScrollViewTestWindow : Window @@ -312,7 +312,7 @@ public class ASCIICustomButtonTest : Scenario private void Button_MouseClick (object sender, MouseEventArgs obj) { - if (obj.MouseEvent.Flags == MouseFlags.WheeledDown) + if (obj.Flags == MouseFlags.WheeledDown) { _scrollView.ContentOffset = new Point ( _scrollView.ContentOffset.X, @@ -320,7 +320,7 @@ public class ASCIICustomButtonTest : Scenario ); obj.Handled = true; } - else if (obj.MouseEvent.Flags == MouseFlags.WheeledUp) + else if (obj.Flags == MouseFlags.WheeledUp) { _scrollView.ContentOffset = new Point ( _scrollView.ContentOffset.X, diff --git a/UICatalog/Scenarios/AdornmentsEditor.cs b/UICatalog/Scenarios/AdornmentsEditor.cs index 7bd6ec042..d50714c5f 100644 --- a/UICatalog/Scenarios/AdornmentsEditor.cs +++ b/UICatalog/Scenarios/AdornmentsEditor.cs @@ -108,7 +108,7 @@ public class AdornmentsEditor : View ViewToEdit = Application.Navigation!.GetFocused (); } - private void ApplicationOnMouseEvent (object? sender, MouseEvent e) + private void ApplicationOnMouseEvent (object? sender, MouseEventArgs e) { if (e.Flags != MouseFlags.Button1Clicked || !AutoSelectViewToEdit) { diff --git a/UICatalog/Scenarios/ArrangementEditor.cs b/UICatalog/Scenarios/ArrangementEditor.cs index 13a48380d..396c493d6 100644 --- a/UICatalog/Scenarios/ArrangementEditor.cs +++ b/UICatalog/Scenarios/ArrangementEditor.cs @@ -147,7 +147,7 @@ public sealed class ArrangementEditor : View } } - private void ApplicationOnMouseEvent (object? sender, MouseEvent e) + private void ApplicationOnMouseEvent (object? sender, MouseEventArgs e) { if (e.Flags != MouseFlags.Button1Clicked || !AutoSelectViewToEdit) { diff --git a/UICatalog/Scenarios/Bars.cs b/UICatalog/Scenarios/Bars.cs index 23b13cee5..b0d226148 100644 --- a/UICatalog/Scenarios/Bars.cs +++ b/UICatalog/Scenarios/Bars.cs @@ -189,10 +189,10 @@ public class Bars : Scenario void MenuLikeExamplesMouseClick (object sender, MouseEventArgs e) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button3Clicked)) { - popOverMenu.X = e.MouseEvent.Position.X; - popOverMenu.Y = e.MouseEvent.Position.Y; + popOverMenu.X = e.Position.X; + popOverMenu.Y = e.Position.Y; popOverMenu.Visible = true; //popOverMenu.Enabled = popOverMenu.Visible; popOverMenu.SetFocus (); @@ -275,7 +275,7 @@ public class Bars : Scenario //private void ShowContextMenu (object s, MouseEventEventArgs e) //{ - // if (e.MouseEvent.Flags != MouseFlags.Button3Clicked) + // if (e.Flags != MouseFlags.Button3Clicked) // { // return; // } @@ -283,8 +283,8 @@ public class Bars : Scenario // var contextMenu = new Bar // { // Id = "contextMenu", - // X = e.MouseEvent.Position.X, - // Y = e.MouseEvent.Position.Y, + // X = e.Position.X, + // Y = e.Position.Y, // Width = Dim.Auto (DimAutoStyle.Content), // Height = Dim.Auto (DimAutoStyle.Content), // Orientation = Orientation.Vertical, @@ -387,7 +387,7 @@ public class Bars : Scenario // contextMenu.Initialized += Menu_Initialized; - // void Application_MouseEvent (object sender, MouseEvent e) + // void Application_MouseEvent (object sender, MouseEventArgs e) // { // // If user clicks outside of the menuWindow, close it // if (!contextMenu.Frame.Contains (e.Position.X, e.Position.Y)) diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs index caebcb406..33c64d003 100644 --- a/UICatalog/Scenarios/CharacterMap.cs +++ b/UICatalog/Scenarios/CharacterMap.cs @@ -98,9 +98,9 @@ public class CharacterMap : Scenario // if user clicks the mouse in TableView _categoryList.MouseClick += (s, e) => { - _categoryList.ScreenToCell (e.MouseEvent.Position, out int? clickedCol); + _categoryList.ScreenToCell (e.Position, out int? clickedCol); - if (clickedCol != null && e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (clickedCol != null && e.Flags.HasFlag (MouseFlags.Button1Clicked)) { EnumerableTableSource table = (EnumerableTableSource)_categoryList.Table; string prevSelection = table.Data.ElementAt (_categoryList.SelectedRow).Category; @@ -529,7 +529,7 @@ internal class CharMap : View private void Handle_MouseEvent (object sender, MouseEventArgs e) { - if (e.MouseEvent.Flags == MouseFlags.WheeledDown) + if (e.Flags == MouseFlags.WheeledDown) { ScrollVertical (1); e.Handled = true; @@ -537,7 +537,7 @@ internal class CharMap : View return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledUp) + if (e.Flags == MouseFlags.WheeledUp) { ScrollVertical (-1); e.Handled = true; @@ -545,7 +545,7 @@ internal class CharMap : View return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledRight) + if (e.Flags == MouseFlags.WheeledRight) { ScrollHorizontal (1); e.Handled = true; @@ -553,7 +553,7 @@ internal class CharMap : View return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (e.Flags == MouseFlags.WheeledLeft) { ScrollHorizontal (-1); e.Handled = true; @@ -839,10 +839,8 @@ internal class CharMap : View private void CopyCodePoint () { Clipboard.Contents = $"U+{SelectedCodePoint:x5}"; } private void CopyGlyph () { Clipboard.Contents = $"{new Rune (SelectedCodePoint)}"; } - private void Handle_MouseClick (object sender, MouseEventArgs args) + private void Handle_MouseClick (object sender, MouseEventArgs me) { - MouseEvent me = args.MouseEvent; - if (me.Flags != MouseFlags.ReportMousePosition && me.Flags != MouseFlags.Button1Clicked && me.Flags != MouseFlags.Button1DoubleClicked) { return; @@ -883,7 +881,7 @@ internal class CharMap : View SetFocus (); } - args.Handled = true; + me.Handled = true; if (me.Flags == MouseFlags.Button1Clicked) { diff --git a/UICatalog/Scenarios/ContentScrolling.cs b/UICatalog/Scenarios/ContentScrolling.cs index 8c97d3e2a..b6986067e 100644 --- a/UICatalog/Scenarios/ContentScrolling.cs +++ b/UICatalog/Scenarios/ContentScrolling.cs @@ -54,28 +54,28 @@ public class ContentScrolling : Scenario private void VirtualDemoView_MouseEvent (object sender, MouseEventArgs e) { - if (e.MouseEvent.Flags == MouseFlags.WheeledDown) + if (e.Flags == MouseFlags.WheeledDown) { ScrollVertical (1); return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledUp) + if (e.Flags == MouseFlags.WheeledUp) { ScrollVertical (-1); return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledRight) + if (e.Flags == MouseFlags.WheeledRight) { ScrollHorizontal (1); return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (e.Flags == MouseFlags.WheeledLeft) { ScrollHorizontal (-1); } diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index 816f80384..63a207d69 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -75,16 +75,16 @@ public class ContextMenus : Scenario appWindow.MouseClick += (s, e) => { - if (e.MouseEvent.Flags == _contextMenu.MouseFlags) + if (e.Flags == _contextMenu.MouseFlags) { - ShowContextMenu (e.MouseEvent.Position.X, e.MouseEvent.Position.Y); + ShowContextMenu (e.Position.X, e.Position.Y); e.Handled = true; } }; Application.MouseEvent += ApplicationMouseEvent; - void ApplicationMouseEvent (object sender, MouseEvent a) { mousePos = a.Position; } + void ApplicationMouseEvent (object sender, MouseEventArgs a) { mousePos = a.Position; } appWindow.WantMousePositionReports = true; diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index b173dd7bc..38ea3bbfb 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -8,7 +8,7 @@ namespace UICatalog.Scenarios; public interface ITool { - void OnMouseEvent (DrawingArea area, MouseEvent mouseEvent); + void OnMouseEvent (DrawingArea area, MouseEventArgs mouseEvent); } internal class DrawLineTool : ITool @@ -17,7 +17,7 @@ internal class DrawLineTool : ITool public LineStyle LineStyle { get; set; } = LineStyle.Single; /// - public void OnMouseEvent (DrawingArea area, MouseEvent mouseEvent) + public void OnMouseEvent (DrawingArea area, MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { @@ -323,7 +323,7 @@ public class DrawingArea : View return false; } - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { CurrentTool.OnMouseEvent (this, mouseEvent); @@ -431,7 +431,7 @@ public class AttributeView : View } /// - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) { diff --git a/UICatalog/Scenarios/ListColumns.cs b/UICatalog/Scenarios/ListColumns.cs index 6bd6dd4be..05859bfbc 100644 --- a/UICatalog/Scenarios/ListColumns.cs +++ b/UICatalog/Scenarios/ListColumns.cs @@ -248,7 +248,7 @@ public class ListColumns : Scenario }; // if user clicks the mouse in TableView - _listColView.MouseClick += (s, e) => { _listColView.ScreenToCell (e.MouseEvent.Position, out int? clickedCol); }; + _listColView.MouseClick += (s, e) => { _listColView.ScreenToCell (e.Position, out int? clickedCol); }; _listColView.KeyBindings.ReplaceCommands (Key.Space, Command.Accept); diff --git a/UICatalog/Scenarios/Mouse.cs b/UICatalog/Scenarios/Mouse.cs index 0b07c48e3..dd1a08789 100644 --- a/UICatalog/Scenarios/Mouse.cs +++ b/UICatalog/Scenarios/Mouse.cs @@ -251,18 +251,18 @@ public class Mouse : Scenario win.MouseEvent += (sender, a) => { - int i = filterSlider.Options.FindIndex (o => o.Data == a.MouseEvent.Flags); + int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags); if (filterSlider.GetSetOptions ().Contains (i)) { - winLogList.Add ($"MouseEvent: ({a.MouseEvent.Position}) - {a.MouseEvent.Flags} {count++}"); + winLogList.Add ($"MouseEvent: ({a.Position}) - {a.Flags} {count++}"); winLog.MoveDown (); } }; win.MouseClick += (sender, a) => { - winLogList.Add ($"MouseClick: ({a.MouseEvent.Position}) - {a.MouseEvent.Flags} {count++}"); + winLogList.Add ($"MouseClick: ({a.Position}) - {a.Flags} {count++}"); winLog.MoveDown (); }; diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index eaeab748e..c676eac23 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -752,16 +752,16 @@ public class TableEditor : Scenario return; } - _tableView.ScreenToCell (e.MouseEvent.Position, out int? clickedCol); + _tableView.ScreenToCell (e.Position, out int? clickedCol); if (clickedCol != null) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button1Clicked)) { // left click in a header SortColumn (clickedCol.Value); } - else if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + else if (e.Flags.HasFlag (MouseFlags.Button3Clicked)) { // right click in a header ShowHeaderContextMenu (clickedCol.Value, e); @@ -1266,7 +1266,7 @@ public class TableEditor : Scenario var contextMenu = new ContextMenu { - Position = new (e.MouseEvent.Position.X + 1, e.MouseEvent.Position.Y + 1) + Position = new (e.Position.X + 1, e.Position.Y + 1) }; MenuBarItem menuItems = new ( diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index ae288a5df..6c46a7996 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -487,9 +487,9 @@ public class TreeViewFileSystem : Scenario private void TreeViewFiles_MouseClick (object sender, MouseEventArgs obj) { // if user right clicks - if (obj.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + if (obj.Flags.HasFlag (MouseFlags.Button3Clicked)) { - IFileSystemInfo rightClicked = _treeViewFiles.GetObjectOnRow (obj.MouseEvent.Position.Y); + IFileSystemInfo rightClicked = _treeViewFiles.GetObjectOnRow (obj.Position.Y); // nothing was clicked if (rightClicked == null) @@ -499,8 +499,8 @@ public class TreeViewFileSystem : Scenario ShowContextMenu ( new Point ( - obj.MouseEvent.Position.X + _treeViewFiles.Frame.X, - obj.MouseEvent.Position.Y + _treeViewFiles.Frame.Y + 2 + obj.Position.X + _treeViewFiles.Frame.X, + obj.Position.Y + _treeViewFiles.Frame.Y + 2 ), rightClicked ); diff --git a/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs b/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs index f1d0a7847..60eb8b25e 100644 --- a/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs +++ b/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs @@ -47,7 +47,7 @@ public class ApplicationMouseEnterLeaveTests var mousePosition = new Point (1, 1); List currentViewsUnderMouse = new () { view }; - var mouseEvent = new MouseEvent + var mouseEvent = new MouseEventArgs { Position = mousePosition, ScreenPosition = mousePosition @@ -80,7 +80,7 @@ public class ApplicationMouseEnterLeaveTests Application.Top.Add (view); var mousePosition = new Point (0, 0); List currentViewsUnderMouse = new (); - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); Application._cachedViewsUnderMouse.Clear (); Application._cachedViewsUnderMouse.Add (view); @@ -203,7 +203,7 @@ public class ApplicationMouseEnterLeaveTests Application.Top.Add (view); var mousePosition = new Point (0, 0); List currentViewsUnderMouse = new (); - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); Application._cachedViewsUnderMouse.Clear (); diff --git a/UnitTests/Application/Mouse/ApplicationMouseTests.cs b/UnitTests/Application/Mouse/ApplicationMouseTests.cs index 963807695..64000649d 100644 --- a/UnitTests/Application/Mouse/ApplicationMouseTests.cs +++ b/UnitTests/Application/Mouse/ApplicationMouseTests.cs @@ -42,10 +42,10 @@ public class ApplicationMouseTests bool expectedClicked ) { - var mouseEvent = new MouseEvent { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Pressed }; + var mouseEvent = new MouseEventArgs { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Pressed }; var clicked = false; - void OnApplicationOnMouseEvent (object s, MouseEvent e) + void OnApplicationOnMouseEvent (object s, MouseEventArgs e) { Assert.Equal (expectedX, e.ScreenPosition.X); Assert.Equal (expectedY, e.ScreenPosition.Y); @@ -116,12 +116,12 @@ public class ApplicationMouseTests Height = size.Height }; - var mouseEvent = new MouseEvent { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; + var mouseEvent = new MouseEventArgs { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; view.MouseClick += (s, e) => { - Assert.Equal (expectedX, e.MouseEvent.Position.X); - Assert.Equal (expectedY, e.MouseEvent.Position.Y); + Assert.Equal (expectedX, e.Position.X); + Assert.Equal (expectedY, e.Position.Y); clicked = true; }; @@ -218,12 +218,12 @@ public class ApplicationMouseTests Application.Top.Add (view); - var mouseEvent = new MouseEvent { Position = new (clickX, clickY), ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; + var mouseEvent = new MouseEventArgs { Position = new (clickX, clickY), ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; view.MouseClick += (s, e) => { - Assert.Equal (expectedX, e.MouseEvent.Position.X); - Assert.Equal (expectedY, e.MouseEvent.Position.Y); + Assert.Equal (expectedX, e.Position.X); + Assert.Equal (expectedY, e.Position.Y); clicked = true; }; diff --git a/UnitTests/Input/ResponderTests.cs b/UnitTests/Input/ResponderTests.cs index cac5c549e..183e06885 100644 --- a/UnitTests/Input/ResponderTests.cs +++ b/UnitTests/Input/ResponderTests.cs @@ -234,7 +234,7 @@ public class ResponderTests //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null })); Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null })); - Assert.False (r.NewMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents })); + Assert.False (r.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.AllEvents })); var v = new View (); //Assert.False (r.OnEnter (v)); diff --git a/UnitTests/View/Mouse/MouseEnterLeaveTests.cs b/UnitTests/View/Mouse/MouseEnterLeaveTests.cs index 28c002eba..e91154c5d 100644 --- a/UnitTests/View/Mouse/MouseEnterLeaveTests.cs +++ b/UnitTests/View/Mouse/MouseEnterLeaveTests.cs @@ -63,7 +63,7 @@ public class MouseEnterLeaveTests Visible = true }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); var eventArgs = new CancelEventArgs (); @@ -136,7 +136,7 @@ public class MouseEnterLeaveTests Enabled = true, Visible = true }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); @@ -159,7 +159,7 @@ public class MouseEnterLeaveTests Visible = false }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); @@ -256,7 +256,7 @@ public class MouseEnterLeaveTests Visible = true }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); @@ -279,7 +279,7 @@ public class MouseEnterLeaveTests Visible = false }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); diff --git a/UnitTests/View/Mouse/MouseTests.cs b/UnitTests/View/Mouse/MouseTests.cs index 87f3e71b5..770536e8b 100644 --- a/UnitTests/View/Mouse/MouseTests.cs +++ b/UnitTests/View/Mouse/MouseTests.cs @@ -121,9 +121,9 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews { MouseFlags mouseFlagsFromEvent = MouseFlags.None; var view = new View (); - view.MouseEvent += (s, e) => mouseFlagsFromEvent = e.MouseEvent.Flags; + view.MouseEvent += (s, e) => mouseFlagsFromEvent = e.Flags; - view.NewMouseEvent (new MouseEvent () { Flags = mouseFlags }); + view.NewMouseEvent (new MouseEventArgs () { Flags = mouseFlags }); Assert.Equal (mouseFlagsFromEvent, expectedMouseFlagsFromEvent); } @@ -142,7 +142,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews e.Handled = true; }; - MouseEvent me = new (); + MouseEventArgs me = new (); view.NewMouseEvent (me); Assert.True (mouseEventInvoked); Assert.True (me.Handled); @@ -163,7 +163,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews } view.Enabled = false; - var me = new MouseEvent (); + var me = new MouseEventArgs (); view.NewMouseEvent (me); Assert.False (me.Handled); view.Dispose (); @@ -182,7 +182,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews } view.Enabled = false; - var me = new MouseEvent () + var me = new MouseEventArgs () { Flags = MouseFlags.Button1Clicked }; @@ -198,7 +198,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_False_Button_Press_Release_DoesNotClick (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -241,7 +241,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_Button_Clicked_Raises_MouseClick (MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -269,7 +269,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_Button_Clicked_Raises_Selecting (MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -296,7 +296,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released)] public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Button_Press_Release_Clicks (MouseFlags pressed, MouseFlags released) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -328,7 +328,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Button_Press_Release_Clicks_Repeatedly (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -368,7 +368,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [Fact] public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Move_InViewport_OutOfViewport_Keeps_Counting () { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { diff --git a/UnitTests/Views/ButtonTests.cs b/UnitTests/Views/ButtonTests.cs index e4b4f7efd..1029acfd6 100644 --- a/UnitTests/Views/ButtonTests.cs +++ b/UnitTests/Views/ButtonTests.cs @@ -599,7 +599,7 @@ public class ButtonTests (ITestOutputHelper output) [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_ButtonClick_Accepts (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var button = new Button () { @@ -618,19 +618,19 @@ public class ButtonTests (ITestOutputHelper output) e.Cancel = true; }; - me = new MouseEvent (); + me = new MouseEventArgs (); me.Flags = pressed; button.NewMouseEvent (me); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - me = new MouseEvent (); + me = new MouseEventArgs (); me.Flags = released; button.NewMouseEvent (me); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - me = new MouseEvent (); + me = new MouseEventArgs (); me.Flags = clicked; button.NewMouseEvent (me); Assert.Equal (1, selectingCount); @@ -646,7 +646,7 @@ public class ButtonTests (ITestOutputHelper output) [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released)] public void WantContinuousButtonPressed_True_ButtonPressRelease_Does_Not_Raise_Selected_Or_Accepted (MouseFlags pressed, MouseFlags released) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var button = new Button () { diff --git a/UnitTests/Views/ComboBoxTests.cs b/UnitTests/Views/ComboBoxTests.cs index 99a0576a0..afc435ca4 100644 --- a/UnitTests/Views/ComboBoxTests.cs +++ b/UnitTests/Views/ComboBoxTests.cs @@ -137,7 +137,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (cb.NewMouseEvent (new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed })); + Assert.True (cb.NewMouseEvent (new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed })); Assert.Equal ("", selected); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); @@ -193,7 +193,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -231,7 +231,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -289,7 +289,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -300,7 +300,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -311,7 +311,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -324,7 +324,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("Three", selected); @@ -334,14 +334,14 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("Three", selected); @@ -351,7 +351,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("Three", selected); @@ -362,7 +362,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("One", selected); @@ -391,14 +391,14 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -409,7 +409,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (-1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (-1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -422,7 +422,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -433,7 +433,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, -1), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, -1), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -446,7 +446,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -457,7 +457,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Frame.Width, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Frame.Width, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -470,7 +470,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -481,7 +481,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, cb.Frame.Height), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, cb.Frame.Height), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -515,7 +515,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -673,7 +673,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -685,7 +685,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -695,7 +695,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -707,7 +707,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -736,7 +736,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -794,7 +794,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index 098ee3aac..1bd08ed72 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -115,11 +115,11 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (ContextMenu.IsShow); Assert.Equal (cm.MenuBar, Application.MouseGrabView); Assert.False (menu.IsMenuOpen); - Assert.False (menu.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menu })); + Assert.False (menu.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menu })); Assert.True (ContextMenu.IsShow); Assert.Equal (cm.MenuBar, Application.MouseGrabView); Assert.False (menu.IsMenuOpen); - Assert.True (menu.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1Clicked, View = menu })); + Assert.True (menu.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1Clicked, View = menu })); Assert.False (ContextMenu.IsShow); Assert.Equal (menu, Application.MouseGrabView); Assert.True (menu.IsMenuOpen); @@ -148,7 +148,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (8, 2), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (8, 2), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -231,7 +231,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rsDialog, ref firstIteration); @@ -287,7 +287,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -532,7 +532,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (0, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (0, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -580,7 +580,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -627,7 +627,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -671,7 +671,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -715,7 +715,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -747,7 +747,7 @@ public class ContextMenuTests (ITestOutputHelper output) lbl.MouseClick += (s, e) => { - if (e.MouseEvent.Flags == cm.MouseFlags) + if (e.Flags == cm.MouseFlags) { lbl.Text = "Replaced"; e.Handled = true; @@ -758,12 +758,12 @@ public class ContextMenuTests (ITestOutputHelper output) top.Add (lbl); Application.Begin (top); - Assert.True (lbl.NewMouseEvent (new MouseEvent { Flags = cm.MouseFlags })); + Assert.True (lbl.NewMouseEvent (new MouseEventArgs { Flags = cm.MouseFlags })); Assert.Equal ("Replaced", lbl.Text); lbl.Text = "Original"; cm.MouseFlags = MouseFlags.Button2Clicked; - Assert.True (lbl.NewMouseEvent (new MouseEvent { Flags = cm.MouseFlags })); + Assert.True (lbl.NewMouseEvent (new MouseEventArgs { Flags = cm.MouseFlags })); Assert.Equal ("Replaced", lbl.Text); top.Dispose (); } @@ -1235,7 +1235,7 @@ public class ContextMenuTests (ITestOutputHelper output) ); // X=5 is the border and so need to use at least one more - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 13), Flags = MouseFlags.Button1Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1253,7 +1253,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 12), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 12), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1327,7 +1327,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1344,7 +1344,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 14), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 14), Flags = MouseFlags.ReportMousePosition }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1362,7 +1362,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.RaiseMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); diff --git a/UnitTests/Views/ScrollBarViewTests.cs b/UnitTests/Views/ScrollBarViewTests.cs index 01b9e7a49..51ce8d965 100644 --- a/UnitTests/Views/ScrollBarViewTests.cs +++ b/UnitTests/Views/ScrollBarViewTests.cs @@ -1176,7 +1176,7 @@ This is a test ", _output ); - Application.RaiseMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); Assert.Null (Application.MouseGrabView); Assert.True (clicked); @@ -1200,7 +1200,7 @@ This is a test ", _output ); - Application.RaiseMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); Assert.Null (Application.MouseGrabView); Assert.True (clicked); diff --git a/UnitTests/Views/TabViewTests.cs b/UnitTests/Views/TabViewTests.cs index 9d769addc..037f106e4 100644 --- a/UnitTests/Views/TabViewTests.cs +++ b/UnitTests/Views/TabViewTests.cs @@ -138,7 +138,7 @@ public class TabViewTests (ITestOutputHelper output) top.Add (tv); Application.Begin (top); - MouseEvent args; + MouseEventArgs args; // Waving mouse around does not trigger click for (var i = 0; i < 100; i++) @@ -233,7 +233,7 @@ public class TabViewTests (ITestOutputHelper output) Application.Begin (top); // Click the right arrow - var args = new MouseEvent { ScreenPosition = new (6, 2), Flags = MouseFlags.Button1Clicked }; + var args = new MouseEventArgs { ScreenPosition = new (6, 2), Flags = MouseFlags.Button1Clicked }; Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); @@ -324,7 +324,7 @@ public class TabViewTests (ITestOutputHelper output) Application.Begin (top); // Click the right arrow - var args = new MouseEvent { ScreenPosition = new (7, 3), Flags = MouseFlags.Button1Clicked }; + var args = new MouseEventArgs { ScreenPosition = new (7, 3), Flags = MouseFlags.Button1Clicked }; Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index 40b3b8378..478e1d00b 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -1178,7 +1178,7 @@ public class TextFieldTests (ITestOutputHelper output) top.Add (tf); Application.Begin (top); - var mouseEvent = new MouseEvent { Flags = MouseFlags.Button1Clicked, View = tf }; + var mouseEvent = new MouseEventArgs { Flags = MouseFlags.Button1Clicked, View = tf }; Application.RaiseMouseEvent (mouseEvent); Assert.Equal (1, clickCounter); @@ -1205,7 +1205,7 @@ public class TextFieldTests (ITestOutputHelper output) return; - void HandleRightClick (object sender, MouseEvent arg) + void HandleRightClick (object sender, MouseEventArgs arg) { if (arg.Flags.HasFlag (MouseFlags.Button3Clicked)) { @@ -1293,7 +1293,7 @@ public class TextFieldTests (ITestOutputHelper output) { var tf = new TextField { Width = 10, Text = " " }; - var ev = new MouseEvent { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; + var ev = new MouseEventArgs { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; tf.NewMouseEvent (ev); Assert.Equal (1, tf.SelectedLength); diff --git a/UnitTests/Views/TextValidateFieldTests.cs b/UnitTests/Views/TextValidateFieldTests.cs index 96a0d6d17..35258bb42 100644 --- a/UnitTests/Views/TextValidateFieldTests.cs +++ b/UnitTests/Views/TextValidateFieldTests.cs @@ -322,7 +322,7 @@ public class TextValidateField_NET_Provider_Tests Assert.False (field.IsValid); Assert.Equal ("--(1 )--", field.Provider.Text); - field.NewMouseEvent (new MouseEvent { Position = new (25, 0), Flags = MouseFlags.Button1Pressed }); + field.NewMouseEvent (new MouseEventArgs { Position = new (25, 0), Flags = MouseFlags.Button1Pressed }); field.NewKeyDownEvent (Key.D1); diff --git a/UnitTests/Views/TextViewTests.cs b/UnitTests/Views/TextViewTests.cs index a912064f6..7dc1f9858 100644 --- a/UnitTests/Views/TextViewTests.cs +++ b/UnitTests/Views/TextViewTests.cs @@ -130,7 +130,7 @@ public class TextViewTests Assert.False (fv.CanFocus); Assert.False (fv.HasFocus); - tv.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); Assert.Empty (tv.SelectedText); Assert.False (tv.CanFocus); @@ -140,7 +140,7 @@ public class TextViewTests fv.CanFocus = true; tv.CanFocus = true; - tv.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); Assert.Equal ("some ", tv.SelectedText); Assert.True (tv.CanFocus); @@ -149,7 +149,7 @@ public class TextViewTests Assert.True (fv.HasFocus); fv.CanFocus = false; - tv.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); Assert.Equal ("some ", tv.SelectedText); // Setting CanFocus to false don't change the SelectedText Assert.True (tv.CanFocus); // v2: CanFocus is not longer automatically changed @@ -1025,7 +1025,7 @@ This is the second line. for (var i = 0; i < 12; i++) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledRight }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledRight }); Assert.Equal (Math.Min (i + 1, 11), tv.LeftColumn); Application.PositionCursor (); Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility); @@ -1034,7 +1034,7 @@ This is the second line. for (var i = 11; i > 0; i--) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledLeft }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledLeft }); Assert.Equal (i - 1, tv.LeftColumn); Application.PositionCursor (); @@ -1077,7 +1077,7 @@ This is the second line. for (var i = 0; i < 12; i++) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledDown }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledDown }); Application.PositionCursor (); Assert.Equal (i + 1, tv.TopRow); Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility); @@ -1086,7 +1086,7 @@ This is the second line. for (var i = 12; i > 0; i--) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledUp }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledUp }); Application.PositionCursor (); Assert.Equal (i - 1, tv.TopRow); @@ -6166,7 +6166,7 @@ This is the second line. Assert.True ( _textView.NewMouseEvent ( - new MouseEvent { Position = new (12, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } + new MouseEventArgs { Position = new (12, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } ) ); Assert.Equal (0, _textView.SelectionStartColumn); @@ -6175,7 +6175,7 @@ This is the second line. Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump ", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (12, 0), Flags = MouseFlags.Button1Clicked })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (12, 0), Flags = MouseFlags.Button1Clicked })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (12, 0), _textView.CursorPosition); @@ -6184,7 +6184,7 @@ This is the second line. Assert.True ( _textView.NewMouseEvent ( - new MouseEvent { Position = new (19, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } + new MouseEventArgs { Position = new (19, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } ) ); Assert.Equal (0, _textView.SelectionStartRow); @@ -6193,7 +6193,7 @@ This is the second line. Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump between", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (19, 0), Flags = MouseFlags.Button1Clicked })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (19, 0), Flags = MouseFlags.Button1Clicked })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (19, 0), _textView.CursorPosition); @@ -6202,7 +6202,7 @@ This is the second line. Assert.True ( _textView.NewMouseEvent ( - new MouseEvent { Position = new (24, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } + new MouseEventArgs { Position = new (24, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } ) ); Assert.Equal (0, _textView.SelectionStartRow); @@ -6211,14 +6211,14 @@ This is the second line. Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump between text", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (24, 0), Flags = MouseFlags.Button1Clicked })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (24, 0), Flags = MouseFlags.Button1Clicked })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (24, 0), _textView.CursorPosition); Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump between text", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (24, 0), Flags = MouseFlags.Button1Pressed })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (24, 0), Flags = MouseFlags.Button1Pressed })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (24, 0), _textView.CursorPosition); @@ -6972,12 +6972,12 @@ TAB to jump between text field", { var tv = new TextView { Width = 10, Text = " " }; - var ev = new MouseEvent { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; + var ev = new MouseEventArgs { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; tv.NewMouseEvent (ev); Assert.Equal (1, tv.SelectedLength); - ev = new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }; + ev = new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }; tv.NewMouseEvent (ev); Assert.Equal (1, tv.SelectedLength); @@ -7094,7 +7094,7 @@ line. _output ); - Assert.True (tv.NewMouseEvent (new MouseEvent { Position = new (0, 3), Flags = MouseFlags.Button1Pressed })); + Assert.True (tv.NewMouseEvent (new MouseEventArgs { Position = new (0, 3), Flags = MouseFlags.Button1Pressed })); tv.Draw (); Assert.Equal (new Point (0, 3), tv.CursorPosition); Assert.Equal (new Point (13, 0), cp); diff --git a/UnitTests/Views/TreeTableSourceTests.cs b/UnitTests/Views/TreeTableSourceTests.cs index 3db7a2742..345dffeb0 100644 --- a/UnitTests/Views/TreeTableSourceTests.cs +++ b/UnitTests/Views/TreeTableSourceTests.cs @@ -111,7 +111,7 @@ public class TreeTableSourceTests : IDisposable Assert.Equal (0, tv.SelectedRow); Assert.Equal (0, tv.SelectedColumn); - Assert.True (tv.NewMouseEvent (new MouseEvent { Position = new (2, 2), Flags = MouseFlags.Button1Clicked })); + Assert.True (tv.NewMouseEvent (new MouseEventArgs { Position = new (2, 2), Flags = MouseFlags.Button1Clicked })); tv.Draw (); @@ -128,15 +128,15 @@ public class TreeTableSourceTests : IDisposable TestHelpers.AssertDriverContentsAre (expected, _output); // Clicking to the right/left of the expand/collapse does nothing - tv.NewMouseEvent (new MouseEvent { Position = new (3, 2), Flags = MouseFlags.Button1Clicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (3, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); TestHelpers.AssertDriverContentsAre (expected, _output); - tv.NewMouseEvent (new MouseEvent { Position = new (1, 2), Flags = MouseFlags.Button1Clicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); TestHelpers.AssertDriverContentsAre (expected, _output); // Clicking on the + again should collapse - tv.NewMouseEvent (new MouseEvent { Position = new (2, 2), Flags = MouseFlags.Button1Clicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (2, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); expected = diff --git a/UnitTests/Views/TreeViewTests.cs b/UnitTests/Views/TreeViewTests.cs index 507ca3541..12d1ecf97 100644 --- a/UnitTests/Views/TreeViewTests.cs +++ b/UnitTests/Views/TreeViewTests.cs @@ -438,7 +438,7 @@ public class TreeViewTests Assert.False (called); // double click triggers activation - tree.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1DoubleClicked }); + tree.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.Button1DoubleClicked }); Assert.True (called); Assert.Same (f, activated); @@ -467,12 +467,12 @@ public class TreeViewTests Assert.False (called); // double click does nothing because we changed button binding to right click - tree.NewMouseEvent (new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button1DoubleClicked }); + tree.NewMouseEvent (new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button1DoubleClicked }); Assert.Null (activated); Assert.False (called); - tree.NewMouseEvent (new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button2Clicked }); + tree.NewMouseEvent (new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button2Clicked }); Assert.True (called); Assert.Same (car1, activated); @@ -506,7 +506,7 @@ public class TreeViewTests // double click does nothing because we changed button to null - tree.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1DoubleClicked }); + tree.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.Button1DoubleClicked }); Assert.False (called); Assert.Null (activated); diff --git a/docfx/docs/mouse.md b/docfx/docs/mouse.md index 63ef13696..18ffd2cb0 100644 --- a/docfx/docs/mouse.md +++ b/docfx/docs/mouse.md @@ -10,9 +10,9 @@ Tenets higher in the list have precedence over tenets lower in the list. ## Mouse APIs -At the core of *Terminal.Gui*'s mouse API is the *[MouseEvent](~/api/Terminal.Gui.MouseEvent.yml)* class. The `MouseEvent` class provides a platform-independent abstraction for common mouse events. Every mouse event can be fully described in a `MouseEvent` instance, and most of the mouse-related APIs are simply helper functions for decoding a `MouseEvent`. +At the core of *Terminal.Gui*'s mouse API is the @Terminal.Gui.MouseEventArgs class. The @Terminal.Gui.MouseEventArgs class provides a platform-independent abstraction for common mouse events. Every mouse event can be fully described in a @Terminal.Gui.MouseEventArgs instance, and most of the mouse-related APIs are simply helper functions for decoding a @Terminal.Gui.MouseEventArgs. -When the user does something with the mouse, the `ConsoleDriver` maps the platform-specific mouse event into a `MouseEvent` and calls `Application.OnMouseEvent`. Then, `Application.OnMouseEvent` determines which `View` the event should go to. The `View.OnMouseEvent` method can be overridden or the `View.MouseEvent` event can be subscribed to, to handle the low-level mouse event. If the low-level event is not handled by a view, `Application` will then call the appropriate high-level helper APIs. For example, if the user double-clicks the mouse, `View.OnMouseClick` will be called/`View.MouseClick` will be fired with the event arguments indicating which mouse button was double-clicked. +When the user does something with the mouse, the `ConsoleDriver` maps the platform-specific mouse event into a `MouseEventArgs` and calls `Application.RaiseMouseEvent`. Then, `Application.RaiseMouseEvent` determines which `View` the event should go to. The `View.OnMouseEvent` method can be overridden or the `View.MouseEvent` event can be subscribed to, to handle the low-level mouse event. If the low-level event is not handled by a view, `Application` will then call the appropriate high-level helper APIs. For example, if the user double-clicks the mouse, `View.OnMouseClick` will be called/`View.MouseClick` will be raised with the event arguments indicating which mouse button was double-clicked. ## Mouse Button and Movement Concepts From f7de547894dc83731c5fb02c49f918ece6310fa3 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 07:44:53 -0600 Subject: [PATCH 23/35] MouseEventArgs cleanup --- Terminal.Gui/Input/MouseEventArgs.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Terminal.Gui/Input/MouseEventArgs.cs b/Terminal.Gui/Input/MouseEventArgs.cs index 90b746d5f..ce1b27495 100644 --- a/Terminal.Gui/Input/MouseEventArgs.cs +++ b/Terminal.Gui/Input/MouseEventArgs.cs @@ -19,13 +19,13 @@ public class MouseEventArgs : HandledEventArgs /// public Point ScreenPosition { get; set; } - /// The deepest View who's screen coordinates are . + /// The deepest View who's contains . public View View { get; set; } - /// The position of the mouse in 's Viewport-relative coordinates. + /// The position of the mouse in 's Viewport-relative coordinates. Only valid if is set. public Point Position { get; set; } /// Returns a that represents the current . /// A that represents the current . - public override string ToString () { return $"({Position}):{Flags}"; } + public override string ToString () { return $"({ScreenPosition}):{Flags}:{View.Id}:{Position}"; } } From 7866e800cc966ec5d06b6728f02817aba068a0b2 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 07:50:50 -0600 Subject: [PATCH 24/35] MouseEventArgs cleanup --- Terminal.Gui/Application/Application.Mouse.cs | 8 ++++---- Terminal.Gui/Input/MouseEventArgs.cs | 7 ++++--- Terminal.Gui/Views/TabMouseEventArgs.cs | 2 +- docfx/docs/migratingfromv1.md | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index 47714c03f..7bf67f809 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -255,17 +255,17 @@ public static partial class Application // Mouse handling } /// - /// Raised when a mouse event occurs. Can be cancelled by setting to . + /// Raised when a mouse event occurs. Can be cancelled by setting to . /// /// /// - /// coordinates are screen-relative. + /// coordinates are screen-relative. /// /// - /// will be the deepest view under the under the mouse. + /// will be the deepest view under the under the mouse. /// /// - /// coordinates are view-relative. + /// coordinates are view-relative. Only valid if is set. /// /// /// Use this evento to handle mouse events at the application level, before View-specific handling. diff --git a/Terminal.Gui/Input/MouseEventArgs.cs b/Terminal.Gui/Input/MouseEventArgs.cs index ce1b27495..24c8cbfda 100644 --- a/Terminal.Gui/Input/MouseEventArgs.cs +++ b/Terminal.Gui/Input/MouseEventArgs.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +#nullable enable +using System.ComponentModel; namespace Terminal.Gui; @@ -20,12 +21,12 @@ public class MouseEventArgs : HandledEventArgs public Point ScreenPosition { get; set; } /// The deepest View who's contains . - public View View { get; set; } + public View? View { get; set; } /// The position of the mouse in 's Viewport-relative coordinates. Only valid if is set. public Point Position { get; set; } /// Returns a that represents the current . /// A that represents the current . - public override string ToString () { return $"({ScreenPosition}):{Flags}:{View.Id}:{Position}"; } + public override string ToString () { return $"({ScreenPosition}):{Flags}:{View?.Id}:{Position}"; } } diff --git a/Terminal.Gui/Views/TabMouseEventArgs.cs b/Terminal.Gui/Views/TabMouseEventArgs.cs index 707f68211..22a23ad01 100644 --- a/Terminal.Gui/Views/TabMouseEventArgs.cs +++ b/Terminal.Gui/Views/TabMouseEventArgs.cs @@ -13,7 +13,7 @@ public class TabMouseEventArgs : EventArgs } /// - /// Gets the actual mouse event. Use to cancel this event and perform custom + /// Gets the actual mouse event. Use to cancel this event and perform custom /// behavior (e.g. show a context menu). /// public MouseEventArgs MouseEvent { get; } diff --git a/docfx/docs/migratingfromv1.md b/docfx/docs/migratingfromv1.md index 3318aa448..2239bd7ff 100644 --- a/docfx/docs/migratingfromv1.md +++ b/docfx/docs/migratingfromv1.md @@ -196,7 +196,7 @@ In v1, the `Command` enum had duplicate entries and inconsistent naming. In v2 i The API for mouse input is now internally consistent and easier to use. -* The @Terminal.Gui.MouseEvent class replaces `MouseEventEventArgs`. +* The @Terminal.Gui.MouseEventArgs class replaces `MouseEventEventArgs`. * More granular APIs are provided to ease handling specific mouse actions. See [Mouse API](mouse.md). * Views can use the @Terminal.Gui.View.Highlight event to have the view be visibly highlighted on various mouse events. * Views can set `View.WantContinousButtonPresses = true` to have their @Terminal.Gui.Command.Accept command be invoked repeatedly as the user holds a mouse button down on the view. @@ -213,7 +213,7 @@ The API for mouse input is now internally consistent and easier to use. ```diff - Application.RootMouseEvent(KeyEvent arg) -+ Application.MouseEvent(object? sender, MouseEvent mouseEvent) ++ Application.MouseEvent(object? sender, MouseEventArgs mouseEvent) ``` ## Navigation - `Cursor`, `Focus`, `TabStop` etc... From 12fe1c2f0d92c84ee500692c50545495140e9e6e Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 08:16:59 -0600 Subject: [PATCH 25/35] Fixed OnMouseClicked --- Terminal.Gui/View/View.Mouse.cs | 69 +++++++++++++++++++++------------ Terminal.Gui/Views/Slider.cs | 4 +- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 8ff82b164..756292af5 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -213,7 +213,7 @@ public partial class View // Mouse APIs /// /// /// This method raises /; if not handled, and one of the - /// mouse buttons was clicked, the / event will be raised + /// mouse buttons was clicked, the / event will be raised /// /// /// See for more information. @@ -286,7 +286,7 @@ public partial class View // Mouse APIs // If it's a click, and we didn't handle it, then we need to generate a click event // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent and // it did not handle the press/release/clicked events via HandlePress/HandleRelease/HandleClicked - return OnMouseClick (mouseEvent); + return RaiseMouseClickEvent (mouseEvent); } return false; @@ -334,31 +334,19 @@ public partial class View // Mouse APIs #region Mouse Click Events - /// Raised when a mouse click occurs. - /// + /// Raises the / event. /// /// - /// Fired when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. + /// Called when the mouse is either clicked or double-clicked. /// /// - /// The coordinates are relative to . - /// - /// - public event EventHandler? MouseClick; - - /// Invokes the MouseClick event. - /// - /// - /// Called when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. + /// If is , will be invoked on every mouse event where + /// the mouse button is pressed. /// /// /// , if the event was handled, otherwise. - protected bool OnMouseClick (MouseEventArgs args) + protected bool RaiseMouseClickEvent (MouseEventArgs args) { - // BUGBUG: This should be named NewMouseClickEvent. Fix this in https://github.com/gui-cs/Terminal.Gui/issues/3029 - // Pre-conditions if (!Enabled) { @@ -368,7 +356,10 @@ public partial class View // Mouse APIs // Cancellable event - // BUGBUG: There should be a call to a protected virtual OnMouseClick here. Fix this in https://github.com/gui-cs/Terminal.Gui/issues/3029 + if (OnMouseClick (args) || args.Handled) + { + return args.Handled; + } MouseClick?.Invoke (this, args); @@ -386,6 +377,34 @@ public partial class View // Mouse APIs return args.Handled; } + /// + /// Called when a mouse click occurs. Check to see which button was clicked. + /// + /// + /// + /// Called when the mouse is either clicked or double-clicked. + /// + /// + /// If is , will be called on every mouse event where + /// the mouse button is pressed. + /// + /// + /// + /// , if the event was handled, otherwise. + protected virtual bool OnMouseClick (MouseEventArgs args) { return false; } + + /// Raised when a mouse click occurs. + /// + /// + /// Raised when the mouse is either clicked or double-clicked. + /// + /// + /// If is , will be raised on every mouse event where + /// the mouse button is pressed. + /// + /// + public event EventHandler? MouseClick; + /// /// INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the click event (typically /// when or are set). @@ -414,7 +433,7 @@ public partial class View // Mouse APIs // If mouse is still in bounds, generate a click if (!WantMousePositionReports && Viewport.Contains (mouseEvent.Position)) { - return OnMouseClick (mouseEvent); + return RaiseMouseClickEvent (mouseEvent); } return mouseEvent.Handled = true; @@ -468,9 +487,11 @@ public partial class View // Mouse APIs || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed) || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed)) { + bool firstPress = true; // The first time we get pressed event, grab the mouse and set focus if (Application.MouseGrabView != this) { + firstPress = true; Application.GrabMouse (this); if (!HasFocus && CanFocus) @@ -478,8 +499,6 @@ public partial class View // Mouse APIs // Set the focus, but don't invoke Accept SetFocus (); } - - mouseEvent.Handled = true; } if (Viewport.Contains (mouseEvent.Position)) @@ -500,10 +519,10 @@ public partial class View // Mouse APIs } } - if (WantContinuousButtonPressed && Application.MouseGrabView == this) + if (!firstPress && WantContinuousButtonPressed && Application.MouseGrabView == this) { // If this is not the first pressed event, generate a click - return OnMouseClick (mouseEvent); + return RaiseMouseClickEvent (mouseEvent); } return mouseEvent.Handled = true; diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index af2ff1366..9cbc785d1 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -1381,11 +1381,9 @@ public class Slider : View, IOrientation mouseEvent.Handled = true; - // BUGBUG: OnMouseClick is/should be internal. - return OnMouseClick (mouseEvent); } - return false; + return mouseEvent.Handled; Point ClampMovePosition (Point position) { From 9363401f44dffe284a8e753236769879f51b3ac8 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 08:57:43 -0600 Subject: [PATCH 26/35] Broke OnMouseClicked --- Terminal.Gui/Application/Application.Mouse.cs | 3 --- Terminal.Gui/Input/MouseEventArgs.cs | 19 +++++++++++++++++++ Terminal.Gui/View/View.Mouse.cs | 8 ++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index 7bf67f809..23bad92d2 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -170,9 +170,6 @@ public static partial class Application // Mouse handling return; } - // We can combine this into the switch expression to reduce cognitive complexity even more and likely - // avoid one or two of these checks in the process, as well. - WantContinuousButtonPressedView = deepestViewUnderMouse switch { { WantContinuousButtonPressed: true } => deepestViewUnderMouse, diff --git a/Terminal.Gui/Input/MouseEventArgs.cs b/Terminal.Gui/Input/MouseEventArgs.cs index 24c8cbfda..193c6dc80 100644 --- a/Terminal.Gui/Input/MouseEventArgs.cs +++ b/Terminal.Gui/Input/MouseEventArgs.cs @@ -26,6 +26,25 @@ public class MouseEventArgs : HandledEventArgs /// The position of the mouse in 's Viewport-relative coordinates. Only valid if is set. public Point Position { get; set; } + public bool IsButtonEvent + { + get + { + return Flags.HasFlag (MouseFlags.Button1Clicked) + || Flags.HasFlag (MouseFlags.Button2Clicked) + || Flags.HasFlag (MouseFlags.Button3Clicked) + || Flags.HasFlag (MouseFlags.Button4Clicked) + || Flags.HasFlag (MouseFlags.Button1DoubleClicked) + || Flags.HasFlag (MouseFlags.Button2DoubleClicked) + || Flags.HasFlag (MouseFlags.Button3DoubleClicked) + || Flags.HasFlag (MouseFlags.Button4DoubleClicked) + || Flags.HasFlag (MouseFlags.Button1TripleClicked) + || Flags.HasFlag (MouseFlags.Button2TripleClicked) + || Flags.HasFlag (MouseFlags.Button3TripleClicked) + || Flags.HasFlag (MouseFlags.Button4TripleClicked); + } + } + /// Returns a that represents the current . /// A that represents the current . public override string ToString () { return $"({ScreenPosition}):{Flags}:{View?.Id}:{Position}"; } diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 756292af5..0024d396f 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -201,7 +201,7 @@ public partial class View // Mouse APIs /// Gets or sets whether the wants mouse position reports. /// if mouse position reports are wanted; otherwise, . - public virtual bool WantMousePositionReports { get; set; } + public bool WantMousePositionReports { get; set; } /// /// Processes a new . This method is called by when a mouse @@ -487,11 +487,9 @@ public partial class View // Mouse APIs || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed) || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed)) { - bool firstPress = true; // The first time we get pressed event, grab the mouse and set focus if (Application.MouseGrabView != this) { - firstPress = true; Application.GrabMouse (this); if (!HasFocus && CanFocus) @@ -499,6 +497,8 @@ public partial class View // Mouse APIs // Set the focus, but don't invoke Accept SetFocus (); } + + mouseEvent.Handled = true; } if (Viewport.Contains (mouseEvent.Position)) @@ -519,7 +519,7 @@ public partial class View // Mouse APIs } } - if (!firstPress && WantContinuousButtonPressed && Application.MouseGrabView == this) + if (WantContinuousButtonPressed && Application.MouseGrabView == this) { // If this is not the first pressed event, generate a click return RaiseMouseClickEvent (mouseEvent); From e1faab09f2892fa391dcdb841a4fef60bd8db1c5 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 09:06:16 -0600 Subject: [PATCH 27/35] Refixed OnMouseClicked --- Terminal.Gui/View/View.Mouse.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 0024d396f..220bc48f3 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -416,6 +416,8 @@ public partial class View // Mouse APIs /// , if the event was handled, otherwise. internal bool WhenGrabbedHandleClicked (MouseEventArgs mouseEvent) { + mouseEvent.Handled = false; + if (Application.MouseGrabView == this && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked) @@ -453,6 +455,8 @@ public partial class View // Mouse APIs /// , if the event was handled, otherwise. internal bool WhenGrabbedHandleReleased (MouseEventArgs mouseEvent) { + mouseEvent.Handled = false; + if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) || mouseEvent.Flags.HasFlag (MouseFlags.Button2Released) || mouseEvent.Flags.HasFlag (MouseFlags.Button3Released) @@ -482,6 +486,8 @@ public partial class View // Mouse APIs /// , if the event was handled, otherwise. private bool WhenGrabbedHandlePressed (MouseEventArgs mouseEvent) { + mouseEvent.Handled = false; + if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed) || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed) @@ -497,8 +503,6 @@ public partial class View // Mouse APIs // Set the focus, but don't invoke Accept SetFocus (); } - - mouseEvent.Handled = true; } if (Viewport.Contains (mouseEvent.Position)) From 7d07d847e7b70647b6604b7724aefaf47b050904 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 09:12:38 -0600 Subject: [PATCH 28/35] Refixed OnMouseClicked - button --- Terminal.Gui/View/View.Mouse.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 220bc48f3..b171dda3e 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -503,6 +503,8 @@ public partial class View // Mouse APIs // Set the focus, but don't invoke Accept SetFocus (); } + + mouseEvent.Handled = true; } if (Viewport.Contains (mouseEvent.Position)) From e6fd6350ba860e1089ac2bed8e87e9f5c3650813 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 09:34:24 -0600 Subject: [PATCH 29/35] More fixes --- Terminal.Gui/View/View.Mouse.cs | 3 +-- UnitTests/View/Mouse/MouseTests.cs | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index b171dda3e..bc9682cb7 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -251,7 +251,7 @@ public partial class View // Mouse APIs } // Post-Conditions - if (HighlightStyle != HighlightStyle.None || (WantContinuousButtonPressed && WantMousePositionReports)) + if (HighlightStyle != HighlightStyle.None || WantContinuousButtonPressed) { if (WhenGrabbedHandlePressed (mouseEvent)) { @@ -527,7 +527,6 @@ public partial class View // Mouse APIs if (WantContinuousButtonPressed && Application.MouseGrabView == this) { - // If this is not the first pressed event, generate a click return RaiseMouseClickEvent (mouseEvent); } diff --git a/UnitTests/View/Mouse/MouseTests.cs b/UnitTests/View/Mouse/MouseTests.cs index 770536e8b..c4b10fe95 100644 --- a/UnitTests/View/Mouse/MouseTests.cs +++ b/UnitTests/View/Mouse/MouseTests.cs @@ -310,9 +310,15 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews view.MouseClick += (s, e) => clickedCount++; + me.Flags = pressed; + view.NewMouseEvent (me); + Assert.Equal (0, clickedCount); + me.Handled = false; + me.Flags = pressed; view.NewMouseEvent (me); Assert.Equal (1, clickedCount); + me.Handled = false; me.Flags = released; view.NewMouseEvent (me); @@ -344,22 +350,22 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews me.Flags = pressed; view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); + Assert.Equal (0, clickedCount); me.Handled = false; me.Flags = pressed; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); me.Handled = false; me.Flags = released; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); me.Handled = false; me.Flags = clicked; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); view.Dispose (); Application.ResetState (ignoreDisposed: true); @@ -386,21 +392,21 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews me.Flags = MouseFlags.Button1Pressed; me.Position = me.Position with { X = 0 }; view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); + Assert.Equal (0, clickedCount); me.Handled = false; // Move out of Viewport me.Flags = MouseFlags.Button1Pressed; me.Position = me.Position with { X = 1 }; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); me.Handled = false; // Move into Viewport me.Flags = MouseFlags.Button1Pressed; me.Position = me.Position with { X = 0 }; view.NewMouseEvent (me); - Assert.Equal (3, clickedCount); + Assert.Equal (2, clickedCount); me.Handled = false; view.Dispose (); From f503a5c06fa041a105f80f0c693d11a23244ad35 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 09:51:02 -0600 Subject: [PATCH 30/35] keyEvent -> key --- .../Application/Application.Keyboard.cs | 38 +++++++++---------- Terminal.Gui/View/View.Keyboard.cs | 2 +- Terminal.Gui/Views/FileDialog.cs | 6 +-- Terminal.Gui/Views/TableView/TableView.cs | 4 +- Terminal.Gui/Views/TileView.cs | 4 +- Terminal.Gui/Views/TreeView/TreeView.cs | 6 +-- UICatalog/Scenarios/Keys.cs | 17 ++++----- UICatalog/Scenarios/Snake.cs | 10 ++--- 8 files changed, 43 insertions(+), 44 deletions(-) diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs index a73e7cb86..c9fa96c63 100644 --- a/Terminal.Gui/Application/Application.Keyboard.cs +++ b/Terminal.Gui/Application/Application.Keyboard.cs @@ -5,17 +5,17 @@ public static partial class Application // Keyboard handling { /// /// Called when the user presses a key (by the ). Raises the cancelable - /// event - /// then calls on all top level views. Called before . + /// event, then calls on all top level views, and finally + /// if the key was not handled, invokes any Application-scoped . /// /// Can be used to simulate key press events. - /// + /// /// if the key was handled. - public static bool RaiseKeyDownEvent (Key keyEvent) + public static bool RaiseKeyDownEvent (Key key) { - KeyDown?.Invoke (null, keyEvent); + KeyDown?.Invoke (null, key); - if (keyEvent.Handled) + if (key.Handled) { return true; } @@ -24,7 +24,7 @@ public static partial class Application // Keyboard handling { foreach (Toplevel topLevel in TopLevels.ToList ()) { - if (topLevel.NewKeyDownEvent (keyEvent)) + if (topLevel.NewKeyDownEvent (key)) { return true; } @@ -37,7 +37,7 @@ public static partial class Application // Keyboard handling } else { - if (Top.NewKeyDownEvent (keyEvent)) + if (Top.NewKeyDownEvent (key)) { return true; } @@ -45,7 +45,7 @@ public static partial class Application // Keyboard handling // Invoke any Application-scoped KeyBindings. // The first view that handles the key will stop the loop. - foreach (KeyValuePair binding in KeyBindings.Bindings.Where (b => b.Key == keyEvent.KeyCode)) + foreach (KeyValuePair binding in KeyBindings.Bindings.Where (b => b.Key == key.KeyCode)) { if (binding.Value.BoundView is { }) { @@ -58,7 +58,7 @@ public static partial class Application // Keyboard handling } else { - if (!KeyBindings.TryGet (keyEvent, KeyBindingScope.Application, out KeyBinding appBinding)) + if (!KeyBindings.TryGet (key, KeyBindingScope.Application, out KeyBinding appBinding)) { continue; } @@ -67,7 +67,7 @@ public static partial class Application // Keyboard handling foreach (Command command in appBinding.Commands) { - toReturn = InvokeCommand (command, keyEvent, appBinding); + toReturn = InvokeCommand (command, key, appBinding); } return toReturn ?? true; @@ -76,18 +76,18 @@ public static partial class Application // Keyboard handling return false; - static bool? InvokeCommand (Command command, Key keyEvent, KeyBinding appBinding) + static bool? InvokeCommand (Command command, Key key, KeyBinding appBinding) { if (!CommandImplementations!.ContainsKey (command)) { throw new NotSupportedException ( - @$"A KeyBinding was set up for the command {command} ({keyEvent}) but that command is not supported by Application." + @$"A KeyBinding was set up for the command {command} ({key}) but that command is not supported by Application." ); } if (CommandImplementations.TryGetValue (command, out View.CommandImplementation? implementation)) { - var context = new CommandContext (command, keyEvent, appBinding); // Create the context here + var context = new CommandContext (command, key, appBinding); // Create the context here return implementation (context); } @@ -116,25 +116,25 @@ public static partial class Application // Keyboard handling /// then calls on all top level views. Called after . /// /// Can be used to simulate key release events. - /// + /// /// if the key was handled. - public static bool RaiseKeyUpEvent (Key a) + public static bool RaiseKeyUpEvent (Key key) { if (!IsInitialized) { return true; } - KeyUp?.Invoke (null, a); + KeyUp?.Invoke (null, key); - if (a.Handled) + if (key.Handled) { return true; } foreach (Toplevel topLevel in TopLevels.ToList ()) { - if (topLevel.NewKeyUpEvent (a)) + if (topLevel.NewKeyUpEvent (key)) { return true; } diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index 1ebc77df0..698d4e7b1 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -426,7 +426,7 @@ public partial class View // Keyboard APIs /// /// If the focused sub view does not handle the key press, this method raises / /// to allow the - /// view to pre-process the key press. If /. + /// view to pre-process the key press. /// /// See for an overview of Terminal.Gui keyboard APIs. /// diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 78ed5b584..3bc7bb386 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -670,11 +670,11 @@ public class FileDialog : Dialog FinishAccept (); } - private void AcceptIf (Key keyEvent, KeyCode isKey) + private void AcceptIf (Key key, KeyCode isKey) { - if (!keyEvent.Handled && keyEvent.KeyCode == isKey) + if (!key.Handled && key.KeyCode == isKey) { - keyEvent.Handled = true; + key.Handled = true; // User hit Enter in text box so probably wants the // contents of the text box as their selection not diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 5da0b11e3..5617c7c21 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -1563,7 +1563,7 @@ public class TableView : View /// private TableSelection CreateTableSelection (int x, int y) { return CreateTableSelection (x, y, x, y); } - private bool CycleToNextTableEntryBeginningWith (Key keyEvent) + private bool CycleToNextTableEntryBeginningWith (Key key) { int row = SelectedRow; @@ -1573,7 +1573,7 @@ public class TableView : View return false; } - int match = CollectionNavigator.GetNextMatchingItem (row, (char)keyEvent); + int match = CollectionNavigator.GetNextMatchingItem (row, (char)key); if (match != -1) { diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index ec117c652..5400ca046 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -286,11 +286,11 @@ public class TileView : View //// BUGBUG: Why is this not handled by a key binding??? /// - protected override bool OnKeyDownNotHandled (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key key) { var focusMoved = false; - if (keyEvent.KeyCode == ToggleResizable) + if (key.KeyCode == ToggleResizable) { foreach (TileViewLineView l in _splitterLines) { diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 36a249e8c..a1a110cbe 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -1182,7 +1182,7 @@ public class TreeView : View, ITreeView where T : class } /// - protected override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key key) { if (!Enabled) { @@ -1190,7 +1190,7 @@ public class TreeView : View, ITreeView where T : class } // If not a keybinding, is the key a searchable key press? - if (CollectionNavigatorBase.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation) + if (CollectionNavigatorBase.IsCompatibleKey (key) && AllowLetterBasedNavigation) { // If there has been a call to InvalidateMap since the last time // we need a new one to reflect the new exposed tree state @@ -1198,7 +1198,7 @@ public class TreeView : View, ITreeView where T : class // Find the current selected object within the tree int current = map.IndexOf (b => b.Model == SelectedObject); - int? newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)keyEvent); + int? newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)key); if (newIndex is int && newIndex != -1) { diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index e758af366..f2796a344 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -76,18 +76,18 @@ public class Keys : Scenario win.Add (label); int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length; - ObservableCollection keyEventList = new (); + ObservableCollection keyList = new (); - var appKeyEventListView = new ListView + var appKeyListView = new ListView { X = 0, Y = Pos.Bottom (label), Width = "KeyDown:".Length + maxKeyString, Height = Dim.Fill (), - Source = new ListWrapper (keyEventList) + Source = new ListWrapper (keyList) }; - appKeyEventListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; - win.Add (appKeyEventListView); + appKeyListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; + win.Add (appKeyListView); // View key events... edit.KeyDown += (s, a) => { keyDownList.Add (a.ToString ()); }; @@ -100,7 +100,7 @@ public class Keys : Scenario // KeyDown label = new Label { - X = Pos.Right (appKeyEventListView) + 1, + X = Pos.Right (appKeyListView) + 1, Y = Pos.Top (label), Text = "TextView Key Down:" }; @@ -142,10 +142,9 @@ public class Keys : Scenario void KeyDownPressUp (Key args, string updown) { - // BUGBUG: KeyEvent.ToString is badly broken var msg = $"Key{updown,-7}: {args}"; - keyEventList.Add (msg); - appKeyEventListView.MoveDown (); + keyList.Add (msg); + appKeyListView.MoveDown (); onKeyDownNotHandledListView.MoveDown (); } diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 998969d8d..906bc931d 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -357,30 +357,30 @@ public class Snake : Scenario } // BUGBUG: Should (can) this use key bindings instead. - protected override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key key) { - if (keyEvent.KeyCode == KeyCode.CursorUp) + if (key.KeyCode == KeyCode.CursorUp) { State.PlannedDirection = Direction.Up; return true; } - if (keyEvent.KeyCode == KeyCode.CursorDown) + if (key.KeyCode == KeyCode.CursorDown) { State.PlannedDirection = Direction.Down; return true; } - if (keyEvent.KeyCode == KeyCode.CursorLeft) + if (key.KeyCode == KeyCode.CursorLeft) { State.PlannedDirection = Direction.Left; return true; } - if (keyEvent.KeyCode == KeyCode.CursorRight) + if (key.KeyCode == KeyCode.CursorRight) { State.PlannedDirection = Direction.Right; From c50f47be1e985d619b3b38369e2cf5726891d901 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 09:58:25 -0600 Subject: [PATCH 31/35] Code cleanup --- Terminal.Gui/Input/ShortcutHelper.cs | 173 --------------------------- Terminal.Gui/View/View.Keyboard.cs | 1 - Terminal.Gui/Views/ListView.cs | 1 - 3 files changed, 175 deletions(-) delete mode 100644 Terminal.Gui/Input/ShortcutHelper.cs diff --git a/Terminal.Gui/Input/ShortcutHelper.cs b/Terminal.Gui/Input/ShortcutHelper.cs deleted file mode 100644 index d5e776a53..000000000 --- a/Terminal.Gui/Input/ShortcutHelper.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System.Diagnostics; - -namespace Terminal.Gui; - -// TODO: Nuke when #2975 is completed -/// Represents a helper to manipulate shortcut keys used on views. -public class ShortcutHelper -{ - // TODO: Update this to use Key, not KeyCode - private KeyCode shortcut; - - /// This is the global setting that can be used as a global shortcut to invoke the action on the view. - public virtual KeyCode Shortcut - { - get => shortcut; - set - { - if (shortcut != value && (PostShortcutValidation (value) || value is KeyCode.Null)) - { - shortcut = value; - } - } - } - - /// The keystroke combination used in the as string. - public virtual string ShortcutTag => Key.ToString (shortcut, Key.Separator); - - /// Lookup for a on range of keys. - /// The source key. - /// First key in range. - /// Last key in range. - public static bool CheckKeysFlagRange (KeyCode key, KeyCode first, KeyCode last) - { - for (var i = (uint)first; i < (uint)last; i++) - { - if ((key | (KeyCode)i) == key) - { - return true; - } - } - - return false; - } - - /// Allows to retrieve a from a - /// The key as string. - /// The delimiter string. - public static KeyCode GetShortcutFromTag (string tag, Rune delimiter = default) - { - string sCut = tag; - - if (string.IsNullOrEmpty (sCut)) - { - return default (KeyCode); - } - - var key = KeyCode.Null; - - //var hasCtrl = false; - if (delimiter == default (Rune)) - { - delimiter = Key.Separator; - } - - string [] keys = sCut.Split (delimiter.ToString ()); - - for (var i = 0; i < keys.Length; i++) - { - string k = keys [i]; - - if (k == "Ctrl") - { - //hasCtrl = true; - key |= KeyCode.CtrlMask; - } - else if (k == "Shift") - { - key |= KeyCode.ShiftMask; - } - else if (k == "Alt") - { - key |= KeyCode.AltMask; - } - else if (k.StartsWith ("F") && k.Length > 1) - { - int.TryParse (k.Substring (1), out int n); - - for (var j = (uint)KeyCode.F1; j <= (uint)KeyCode.F12; j++) - { - int.TryParse (((KeyCode)j).ToString ().Substring (1), out int f); - - if (f == n) - { - key |= (KeyCode)j; - } - } - } - else - { - key |= (KeyCode)Enum.Parse (typeof (KeyCode), k); - } - } - - return key; - } - - /// Used at key up validation. - /// The key to validate. - /// true if is valid.falseotherwise. - public static bool PostShortcutValidation (KeyCode key) - { - GetKeyToString (key, out KeyCode knm); - - if (CheckKeysFlagRange (key, KeyCode.F1, KeyCode.F12) || ((key & (KeyCode.CtrlMask | KeyCode.ShiftMask | KeyCode.AltMask)) != 0 && knm != KeyCode.Null)) - { - return true; - } - - return false; - } - - /// Used at key down or key press validation. - /// The key to validate. - /// true if is valid.falseotherwise. - public static bool PreShortcutValidation (KeyCode key) - { - if ((key & (KeyCode.CtrlMask | KeyCode.ShiftMask | KeyCode.AltMask)) == 0 - && !CheckKeysFlagRange (key, KeyCode.F1, KeyCode.F12)) - { - return false; - } - - return true; - } - - /// Return key as string. - /// The key to extract. - /// Correspond to the non modifier key. - private static string GetKeyToString (KeyCode key, out KeyCode knm) - { - if (key == KeyCode.Null) - { - knm = KeyCode.Null; - - return ""; - } - - knm = key; - KeyCode mK = key & (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.ShiftMask); - knm &= ~mK; - - for (var i = (uint)KeyCode.F1; i < (uint)KeyCode.F12; i++) - { - if (knm == (KeyCode)i) - { - mK |= (KeyCode)i; - } - } - - knm &= ~mK; - uint.TryParse (knm.ToString (), out uint c); - string s = mK == KeyCode.Null ? "" : mK.ToString (); - - if (s != "" && (knm != KeyCode.Null || c > 0)) - { - s += ","; - } - - s += c == 0 ? knm == KeyCode.Null ? "" : knm.ToString () : ((char)c).ToString (); - - return s; - } -} diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index 698d4e7b1..87c5a1ce6 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -297,7 +297,6 @@ public partial class View // Keyboard APIs } // After - // TODO: Is ProcessKeyDown really the right name? if (RaiseKeyDownNotHandled (key) || key.Handled) { return true; diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 1fa76e540..bae3400ce 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -817,7 +817,6 @@ public class ListView : View, IDesignable } } - // TODO: This should be cancelable /// Invokes the event if it is defined. /// if the event was fired. public bool OnOpenSelectedItem () From 6a90328c6159e1471d857857c47387ebd25042b1 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 10:33:56 -0600 Subject: [PATCH 32/35] Added Is helpers --- Terminal.Gui/Application/Application.Mouse.cs | 3 + Terminal.Gui/Input/MouseEventArgs.cs | 90 ++++++++++++++----- Terminal.Gui/View/View.Mouse.cs | 25 +----- Terminal.Gui/Views/TabView.cs | 14 +-- Terminal.Gui/Views/TextField.cs | 3 +- Terminal.Gui/Views/TextView.cs | 8 +- Terminal.Gui/Views/TreeView/TreeView.cs | 8 +- 7 files changed, 83 insertions(+), 68 deletions(-) diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index 23bad92d2..c4477ac85 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -251,6 +251,8 @@ public static partial class Application // Mouse handling } } + +#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved /// /// Raised when a mouse event occurs. Can be cancelled by setting to . /// @@ -269,6 +271,7 @@ public static partial class Application // Mouse handling /// /// public static event EventHandler? MouseEvent; +#pragma warning restore CS1574 // XML comment has cref attribute that could not be resolved internal static bool HandleMouseGrab (View? deepestViewUnderMouse, MouseEventArgs mouseEvent) { diff --git a/Terminal.Gui/Input/MouseEventArgs.cs b/Terminal.Gui/Input/MouseEventArgs.cs index 193c6dc80..cdf3aafb1 100644 --- a/Terminal.Gui/Input/MouseEventArgs.cs +++ b/Terminal.Gui/Input/MouseEventArgs.cs @@ -5,7 +5,8 @@ namespace Terminal.Gui; /// /// Specifies the event arguments for . This is a higher-level construct than -/// the wrapped class and is used for the events defined on and subclasses +/// the wrapped class and is used for the events defined on +/// and subclasses /// of View (e.g. and ). /// public class MouseEventArgs : HandledEventArgs @@ -23,27 +24,76 @@ public class MouseEventArgs : HandledEventArgs /// The deepest View who's contains . public View? View { get; set; } - /// The position of the mouse in 's Viewport-relative coordinates. Only valid if is set. + /// + /// The position of the mouse in 's Viewport-relative coordinates. Only valid if + /// is set. + /// public Point Position { get; set; } - public bool IsButtonEvent - { - get - { - return Flags.HasFlag (MouseFlags.Button1Clicked) - || Flags.HasFlag (MouseFlags.Button2Clicked) - || Flags.HasFlag (MouseFlags.Button3Clicked) - || Flags.HasFlag (MouseFlags.Button4Clicked) - || Flags.HasFlag (MouseFlags.Button1DoubleClicked) - || Flags.HasFlag (MouseFlags.Button2DoubleClicked) - || Flags.HasFlag (MouseFlags.Button3DoubleClicked) - || Flags.HasFlag (MouseFlags.Button4DoubleClicked) - || Flags.HasFlag (MouseFlags.Button1TripleClicked) - || Flags.HasFlag (MouseFlags.Button2TripleClicked) - || Flags.HasFlag (MouseFlags.Button3TripleClicked) - || Flags.HasFlag (MouseFlags.Button4TripleClicked); - } - } + /// + /// Gets whether contains any of the button pressed related flags. + /// + public bool IsPressed => Flags.HasFlag (MouseFlags.Button1Pressed) + || Flags.HasFlag (MouseFlags.Button2Pressed) + || Flags.HasFlag (MouseFlags.Button3Pressed) + || Flags.HasFlag (MouseFlags.Button4Pressed); + + /// + /// Gets whether contains any of the button released related flags. + /// + public bool IsReleased => Flags.HasFlag (MouseFlags.Button1Released) + || Flags.HasFlag (MouseFlags.Button2Released) + || Flags.HasFlag (MouseFlags.Button3Released) + || Flags.HasFlag (MouseFlags.Button4Released); + + /// + /// Gets whether contains any of the single-clicked related flags. + /// + public bool IsSingleClicked => Flags.HasFlag (MouseFlags.Button1Clicked) + || Flags.HasFlag (MouseFlags.Button2Clicked) + || Flags.HasFlag (MouseFlags.Button3Clicked) + || Flags.HasFlag (MouseFlags.Button4Clicked); + + /// + /// Gets whether contains any of the double-clicked related flags. + /// + public bool IsDoubleClicked => Flags.HasFlag (MouseFlags.Button1DoubleClicked) + || Flags.HasFlag (MouseFlags.Button2DoubleClicked) + || Flags.HasFlag (MouseFlags.Button3DoubleClicked) + || Flags.HasFlag (MouseFlags.Button4DoubleClicked); + + /// + /// Gets whether contains any of the triple-clicked related flags. + /// + public bool IsTripleClicked => Flags.HasFlag (MouseFlags.Button1TripleClicked) + || Flags.HasFlag (MouseFlags.Button2TripleClicked) + || Flags.HasFlag (MouseFlags.Button3TripleClicked) + || Flags.HasFlag (MouseFlags.Button4TripleClicked); + + /// + /// Gets whether contains any of the mouse button clicked related flags. + /// + public bool IsSingleDoubleOrTripleClicked => + Flags.HasFlag (MouseFlags.Button1Clicked) + || Flags.HasFlag (MouseFlags.Button2Clicked) + || Flags.HasFlag (MouseFlags.Button3Clicked) + || Flags.HasFlag (MouseFlags.Button4Clicked) + || Flags.HasFlag (MouseFlags.Button1DoubleClicked) + || Flags.HasFlag (MouseFlags.Button2DoubleClicked) + || Flags.HasFlag (MouseFlags.Button3DoubleClicked) + || Flags.HasFlag (MouseFlags.Button4DoubleClicked) + || Flags.HasFlag (MouseFlags.Button1TripleClicked) + || Flags.HasFlag (MouseFlags.Button2TripleClicked) + || Flags.HasFlag (MouseFlags.Button3TripleClicked) + || Flags.HasFlag (MouseFlags.Button4TripleClicked); + + /// + /// Gets whether contains any of the mouse wheel related flags. + /// + public bool IsWheel => Flags.HasFlag (MouseFlags.WheeledDown) + || Flags.HasFlag (MouseFlags.WheeledUp) + || Flags.HasFlag (MouseFlags.WheeledLeft) + || Flags.HasFlag (MouseFlags.WheeledRight); /// Returns a that represents the current . /// A that represents the current . diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index bc9682cb7..e0e36609f 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -269,19 +269,7 @@ public partial class View // Mouse APIs } } - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button1TripleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2TripleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3TripleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4TripleClicked) - ) + if (mouseEvent.IsSingleDoubleOrTripleClicked) { // If it's a click, and we didn't handle it, then we need to generate a click event // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent and @@ -418,11 +406,7 @@ public partial class View // Mouse APIs { mouseEvent.Handled = false; - if (Application.MouseGrabView == this - && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked))) + if (Application.MouseGrabView == this && mouseEvent.IsSingleClicked) { // We're grabbed. Clicked event comes after the last Release. This is our signal to ungrab Application.UngrabMouse (); @@ -457,10 +441,7 @@ public partial class View // Mouse APIs { mouseEvent.Handled = false; - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Released) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Released) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Released)) + if (mouseEvent.IsReleased) { if (Application.MouseGrabView == this) { diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 62f403364..d605b6fa0 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -573,11 +573,7 @@ public class TabView : View { Tab hit = me.View is Tab ? (Tab)me.View : null; - bool isClick = me.Flags.HasFlag (MouseFlags.Button1Clicked) - || me.Flags.HasFlag (MouseFlags.Button2Clicked) - || me.Flags.HasFlag (MouseFlags.Button3Clicked); - - if (isClick) + if (me.IsSingleClicked) { _host.OnTabClicked (new TabMouseEventArgs (hit, me)); @@ -588,9 +584,7 @@ public class TabView : View } } - if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) - && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) - && !me.Flags.HasFlag (MouseFlags.Button1TripleClicked)) + if (!me.IsSingleDoubleOrTripleClicked) { return false; } @@ -600,9 +594,7 @@ public class TabView : View SetFocus (); } - if (me.Flags.HasFlag (MouseFlags.Button1Clicked) - || me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) - || me.Flags.HasFlag (MouseFlags.Button1TripleClicked)) + if (me.IsSingleDoubleOrTripleClicked) { var scrollIndicatorHit = 0; diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index b9f601493..0b08e1f04 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -800,9 +800,8 @@ public class TextField : View /// protected override bool OnMouseEvent (MouseEventArgs ev) { - if (!ev.Flags.HasFlag (MouseFlags.Button1Pressed) + if (ev is { IsPressed: false, IsReleased: false } && !ev.Flags.HasFlag (MouseFlags.ReportMousePosition) - && !ev.Flags.HasFlag (MouseFlags.Button1Released) && !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked) && !ev.Flags.HasFlag (MouseFlags.Button1TripleClicked) && !ev.Flags.HasFlag (ContextMenu.MouseFlags)) diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 7400fe2c4..132f907a3 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3276,16 +3276,10 @@ public class TextView : View /// protected override bool OnMouseEvent (MouseEventArgs ev) { - if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked) - && !ev.Flags.HasFlag (MouseFlags.Button1Pressed) + if (ev is { IsSingleDoubleOrTripleClicked: false, IsPressed: false, IsReleased: false, IsWheel: false } && !ev.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) - && !ev.Flags.HasFlag (MouseFlags.Button1Released) && !ev.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ButtonShift) - && !ev.Flags.HasFlag (MouseFlags.WheeledDown) - && !ev.Flags.HasFlag (MouseFlags.WheeledUp) - && !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked) && !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked | MouseFlags.ButtonShift) - && !ev.Flags.HasFlag (MouseFlags.Button1TripleClicked) && !ev.Flags.HasFlag (ContextMenu!.MouseFlags)) { return false; diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index af6f80eb1..4e09eba2b 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -993,12 +993,8 @@ public class TreeView : View, ITreeView where T : class protected override bool OnMouseEvent (MouseEventArgs me) { // If it is not an event we care about - if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) - && !me.Flags.HasFlag (ObjectActivationButton ?? MouseFlags.Button1DoubleClicked) - && !me.Flags.HasFlag (MouseFlags.WheeledDown) - && !me.Flags.HasFlag (MouseFlags.WheeledUp) - && !me.Flags.HasFlag (MouseFlags.WheeledRight) - && !me.Flags.HasFlag (MouseFlags.WheeledLeft)) + if (me is { IsSingleClicked: false, IsPressed: false, IsReleased: false, IsWheel: false } + && !me.Flags.HasFlag (ObjectActivationButton ?? MouseFlags.Button1DoubleClicked)) { // do nothing return false; From 64f87cd4458f34f27610384ec6c60fb2400360aa Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 10:36:34 -0600 Subject: [PATCH 33/35] code cleanup --- Terminal.Gui/Input/MouseFlags.cs | 2 +- Terminal.Gui/View/View.Mouse.cs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Terminal.Gui/Input/MouseFlags.cs b/Terminal.Gui/Input/MouseFlags.cs index e77175f75..56bed6e88 100644 --- a/Terminal.Gui/Input/MouseFlags.cs +++ b/Terminal.Gui/Input/MouseFlags.cs @@ -1,6 +1,6 @@ namespace Terminal.Gui; -/// Mouse flags reported in . +/// Mouse flags reported in . /// They just happen to map to the ncurses ones. [Flags] public enum MouseFlags diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index e0e36609f..a76de77b3 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -469,10 +469,7 @@ public partial class View // Mouse APIs { mouseEvent.Handled = false; - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed)) + if (mouseEvent.IsPressed) { // The first time we get pressed event, grab the mouse and set focus if (Application.MouseGrabView != this) From bf2e032cf4f4913dc3eb31575c778dcbc90d4bd9 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 10:48:00 -0600 Subject: [PATCH 34/35] Fixed Time/DateField crash --- Terminal.Gui/Views/DateField.cs | 4 ++-- Terminal.Gui/Views/TimeField.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 0c8b253c2..08d21d732 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -162,12 +162,12 @@ public class DateField : TextField newPoint = 1; } - if (newPoint != point) + //if (newPoint != point) { CursorPosition = newPoint; } - while (Text [CursorPosition].ToString () == _separator) + while (CursorPosition < Text.GetColumns () - 1 && Text [CursorPosition].ToString () == _separator) { if (increment) { diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index e520e479c..32f5046fc 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -220,12 +220,12 @@ public class TimeField : TextField newPoint = 1; } - if (newPoint != point) + //if (newPoint != point) { CursorPosition = newPoint; } - while (Text [CursorPosition] == _sepChar [0]) + while (CursorPosition < Text.GetColumns() -1 && Text [CursorPosition] == _sepChar [0]) { if (increment) { From e85f6942696d4e51d4c0bd996393c9c04ef31b97 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 15 Oct 2024 10:55:23 -0600 Subject: [PATCH 35/35] Fixed Time/DateField crash 2 --- Terminal.Gui/Views/DateField.cs | 7 ++++++- Terminal.Gui/Views/TimeField.cs | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 08d21d732..9490a7b28 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -116,6 +116,11 @@ public class DateField : TextField /// protected override bool OnMouseEvent (MouseEventArgs ev) { + if (base.OnMouseEvent (ev) || ev.Handled) + { + return true; + } + if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { AdjCursorPosition (ev.Position.X); @@ -162,7 +167,7 @@ public class DateField : TextField newPoint = 1; } - //if (newPoint != point) + if (newPoint != point) { CursorPosition = newPoint; } diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index 32f5046fc..ecc94a7be 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -165,6 +165,11 @@ public class TimeField : TextField /// protected override bool OnMouseEvent (MouseEventArgs ev) { + if (base.OnMouseEvent (ev) || ev.Handled) + { + return true; + } + if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { int point = ev.Position.X; @@ -220,7 +225,7 @@ public class TimeField : TextField newPoint = 1; } - //if (newPoint != point) + if (newPoint != point) { CursorPosition = newPoint; }