diff --git a/Terminal.Gui/Views/TreeView.cs b/Terminal.Gui/Views/TreeView.cs
index 4f4503342..4fdf51ab1 100644
--- a/Terminal.Gui/Views/TreeView.cs
+++ b/Terminal.Gui/Views/TreeView.cs
@@ -609,6 +609,29 @@ namespace Terminal.Gui {
}
}
+ ///
+ ///
+ /// Returns the Y coordinate within the of the
+ /// tree at which would be displayed or null if
+ /// it is not currently exposed (e.g. its parent is collapsed).
+ ///
+ ///
+ /// Note that the returned value can be negative if the TreeView is scrolled
+ /// down and the object is off the top of the view.
+ ///
+ ///
+ ///
+ ///
+ public int? IndexOf(T toFind)
+ {
+ var idx = BuildLineMap ().IndexOf (o => o.Model.Equals (toFind));
+
+ if (idx == -1)
+ return null;
+
+ return idx - ScrollOffsetVertical;
+ }
+
///
/// Moves the to the next item that begins with
/// This method will loop back to the start of the tree if reaching the end without finding a match
diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs
index de1d49f90..acb97161b 100644
--- a/UICatalog/Scenarios/TreeViewFileSystem.cs
+++ b/UICatalog/Scenarios/TreeViewFileSystem.cs
@@ -78,6 +78,7 @@ namespace UICatalog.Scenarios {
treeViewFiles.ObjectActivated += TreeViewFiles_ObjectActivated;
treeViewFiles.MouseClick += TreeViewFiles_MouseClick;
+ treeViewFiles.KeyPress += TreeViewFiles_KeyPress;
SetupFileTree ();
@@ -89,6 +90,29 @@ namespace UICatalog.Scenarios {
red = Application.Driver.MakeAttribute (Color.Red, Color.Blue);
}
+ private void TreeViewFiles_KeyPress (View.KeyEventEventArgs obj)
+ {
+ if(obj.KeyEvent.Key == (Key.R | Key.CtrlMask)) {
+
+ var selected = treeViewFiles.SelectedObject;
+
+ // nothing is selected
+ if (selected == null)
+ return;
+
+ var location = treeViewFiles.IndexOf (selected);
+
+ //selected object is offscreen or somehow not found
+ if (location == null || location < 0 || location > treeViewFiles.Frame.Height)
+ return;
+
+ ShowContextMenu (new Point (
+ 5 + treeViewFiles.Frame.X,
+ location.Value + treeViewFiles.Frame.Y + 2),
+ selected);
+ }
+ }
+
private void TreeViewFiles_MouseClick (View.MouseEventArgs obj)
{
// if user right clicks
@@ -100,39 +124,44 @@ namespace UICatalog.Scenarios {
if (rightClicked == null)
return;
- var menu = new ContextMenu ();
- menu.Position = new Point(
+ ShowContextMenu (new Point (
obj.MouseEvent.X + treeViewFiles.Frame.X,
- obj.MouseEvent.Y + treeViewFiles.Frame.Y +1);
-
- menu.MenuItems = new MenuBarItem (new [] { new MenuItem ("Properties",null,()=> {
- MessageBox.Query($"{rightClicked.Name}({rightClicked.GetType().Name})",Describe(rightClicked),"Ok");
- }
-
- ) });
- menu.Show ();
-
+ obj.MouseEvent.Y + treeViewFiles.Frame.Y + 2),
+ rightClicked);
}
}
- private string Describe (FileSystemInfo f)
+ private void ShowContextMenu (Point screenPoint, FileSystemInfo forObject)
{
- try {
+ var menu = new ContextMenu ();
+ menu.Position = screenPoint;
- if (f is FileInfo fi) {
- return "Size:" + fi.Length;
- }
+ menu.MenuItems = new MenuBarItem (new [] { new MenuItem ("Properties", null, () => ShowPropertiesOf (forObject)) });
+
+ Application.MainLoop.Invoke(menu.Show);
+ }
- if (f is DirectoryInfo d) {
- return $@"Parent:{d.Parent}
-Attributes:{d.Attributes}";
- }
- } catch (Exception) {
+ private void ShowPropertiesOf (FileSystemInfo fileSystemInfo)
+ {
+ if (fileSystemInfo is FileInfo f) {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder ();
+ sb.AppendLine ($"Path:{f.DirectoryName}");
+ sb.AppendLine ($"Size:{f.Length:N0} bytes");
+ sb.AppendLine ($"Modified:{ f.LastWriteTime}");
+ sb.AppendLine ($"Created:{ f.CreationTime}");
- return "Could not get properties";
+ MessageBox.Query (f.Name, sb.ToString (), "Close");
}
- return null;
+ if (fileSystemInfo is DirectoryInfo dir) {
+
+ System.Text.StringBuilder sb = new System.Text.StringBuilder ();
+ sb.AppendLine ($"Path:{dir.Parent?.FullName}");
+ sb.AppendLine ($"Modified:{ dir.LastWriteTime}");
+ sb.AppendLine ($"Created:{ dir.CreationTime}");
+
+ MessageBox.Query (dir.Name, sb.ToString (), "Close");
+ }
}
private void SetupScrollBar ()
@@ -187,25 +216,7 @@ Attributes:{d.Attributes}";
private void TreeViewFiles_ObjectActivated (ObjectActivatedEventArgs obj)
{
- if (obj.ActivatedObject is FileInfo f) {
- System.Text.StringBuilder sb = new System.Text.StringBuilder ();
- sb.AppendLine ($"Path:{f.DirectoryName}");
- sb.AppendLine ($"Size:{f.Length:N0} bytes");
- sb.AppendLine ($"Modified:{ f.LastWriteTime}");
- sb.AppendLine ($"Created:{ f.CreationTime}");
-
- MessageBox.Query (f.Name, sb.ToString (), "Close");
- }
-
- if (obj.ActivatedObject is DirectoryInfo dir) {
-
- System.Text.StringBuilder sb = new System.Text.StringBuilder ();
- sb.AppendLine ($"Path:{dir.Parent?.FullName}");
- sb.AppendLine ($"Modified:{ dir.LastWriteTime}");
- sb.AppendLine ($"Created:{ dir.CreationTime}");
-
- MessageBox.Query (dir.Name, sb.ToString (), "Close");
- }
+ ShowPropertiesOf (obj.ActivatedObject);
}
private void ShowLines ()
diff --git a/UnitTests/TreeViewTests.cs b/UnitTests/TreeViewTests.cs
index 41e0b12f4..7dc514b49 100644
--- a/UnitTests/TreeViewTests.cs
+++ b/UnitTests/TreeViewTests.cs
@@ -768,7 +768,68 @@ namespace Terminal.Gui.Views {
Assert.Null (tv.HitTest (new Point (0, 3)));
Assert.Null (tv.HitTest (new Point (0, 4)));
}
- [Fact, AutoInitShutdown]
+
+ [Fact, AutoInitShutdown]
+ public void TestTreeIndexOf ()
+ {
+ var tv = new TreeView { Width = 20, Height = 10 };
+
+ var n1 = new TreeNode ("normal");
+ var n1_1 = new TreeNode ("pink");
+ var n1_2 = new TreeNode ("normal");
+ n1.Children.Add (n1_1);
+ n1.Children.Add (n1_2);
+
+ var n2 = new TreeNode ("pink");
+ tv.AddObject (n1);
+ tv.AddObject (n2);
+ tv.Expand (n1);
+
+ tv.ColorScheme = new ColorScheme ();
+ tv.Redraw (tv.Bounds);
+
+ GraphViewTests.AssertDriverContentsAre (
+@"├-normal
+│ ├─pink
+│ └─normal
+└─pink
+", output);
+
+ Assert.Equal (0, tv.IndexOf (n1));
+ Assert.Equal (1, tv.IndexOf (n1_1));
+ Assert.Equal (2, tv.IndexOf (n1_2));
+ Assert.Equal (3, tv.IndexOf (n2));
+
+ tv.Collapse (n1);
+
+ tv.Redraw (tv.Bounds);
+
+
+ GraphViewTests.AssertDriverContentsAre (
+@"├+normal
+└─pink
+", output);
+ Assert.Equal (0, tv.IndexOf (n1));
+ Assert.Null (tv.IndexOf (n1_1));
+ Assert.Null (tv.IndexOf (n1_2));
+ Assert.Equal (1, tv.IndexOf (n2));
+
+
+ // scroll down 1
+ tv.ScrollOffsetVertical = 1;
+
+ tv.Redraw (tv.Bounds);
+
+
+ GraphViewTests.AssertDriverContentsAre (
+@"└─pink
+", output);
+ Assert.Equal (-1, tv.IndexOf (n1));
+ Assert.Null (tv.IndexOf (n1_1));
+ Assert.Null (tv.IndexOf (n1_2));
+ Assert.Equal (0, tv.IndexOf (n2));
+ }
+ [Fact, AutoInitShutdown]
public void TestTreeViewColor()
{
var tv = new TreeView{Width = 20,Height = 10};