TreeViewFileSystem.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using Terminal.Gui;
  7. namespace UICatalog.Scenarios {
  8. [ScenarioMetadata (Name: "TreeViewFileSystem", Description: "Hierarchical file system explorer based on TreeView")]
  9. [ScenarioCategory ("Controls")]
  10. [ScenarioCategory ("Dialogs")]
  11. [ScenarioCategory ("Text")]
  12. [ScenarioCategory ("Dialogs")]
  13. [ScenarioCategory ("TopLevel")]
  14. class TreeViewFileSystem : Scenario {
  15. TreeView _treeView;
  16. public override void Setup ()
  17. {
  18. Win.Title = this.GetName();
  19. Win.Y = 1; // menu
  20. Win.Height = Dim.Fill (1); // status bar
  21. Top.LayoutSubviews ();
  22. var menu = new MenuBar (new MenuBarItem [] {
  23. new MenuBarItem ("_File", new MenuItem [] {
  24. new MenuItem ("_Quit", "", () => Quit()),
  25. }),
  26. new MenuBarItem ("_View", new MenuItem [] {
  27. new MenuItem ("_ShowLines", "", () => ShowLines()),
  28. }),
  29. });
  30. Top.Add (menu);
  31. var statusBar = new StatusBar (new StatusItem [] {
  32. new StatusItem(Key.F2, "~F2~ Add Root Drives", () => AddRootDrives()),
  33. new StatusItem(Key.F3, "~F3~ Remove Root Object", () => RemoveRoot()),
  34. new StatusItem(Key.F4, "~F4~ Clear Objects", () => ClearObjects()),
  35. new StatusItem(Key.F5, "~F5~ Simple Tree", () => AddSimpleTree()),
  36. new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => Quit()),
  37. });
  38. Top.Add (statusBar);
  39. _treeView = new TreeView () {
  40. X = 0,
  41. Y = 0,
  42. Width = Dim.Fill (),
  43. Height = Dim.Fill (),
  44. };
  45. string root = System.IO.Path.GetPathRoot(Environment.CurrentDirectory);
  46. if(root == null)
  47. {
  48. MessageBox.ErrorQuery(10,5,"Error","Unable to determine file system root","ok");
  49. return;
  50. }
  51. Win.Add (_treeView);
  52. }
  53. private void ShowLines ()
  54. {
  55. _treeView.ShowBranchLines = !_treeView.ShowBranchLines;
  56. _treeView.SetNeedsDisplay();
  57. }
  58. /// <summary>
  59. /// Sets up children getter delegates that return subfolders/files from directories
  60. /// </summary>
  61. private void SetupFileSystemDelegates ()
  62. {
  63. // As a shortcut to enumerating half the file system, tell tree that all directories are expandable (even if they turn out to be empty later on)
  64. _treeView.CanExpandGetter = (o)=>o is DirectoryInfo;
  65. // Determines how to compute children of any given branch
  66. _treeView.ChildrenGetter = GetChildren;
  67. // Determines how to represent objects as strings on the screen
  68. _treeView.AspectGetter = AspectGetter;
  69. }
  70. private void AddSimpleTree ()
  71. {
  72. ClearObjects();
  73. // Clear any previous delegates
  74. _treeView.CanExpandGetter = null;
  75. _treeView.ChildrenGetter = null;
  76. // Add 2 root nodes with simple set of subfolders
  77. _treeView.AddObject(CreateSimpleRoot());
  78. _treeView.AddObject(CreateSimpleRoot());
  79. }
  80. private ITreeNode CreateSimpleRoot ()
  81. {
  82. return new TreeNode("Root"){
  83. Children = new List<ITreeNode>()
  84. {
  85. new TreeNode("Folder_1"){
  86. Children = new List<ITreeNode>()
  87. {
  88. new TreeNode("Folder_1.1"){
  89. Children = new List<ITreeNode>()
  90. {
  91. new TreeNode("File_1.1.1"),
  92. new TreeNode("File_1.1.2")
  93. }},
  94. new TreeNode("Folder_1.2"){
  95. Children = new List<ITreeNode>()
  96. {
  97. new TreeNode("File_1.2.1"),
  98. new TreeNode("File_1.2.2")
  99. }},
  100. new TreeNode("File_1.1")
  101. }},
  102. new TreeNode("Folder_2"){
  103. Children = new List<ITreeNode>()
  104. {
  105. new TreeNode("Folder_2.1"){
  106. Children = new List<ITreeNode>()
  107. {
  108. new TreeNode("File_2.1.1"),
  109. new TreeNode("File_2.1.2")
  110. }},
  111. new TreeNode("Folder_2.2"){
  112. Children = new List<ITreeNode>()
  113. {
  114. new TreeNode("File_2.2.1"),
  115. new TreeNode("File_2.2.2")
  116. }},
  117. new TreeNode("File_2.1")
  118. }},
  119. new TreeNode("Folder_3"){
  120. Children = new List<ITreeNode>()
  121. {
  122. new TreeNode("Folder_3.1"){
  123. Children = new List<ITreeNode>()
  124. {
  125. new TreeNode("File_3.1.1"),
  126. new TreeNode("File_3.1.2")
  127. }},
  128. new TreeNode("Folder_3.2"){
  129. Children = new List<ITreeNode>()
  130. {
  131. new TreeNode("File_3.2.1"),
  132. new TreeNode("File_3.2.2")
  133. }},
  134. new TreeNode("File_3.1")
  135. }}
  136. }
  137. };
  138. }
  139. private void ClearObjects()
  140. {
  141. _treeView.ClearObjects();
  142. }
  143. private void AddRootDrives()
  144. {
  145. SetupFileSystemDelegates();
  146. _treeView.AddObjects(DriveInfo.GetDrives().Select(d=>d.RootDirectory));
  147. }
  148. private void RemoveRoot()
  149. {
  150. if(_treeView.SelectedObject == null)
  151. MessageBox.ErrorQuery(10,5,"Error","No object selected","ok");
  152. else {
  153. _treeView.Remove(_treeView.SelectedObject);
  154. }
  155. }
  156. private IEnumerable<object> GetChildren(object model)
  157. {
  158. // If it is a directory it's children are all contained files and dirs
  159. if(model is DirectoryInfo d) {
  160. try {
  161. return d.GetFileSystemInfos()
  162. //show directories first
  163. .OrderBy(a=>a is DirectoryInfo ? 0:1)
  164. .ThenBy(b=>b.Name);
  165. }
  166. catch(SystemException ex) {
  167. return new []{ex};
  168. }
  169. }
  170. return new object[0];
  171. }
  172. private string AspectGetter(object model)
  173. {
  174. if(model is DirectoryInfo d)
  175. return d.Name;
  176. if(model is FileInfo f)
  177. return f.Name;
  178. return model.ToString();
  179. }
  180. private void Quit ()
  181. {
  182. Application.RequestStop ();
  183. }
  184. }
  185. }