using System; using System.Collections.Generic; using System.Linq; namespace Terminal.Gui { /// /// Interface for supplying data to a on demand as root level nodes /// are expanded by the user /// public interface ITreeBuilder { /// /// Returns true if is implemented by this class /// /// bool SupportsCanExpand { get; } /// /// Returns true/false for whether a model has children. This method should be implemented /// when is an expensive operation otherwise /// should return false (in which case this method will not /// be called) /// /// Only implement this method if you have a very fast way of determining whether /// an object can have children e.g. checking a Type (directories can always be expanded) /// /// /// bool CanExpand (T toExpand); /// /// Returns all children of a given which should be added to the /// tree as new branches underneath it /// /// /// IEnumerable GetChildren (T forObject); } /// /// Abstract implementation of . /// public abstract class TreeBuilder : ITreeBuilder { /// public bool SupportsCanExpand { get; protected set; } = false; /// /// Override this method to return a rapid answer as to whether /// returns results. If you are implementing this method ensure you passed true in base /// constructor or set /// /// /// public virtual bool CanExpand (T toExpand) { return GetChildren (toExpand).Any (); } /// public abstract IEnumerable GetChildren (T forObject); /// /// Constructs base and initializes /// /// Pass true if you intend to /// implement otherwise false public TreeBuilder (bool supportsCanExpand) { SupportsCanExpand = supportsCanExpand; } } /// /// implementation for objects /// public class TreeNodeBuilder : TreeBuilder { /// /// Initialises a new instance of builder for any model objects of /// Type /// public TreeNodeBuilder () : base (false) { } /// /// Returns from /// /// /// public override IEnumerable GetChildren (ITreeNode model) { return model.Children; } } /// /// Implementation of that uses user defined functions /// public class DelegateTreeBuilder : TreeBuilder { private Func> childGetter; private Func canExpand; /// /// Constructs an implementation of that calls the user /// defined method to determine children /// /// /// public DelegateTreeBuilder (Func> childGetter) : base (false) { this.childGetter = childGetter; } /// /// Constructs an implementation of that calls the user /// defined method to determine children /// and to determine expandability /// /// /// /// public DelegateTreeBuilder (Func> childGetter, Func canExpand) : base (true) { this.childGetter = childGetter; this.canExpand = canExpand; } /// /// Returns whether a node can be expanded based on the delegate passed during construction /// /// /// public override bool CanExpand (T toExpand) { return canExpand?.Invoke (toExpand) ?? base.CanExpand (toExpand); } /// /// Returns children using the delegate method passed during construction /// /// /// public override IEnumerable GetChildren (T forObject) { return childGetter.Invoke (forObject); } } }