using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.ComponentModel; using glue.Extensions.Enumerable; using glue.XDag; namespace glue.WpfUtil { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class DagLayoutPanel : Panel { internal partial class LayoutDag : Dag<LayoutDag.Node> { [DebuggerDisplay("{ToString(),nq}")] internal new class Node : Dag<LayoutDag.Node>.Node { static Size infinite_size = new Size(double.PositiveInfinity, double.PositiveInfinity); [DebuggerBrowsable(DebuggerBrowsableState.Never)] Point top_handle; [DebuggerBrowsable(DebuggerBrowsableState.Never)] Point bot_handle; [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly public FrameworkElement fe; public int order; static int i_next = 0; public Rail.SingleNodePos railpos; Size _desired = infinite_size; public Node(LayoutDag ld, FrameworkElement fe) : base(ld) { this.order = i_next++; this.fe = fe; } public bool ChangeParents(IEnumerable<Node> iefe) { bool f_any = false; foreach (Node n in Parents.Except(iefe).ToArray()) { base.RemoveParent(n); f_any = true; } foreach (Node n in iefe.Except(Parents).ToArray()) { base.AddParent(n); f_any = true; } return f_any; } public new LayoutDag Dag { get { return (LayoutDag)base.Dag; } } public FrameworkElement Item { get { return fe; } } IEnumerable<Node> OrderedChildren { get { return Children.OrderBy(n => n.order); } } IEnumerable<Node> OrderedParents { get { return Parents.OrderBy(n => n.order); } } int GetChildIndex(Node child) { return OrderedChildren.IndexOfFirst(n => n == child); } int GetParentIndex(Node parent) { return OrderedParents.IndexOfFirst(n => n == parent); } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Size DesiredSize { get { if (_desired == infinite_size) { fe.Measure(infinite_size); _desired = fe.DesiredSize; } return _desired; } } public bool ReMeasure() { fe.Measure(infinite_size); Size sz = fe.DesiredSize; if (sz.Equals(_desired)) return false; _desired = sz; return true; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Rect Final { get { if (railpos == null) return default(Rect); double ypos = Dag.panel.rails.Take(Level).Sum(r => r.MaxHeight + 30); Rect r_final = new Rect(new Point(railpos.RailCalcs().Left.Value, ypos), DesiredSize); top_handle = r_final.TopLeft; top_handle.X += r_final.Width / 2; bot_handle = r_final.BottomLeft; bot_handle.X += r_final.Width / 2; return r_final; } } public void DoRender(DrawingContext dc, Pen pen, Pen dashpen) { foreach (var cn in Children) { if (!cn.top_handle.Equals(default(Point))) dc.DrawLine(pen, bot_handle, cn.top_handle); } } public override string ToString() { double d1 = railpos == null ? 0 : railpos.RailCalcs().Left.Value; double d2 = railpos == null ? 0 : railpos.RailCalcs().Right.Value; return String.Format("{0:N2}-{1:N2} {2} parents: {3}/{4} children: {5}/{6} {7}", d1, d2, base.ToString(), Parents.Count, AllAncestors.Count, Children.Count, AllDescendants.Count, fe.Name); } public IEnumerable<FrameworkElement> FrameworkElementParents { get { IList rgp = GetDagParents(this.Item); return rgp == null ? Enumerable.Empty<FrameworkElement>() : rgp.OfType<FrameworkElement>(); } set { SetDagParents(this.Item, value.ToArray()); } } }; }; }; }