mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* touching publish.yml * Moved Examples into ./Examples * Moved Benchmarks into ./Tests * Moved Benchmarks into ./Tests * Moved UICatalog into ./Examples * Moved UICatalog into ./Examples 2 * Moved tests into ./Tests * Updated nuget
328 lines
11 KiB
C#
328 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using Terminal.Gui;
|
|
|
|
namespace UICatalog.Scenarios;
|
|
|
|
[ScenarioMetadata ("Class Explorer", "Tree view explorer for classes by namespace based on TreeView.")]
|
|
[ScenarioCategory ("Controls")]
|
|
[ScenarioCategory ("TreeView")]
|
|
public class ClassExplorer : Scenario
|
|
{
|
|
private MenuItem _highlightModelTextOnly;
|
|
private MenuItem _miShowPrivate;
|
|
private TextView _textView;
|
|
private TreeView<object> _treeView;
|
|
|
|
public override void Main ()
|
|
{
|
|
Application.Init ();
|
|
var top = new Toplevel ();
|
|
|
|
var menu = new MenuBar
|
|
{
|
|
Menus =
|
|
[
|
|
new MenuBarItem ("_File", new MenuItem [] { new ("_Quit", "", () => Quit ()) }),
|
|
new MenuBarItem (
|
|
"_View",
|
|
new []
|
|
{
|
|
_miShowPrivate =
|
|
new MenuItem (
|
|
"_Include Private",
|
|
"",
|
|
() => ShowPrivate ()
|
|
) { Checked = false, CheckType = MenuItemCheckStyle.Checked },
|
|
new ("_Expand All", "", () => _treeView.ExpandAll ()),
|
|
new ("_Collapse All", "", () => _treeView.CollapseAll ())
|
|
}
|
|
),
|
|
new MenuBarItem (
|
|
"_Style",
|
|
new []
|
|
{
|
|
_highlightModelTextOnly = new MenuItem (
|
|
"_Highlight Model Text Only",
|
|
"",
|
|
() => OnCheckHighlightModelTextOnly ()
|
|
) { CheckType = MenuItemCheckStyle.Checked }
|
|
}
|
|
)
|
|
]
|
|
};
|
|
top.Add (menu);
|
|
|
|
var win = new Window
|
|
{
|
|
Title = GetName (),
|
|
Y = Pos.Bottom (menu)
|
|
};
|
|
|
|
_treeView = new TreeView<object> { X = 0, Y = 1, Width = Dim.Percent (50), Height = Dim.Fill () };
|
|
|
|
var lblSearch = new Label { Text = "Search" };
|
|
var tfSearch = new TextField { Width = 20, X = Pos.Right (lblSearch) };
|
|
|
|
win.Add (lblSearch);
|
|
win.Add (tfSearch);
|
|
|
|
TreeViewTextFilter<object> filter = new (_treeView);
|
|
_treeView.Filter = filter;
|
|
|
|
tfSearch.TextChanged += (s, e) =>
|
|
{
|
|
filter.Text = tfSearch.Text;
|
|
|
|
if (_treeView.SelectedObject != null)
|
|
{
|
|
_treeView.EnsureVisible (_treeView.SelectedObject);
|
|
}
|
|
};
|
|
|
|
_treeView.AddObjects (AppDomain.CurrentDomain.GetAssemblies ());
|
|
_treeView.AspectGetter = GetRepresentation;
|
|
_treeView.TreeBuilder = new DelegateTreeBuilder<object> (ChildGetter, CanExpand);
|
|
_treeView.SelectionChanged += TreeView_SelectionChanged;
|
|
|
|
win.Add (_treeView);
|
|
|
|
_textView = new TextView { X = Pos.Right (_treeView), Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
|
|
|
|
win.Add (_textView);
|
|
|
|
top.Add (win);
|
|
|
|
Application.Run (top);
|
|
top.Dispose ();
|
|
Application.Shutdown ();
|
|
}
|
|
|
|
private bool CanExpand (object arg) { return arg is Assembly || arg is Type || arg is ShowForType; }
|
|
|
|
private IEnumerable<object> ChildGetter (object arg)
|
|
{
|
|
try
|
|
{
|
|
if (arg is Assembly a)
|
|
{
|
|
return a.GetTypes ();
|
|
}
|
|
|
|
if (arg is Type t)
|
|
{
|
|
// Note that here we cannot simply return the enum values as the same object cannot appear under multiple branches
|
|
return Enum.GetValues (typeof (Showable))
|
|
.Cast<Showable> ()
|
|
|
|
// Although we new the Type every time the delegate is called state is preserved because the class has appropriate equality members
|
|
.Select (v => new ShowForType (v, t));
|
|
}
|
|
|
|
if (arg is ShowForType show)
|
|
{
|
|
switch (show.ToShow)
|
|
{
|
|
case Showable.Properties:
|
|
return show.Type.GetProperties (GetFlags ());
|
|
case Showable.Constructors:
|
|
return show.Type.GetConstructors (GetFlags ());
|
|
case Showable.Events:
|
|
return show.Type.GetEvents (GetFlags ());
|
|
case Showable.Fields:
|
|
return show.Type.GetFields (GetFlags ());
|
|
case Showable.Methods:
|
|
return show.Type.GetMethods (GetFlags ());
|
|
}
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return Enumerable.Empty<object> ();
|
|
}
|
|
|
|
return Enumerable.Empty<object> ();
|
|
}
|
|
|
|
private BindingFlags GetFlags ()
|
|
{
|
|
if (_miShowPrivate.Checked == true)
|
|
{
|
|
return BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
|
}
|
|
|
|
return BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
|
|
}
|
|
|
|
private string GetRepresentation (object model)
|
|
{
|
|
try
|
|
{
|
|
if (model is Assembly ass)
|
|
{
|
|
return ass.GetName ().Name;
|
|
}
|
|
|
|
if (model is PropertyInfo p)
|
|
{
|
|
return p.Name;
|
|
}
|
|
|
|
if (model is FieldInfo f)
|
|
{
|
|
return f.Name;
|
|
}
|
|
|
|
if (model is EventInfo ei)
|
|
{
|
|
return ei.Name;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ex.Message;
|
|
}
|
|
|
|
return model.ToString ();
|
|
}
|
|
|
|
private void OnCheckHighlightModelTextOnly ()
|
|
{
|
|
_treeView.Style.HighlightModelTextOnly = !_treeView.Style.HighlightModelTextOnly;
|
|
_highlightModelTextOnly.Checked = _treeView.Style.HighlightModelTextOnly;
|
|
_treeView.SetNeedsDraw ();
|
|
}
|
|
|
|
private void Quit () { Application.RequestStop (); }
|
|
|
|
private void ShowPrivate ()
|
|
{
|
|
_miShowPrivate.Checked = !_miShowPrivate.Checked;
|
|
_treeView.RebuildTree ();
|
|
_treeView.SetFocus ();
|
|
}
|
|
|
|
private void TreeView_SelectionChanged (object sender, SelectionChangedEventArgs<object> e)
|
|
{
|
|
object val = e.NewValue;
|
|
object [] all = _treeView.GetAllSelectedObjects ().ToArray ();
|
|
|
|
if (val == null || val is ShowForType)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (all.Length > 1)
|
|
{
|
|
_textView.Text = all.Length + " Objects";
|
|
}
|
|
else
|
|
{
|
|
var sb = new StringBuilder ();
|
|
|
|
// tell the user about the currently selected tree node
|
|
sb.AppendLine (e.NewValue.GetType ().Name);
|
|
|
|
if (val is Assembly ass)
|
|
{
|
|
sb.AppendLine ($"Location:{ass.Location}");
|
|
sb.AppendLine ($"FullName:{ass.FullName}");
|
|
}
|
|
|
|
if (val is PropertyInfo p)
|
|
{
|
|
sb.AppendLine ($"Name:{p.Name}");
|
|
sb.AppendLine ($"Type:{p.PropertyType}");
|
|
sb.AppendLine ($"CanWrite:{p.CanWrite}");
|
|
sb.AppendLine ($"CanRead:{p.CanRead}");
|
|
}
|
|
|
|
if (val is FieldInfo f)
|
|
{
|
|
sb.AppendLine ($"Name:{f.Name}");
|
|
sb.AppendLine ($"Type:{f.FieldType}");
|
|
}
|
|
|
|
if (val is EventInfo ev)
|
|
{
|
|
sb.AppendLine ($"Name:{ev.Name}");
|
|
sb.AppendLine ("Parameters:");
|
|
|
|
foreach (ParameterInfo parameter in ev.EventHandlerType.GetMethod ("Invoke")
|
|
.GetParameters ())
|
|
{
|
|
sb.AppendLine ($" {parameter.ParameterType} {parameter.Name}");
|
|
}
|
|
}
|
|
|
|
if (val is MethodInfo method)
|
|
{
|
|
sb.AppendLine ($"Name:{method.Name}");
|
|
sb.AppendLine ($"IsPublic:{method.IsPublic}");
|
|
sb.AppendLine ($"IsStatic:{method.IsStatic}");
|
|
sb.AppendLine ($"Parameters:{(method.GetParameters ().Any () ? "" : "None")}");
|
|
|
|
foreach (ParameterInfo parameter in method.GetParameters ())
|
|
{
|
|
sb.AppendLine ($" {parameter.ParameterType} {parameter.Name}");
|
|
}
|
|
}
|
|
|
|
if (val is ConstructorInfo ctor)
|
|
{
|
|
sb.AppendLine ($"Name:{ctor.Name}");
|
|
sb.AppendLine ($"Parameters:{(ctor.GetParameters ().Any () ? "" : "None")}");
|
|
|
|
foreach (ParameterInfo parameter in ctor.GetParameters ())
|
|
{
|
|
sb.AppendLine ($" {parameter.ParameterType} {parameter.Name}");
|
|
}
|
|
}
|
|
|
|
_textView.Text = sb.ToString ().Replace ("\r\n", "\n");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_textView.Text = ex.Message;
|
|
}
|
|
|
|
_textView.SetNeedsDraw ();
|
|
}
|
|
|
|
private enum Showable
|
|
{
|
|
Properties,
|
|
Fields,
|
|
Events,
|
|
Constructors,
|
|
Methods
|
|
}
|
|
|
|
private class ShowForType
|
|
{
|
|
public ShowForType (Showable toShow, Type type)
|
|
{
|
|
ToShow = toShow;
|
|
Type = type;
|
|
}
|
|
|
|
public Showable ToShow { get; }
|
|
public Type Type { get; }
|
|
|
|
// Make sure to implement Equals methods on your objects if you intend to return new instances every time in ChildGetter
|
|
public override bool Equals (object obj)
|
|
{
|
|
return obj is ShowForType type && EqualityComparer<Type>.Default.Equals (Type, type.Type) && ToShow == type.ToShow;
|
|
}
|
|
|
|
public override int GetHashCode () { return HashCode.Combine (Type, ToShow); }
|
|
public override string ToString () { return ToShow.ToString (); }
|
|
}
|
|
}
|