TreeViewFileSystem.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. _treeView.TreeBuilder = new DelegateTreeBuilder(
  64. // Determines how to compute children of any given branch
  65. GetChildren,
  66. // 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)
  67. (o)=>o is DirectoryInfo
  68. );
  69. // Determines how to represent objects as strings on the screen
  70. _treeView.AspectGetter = AspectGetter;
  71. }
  72. private void AddSimpleTree ()
  73. {
  74. ClearObjects();
  75. // Set builder to serve children of ITreeNode objects
  76. _treeView.TreeBuilder = new TreeNodeBuilder();
  77. // Add 2 root nodes with simple set of subfolders
  78. _treeView.AddObject(CreateSimpleRoot());
  79. _treeView.AddObject(CreateSimpleRoot());
  80. }
  81. private ITreeNode CreateSimpleRoot ()
  82. {
  83. return new TreeNode("Root"){
  84. Children = new List<ITreeNode>()
  85. {
  86. new TreeNode("Folder_1"){
  87. Children = new List<ITreeNode>()
  88. {
  89. new TreeNode("Folder_1.1"){
  90. Children = new List<ITreeNode>()
  91. {
  92. new TreeNode("File_1.1.1"),
  93. new TreeNode("File_1.1.2")
  94. }},
  95. new TreeNode("Folder_1.2"){
  96. Children = new List<ITreeNode>()
  97. {
  98. new TreeNode("File_1.2.1"),
  99. new TreeNode("File_1.2.2")
  100. }},
  101. new TreeNode("File_1.1")
  102. }},
  103. new TreeNode("Folder_2"){
  104. Children = new List<ITreeNode>()
  105. {
  106. new TreeNode("Folder_2.1"){
  107. Children = new List<ITreeNode>()
  108. {
  109. new TreeNode("File_2.1.1"),
  110. new TreeNode("File_2.1.2")
  111. }},
  112. new TreeNode("Folder_2.2"){
  113. Children = new List<ITreeNode>()
  114. {
  115. new TreeNode("File_2.2.1"),
  116. new TreeNode("File_2.2.2")
  117. }},
  118. new TreeNode("File_2.1")
  119. }},
  120. new TreeNode("Folder_3"){
  121. Children = new List<ITreeNode>()
  122. {
  123. new TreeNode("Folder_3.1"){
  124. Children = new List<ITreeNode>()
  125. {
  126. new TreeNode("File_3.1.1"),
  127. new TreeNode("File_3.1.2")
  128. }},
  129. new TreeNode("Folder_3.2"){
  130. Children = new List<ITreeNode>()
  131. {
  132. new TreeNode("File_3.2.1"),
  133. new TreeNode("File_3.2.2")
  134. }},
  135. new TreeNode("File_3.1")
  136. }}
  137. }
  138. };
  139. }
  140. private void ClearObjects()
  141. {
  142. _treeView.ClearObjects();
  143. }
  144. private void AddRootDrives()
  145. {
  146. SetupFileSystemDelegates();
  147. _treeView.AddObjects(DriveInfo.GetDrives().Select(d=>d.RootDirectory));
  148. }
  149. private void RemoveRoot()
  150. {
  151. if(_treeView.SelectedObject == null)
  152. MessageBox.ErrorQuery(10,5,"Error","No object selected","ok");
  153. else {
  154. _treeView.Remove(_treeView.SelectedObject);
  155. }
  156. }
  157. private IEnumerable<object> GetChildren(object model)
  158. {
  159. // If it is a directory it's children are all contained files and dirs
  160. if(model is DirectoryInfo d) {
  161. try {
  162. return d.GetFileSystemInfos()
  163. //show directories first
  164. .OrderBy(a=>a is DirectoryInfo ? 0:1)
  165. .ThenBy(b=>b.Name);
  166. }
  167. catch(SystemException ex) {
  168. return new []{ex};
  169. }
  170. }
  171. return new object[0];
  172. }
  173. private string AspectGetter(object model)
  174. {
  175. if(model is DirectoryInfo d)
  176. return d.Name;
  177. if(model is FileInfo f)
  178. return f.Name;
  179. return model.ToString();
  180. }
  181. private void Quit ()
  182. {
  183. Application.RequestStop ();
  184. }
  185. }
  186. }