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 (() => { });
+ }
}
}