Skip to content

Commit 2d7b3f4

Browse files
author
tznind
committed
Added interactive scenario (create and delete tree nodes on demand). Added Tag and Text to interface for ITreeNode
1 parent db3d784 commit 2d7b3f4

4 files changed

Lines changed: 170 additions & 8 deletions

File tree

‎Terminal.Gui/Views/TreeView.cs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,21 @@ namespace Terminal.Gui {
1212
/// </summary>
1313
public interface ITreeNode
1414
{
15+
/// <summary>
16+
/// Text to display when rendering the node
17+
/// </summary>
18+
string Text {get;set;}
19+
1520
/// <summary>
1621
/// The children of your class which should be rendered underneath it when expanded
1722
/// </summary>
1823
/// <value></value>
1924
IList<ITreeNode> Children {get;}
25+
26+
/// <summary>
27+
/// Optionally allows you to store some custom data/class here.
28+
/// </summary>
29+
object Tag {get;set;}
2030
}
2131

2232
/// <summary>
@@ -36,6 +46,11 @@ public class TreeNode : ITreeNode
3646
/// <value></value>
3747
public string Text {get;set;}
3848

49+
/// <summary>
50+
/// Optionally allows you to store some custom data/class here.
51+
/// </summary>
52+
public object Tag {get;set;}
53+
3954
/// <summary>
4055
/// returns <see cref="Text"/>
4156
/// </summary>
@@ -228,6 +243,7 @@ public class TreeView : TreeView<ITreeNode> {
228243
public TreeView ()
229244
{
230245
TreeBuilder = new TreeNodeBuilder();
246+
AspectGetter = o=>o == null ? "Null" : (o.Text ?? o?.ToString() ?? "Unamed Node");
231247
}
232248
}
233249

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Terminal.Gui;
7+
using static UICatalog.Scenario;
8+
9+
namespace UICatalog.Scenarios {
10+
11+
[ScenarioMetadata (Name: "Interactive Tree", Description: "Create nodes and child nodes in TreeView")]
12+
[ScenarioCategory ("Controls")]
13+
class InteractiveTree : Scenario{
14+
15+
TreeView treeView;
16+
17+
public override void Setup ()
18+
{
19+
Win.Title = this.GetName();
20+
Win.Y = 1; // menu
21+
Win.Height = Dim.Fill (1); // status bar
22+
Top.LayoutSubviews ();
23+
24+
var menu = new MenuBar (new MenuBarItem [] {
25+
new MenuBarItem ("_File", new MenuItem [] {
26+
new MenuItem ("_Quit", "", () => Quit()),
27+
})
28+
});
29+
30+
treeView = new TreeView() {
31+
X = 0,
32+
Y = 0,
33+
Width = Dim.Fill(),
34+
Height = Dim.Fill(1),
35+
};
36+
treeView.KeyPress += TreeView_KeyPress;
37+
38+
Win.Add(treeView);
39+
40+
var statusBar = new StatusBar (new StatusItem [] {
41+
new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => Quit()),
42+
new StatusItem(Key.CtrlMask | Key.C, "~^C~ Add Child", () => AddChildNode()),
43+
new StatusItem(Key.CtrlMask | Key.T, "~^T~ Add Root", () => AddRootNode()),
44+
new StatusItem(Key.CtrlMask | Key.R, "~^R~ Rename Node", () => RenameNode()),
45+
});
46+
Top.Add (statusBar);
47+
48+
}
49+
50+
private void TreeView_KeyPress (View.KeyEventEventArgs obj)
51+
{
52+
if(obj.KeyEvent.Key == Key.DeleteChar) {
53+
54+
var toDelete = treeView.SelectedObject;
55+
56+
if(toDelete == null)
57+
return;
58+
59+
obj.Handled = true;
60+
61+
// if it is a root object remove it
62+
if(treeView.Objects.Contains(toDelete)) {
63+
treeView.Remove(toDelete);
64+
}
65+
else {
66+
var parent = treeView.GetParent(toDelete);
67+
68+
if(parent == null)
69+
MessageBox.ErrorQuery("Could not delete",$"Parent of '{toDelete}' was unexpectedly null","Ok");
70+
else {
71+
//update the model
72+
parent.Children.Remove(toDelete);
73+
74+
//refresh the tree
75+
treeView.RefreshObject(parent);
76+
}
77+
}
78+
}
79+
}
80+
81+
private void RenameNode ()
82+
{
83+
var node = treeView.SelectedObject;
84+
85+
if(node != null) {
86+
if(GetText("Text","Enter text for node:",node.Text,out string entered)) {
87+
node.Text = entered;
88+
treeView.RefreshObject(node);
89+
}
90+
}
91+
}
92+
93+
private void AddRootNode ()
94+
{
95+
if(GetText("Text","Enter text for node:","",out string entered)) {
96+
treeView.AddObject(new TreeNode(entered));
97+
}
98+
}
99+
100+
private void AddChildNode()
101+
{
102+
var node = treeView.SelectedObject;
103+
104+
if(node != null) {
105+
if(GetText("Text","Enter text for node:","",out string entered)) {
106+
node.Children.Add(new TreeNode(entered));
107+
treeView.RefreshObject(node);
108+
}
109+
}
110+
}
111+
112+
private bool GetText(string title, string label, string initialText, out string enteredText)
113+
{
114+
bool okPressed = false;
115+
116+
var ok = new Button ("Ok", is_default: true);
117+
ok.Clicked += () => { okPressed = true; Application.RequestStop (); };
118+
var cancel = new Button ("Cancel");
119+
cancel.Clicked += () => { Application.RequestStop (); };
120+
var d = new Dialog (title, 60, 20, ok, cancel);
121+
122+
var lbl = new Label() {
123+
X = 0,
124+
Y = 1,
125+
Text = label
126+
};
127+
128+
var tf = new TextField()
129+
{
130+
Text = initialText,
131+
X = 0,
132+
Y = 2,
133+
Width = Dim.Fill()
134+
};
135+
136+
d.Add (lbl,tf);
137+
tf.SetFocus();
138+
139+
Application.Run (d);
140+
141+
enteredText = okPressed? tf.Text.ToString() : null;
142+
return okPressed;
143+
}
144+
145+
private void Quit ()
146+
{
147+
Application.RequestStop ();
148+
}
149+
}
150+
}

‎UICatalog/Scenarios/TreeUseCases.cs‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public override void Setup ()
4343
}
4444

4545
// Your data class
46-
private class House : ITreeNode {
46+
private class House : TreeNode {
4747

4848

4949
// Your properties
@@ -59,14 +59,10 @@ public override string ToString ()
5959
return Address;
6060
}
6161
}
62-
private class Room : ITreeNode{
62+
private class Room : TreeNode{
6363

6464
public string Name {get;set;}
6565

66-
67-
// Rooms have no sub objects
68-
public IList<ITreeNode> Children => new List<ITreeNode>();
69-
7066
public override string ToString ()
7167
{
7268
return Name;

‎docfx/articles/treeview.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Having to create a bunch of TreeNode objects can be a pain especially if you alr
3434

3535
```csharp
3636
// Your data class
37-
private class House : ITreeNode {
37+
private class House : TreeNode {
3838

3939

4040
// Your properties
@@ -52,7 +52,7 @@ private class House : ITreeNode {
5252
}
5353

5454
// Your other data class
55-
private class Room : ITreeNode{
55+
private class Room : TreeNode{
5656

5757
public string Name {get;set;}
5858

0 commit comments

Comments
 (0)