From ec853402859b8d5cd1b49323610a824a2af9f7cd Mon Sep 17 00:00:00 2001 From: tznind Date: Tue, 2 Mar 2021 19:14:38 +0000 Subject: [PATCH] Added ObjectActivated event --- Terminal.Gui/Views/TreeView.cs | 64 +++++++++++++++++++++ UnitTests/TreeViewTests.cs | 100 +++++++++++++++++++++++++++++---- 2 files changed, 154 insertions(+), 10 deletions(-) diff --git a/Terminal.Gui/Views/TreeView.cs b/Terminal.Gui/Views/TreeView.cs index 1611d8c95..cb185442b 100644 --- a/Terminal.Gui/Views/TreeView.cs +++ b/Terminal.Gui/Views/TreeView.cs @@ -332,6 +332,17 @@ namespace Terminal.Gui { } } + + /// + /// This event is raised when an object is activated e.g. by double clicking or pressing + /// + public event Action> ObjectActivated; + + /// + /// Key which when pressed triggers . Defaults to Enter + /// + public Key ObjectActivationKey {get;set;} = Key.Enter; + /// /// Secondary selected regions of tree when is true /// @@ -648,7 +659,20 @@ namespace Terminal.Gui { /// public override bool ProcessKey (KeyEvent keyEvent) { + if(keyEvent.Key == ObjectActivationKey) + { + var o = SelectedObject; + + if(o != null){ + OnObjectActivated(new ObjectActivatedEventArgs(this,o)); + + PositionCursor (); + return true; + } + } + switch (keyEvent.Key) { + case Key.CursorRight: Expand(SelectedObject); break; @@ -696,6 +720,15 @@ namespace Terminal.Gui { return true; } + /// + /// Raises the event + /// + /// + protected void OnObjectActivated(ObjectActivatedEventArgs e) + { + ObjectActivated?.Invoke(e); + } + /// public override bool MouseEvent (MouseEvent me) { @@ -1124,6 +1157,37 @@ namespace Terminal.Gui { } } + /// + /// Event args for the event + /// + /// + public class ObjectActivatedEventArgs where T : class { + + /// + /// The tree in which the activation occurred + /// + /// + public TreeView Tree {get;} + + /// + /// The object that was selected at the time of activation + /// + /// + public T ActivatedObject {get;} + + + /// + /// Creates a new instance documenting activation of the object + /// + /// Tree in which the activation is happening + /// What object is being activated + public ObjectActivatedEventArgs(TreeView tree, T activated) + { + Tree = tree; + ActivatedObject = activated; + } + } + class TreeSelection where T : class { public Branch Origin {get;} diff --git a/UnitTests/TreeViewTests.cs b/UnitTests/TreeViewTests.cs index b4a335788..992057ec0 100644 --- a/UnitTests/TreeViewTests.cs +++ b/UnitTests/TreeViewTests.cs @@ -103,9 +103,7 @@ namespace UnitTests { var tree = CreateTree(out Factory f, out Car car1, out _); tree.Bounds = new Rect(0,0,10,10); - var driver = new FakeDriver (); - Application.Init (driver, new FakeMainLoop (() => FakeConsole.ReadKey (true))); - driver.Init (() => { }); + InitFakeDriver(); //-+Factory Assert.Equal(9,tree.GetContentWidth(true)); @@ -129,9 +127,7 @@ namespace UnitTests { // control only allows 1 row to be viewed at once tree.Bounds = new Rect(0,0,20,1); - var driver = new FakeDriver (); - Application.Init (driver, new FakeMainLoop (() => FakeConsole.ReadKey (true))); - driver.Init (() => { }); + InitFakeDriver(); //-+Factory Assert.Equal(9,tree.GetContentWidth(true)); @@ -449,14 +445,12 @@ namespace UnitTests { tree.SelectedObject = root; - Assert.Equal(1,tree.GetAllSelectedObjects().Count()); - Assert.Contains(root,tree.GetAllSelectedObjects()); + Assert.Single(tree.GetAllSelectedObjects(),root); // move selection down 1 tree.AdjustSelection(1,false); - Assert.Equal(1,tree.GetAllSelectedObjects().Count()); - Assert.Contains(l1,tree.GetAllSelectedObjects()); + Assert.Single(tree.GetAllSelectedObjects(),l1); // expand selection down 2 (e.g. shift down twice) tree.AdjustSelection(1,true); @@ -473,6 +467,85 @@ namespace UnitTests { Assert.Empty(tree.GetAllSelectedObjects()); } + [Fact] + public void ObjectActivated_Called() + { + var tree = CreateTree(out Factory f, out Car car1, out _); + + InitFakeDriver(); + + object activated = null; + bool called = false; + + // register for the event + tree.ObjectActivated += (s)=> + { + activated = s.ActivatedObject; + called = true; + }; + + Assert.False(called); + + // no object is selected yet so no event should happen + tree.ProcessKey(new KeyEvent(Key.Enter,new KeyModifiers())); + + Assert.Null(activated); + Assert.False(called); + + // down to select factory + tree.ProcessKey(new KeyEvent(Key.CursorDown,new KeyModifiers())); + + tree.ProcessKey(new KeyEvent(Key.Enter,new KeyModifiers())); + + Assert.True(called); + Assert.Same(f,activated); + } + + + [Fact] + public void ObjectActivated_CustomKey() + { + var tree = CreateTree(out Factory f, out Car car1, out _); + + InitFakeDriver(); + + tree.ObjectActivationKey = Key.Delete; + object activated = null; + bool called = false; + + // register for the event + tree.ObjectActivated += (s)=> + { + activated = s.ActivatedObject; + called = true; + }; + + Assert.False(called); + + // no object is selected yet so no event should happen + tree.ProcessKey(new KeyEvent(Key.Enter,new KeyModifiers())); + + Assert.Null(activated); + Assert.False(called); + + // down to select factory + tree.ProcessKey(new KeyEvent(Key.CursorDown,new KeyModifiers())); + + tree.ProcessKey(new KeyEvent(Key.Enter,new KeyModifiers())); + + // Enter is not the activation key in this unit test + Assert.Null(activated); + Assert.False(called); + + // Delete is the activation key in this test so should result in activation occurring + tree.ProcessKey(new KeyEvent(Key.Delete,new KeyModifiers())); + + Assert.True(called); + Assert.Same(f,activated); + + } + + /// /// Simulates behind the scenes changes to an object (which children it has) and how to sync that into the tree using @@ -527,5 +600,12 @@ namespace UnitTests { return obj is EqualityTestObject eto && Equals(Name, eto.Name); } } + + private void InitFakeDriver() + { + var driver = new FakeDriver (); + Application.Init (driver, new FakeMainLoop (() => FakeConsole.ReadKey (true))); + driver.Init (() => { }); + } } }