예제 #1
0
        public static AlignerOptions Options <TItem, TEdge> (this IGraphSceneLayout <TItem, TEdge> layout) where TEdge : IEdge <TItem>, TItem
        {
            var result = new AlignerOptions {
                Dimension  = layout.Dimension,
                Distance   = layout.Distance,
                PointOrder = layout.Dimension == Dimension.X ? PointOrder.XY : PointOrder.YX,
            };

            if (layout.Dimension == Dimension.X)
            {
                result.AlignX = Alignment.Start;
                result.AlignY = layout.Centered ? Alignment.Center : Alignment.Start;
            }
            else
            {
                result.AlignX = layout.Centered ? Alignment.Center : Alignment.Start;
                result.AlignY = Alignment.Start;
            }
            if (layout.Dimension == Dimension.X)
            {
                result.PointOrderDelta = layout.StyleSheet.AutoSize.Width / 2;
            }
            else
            {
                result.PointOrderDelta = layout.StyleSheet.AutoSize.Height / 2;
            }
            return(result);
        }
예제 #2
0
 public AlignerOptions(AlignerOptions other)
 {
     AlignX          = other.AlignX;
     AlignY          = other.AlignY;
     PointOrder      = other.PointOrder;
     PointOrderDelta = other.PointOrderDelta;
     Dimension       = other.Dimension;
     Distance        = other.Distance;
     Collisions      = other.Collisions;
 }
예제 #3
0
        public virtual void OneColumn(IEnumerable <TItem> items, Point at, AlignerOptions options)
        {
            var bounds = new Rectangle(int.MaxValue, int.MaxValue, 0, 0);

            MeasureColumn(items, options, ref bounds);
            if (bounds.Location == new Point(int.MaxValue, int.MaxValue))  // this happens if items have no shape
            {
                bounds.Location = at;
            }
            var locator = new LocateVisitBuilder <TItem>(this.Locator);

            LocateColumn(items, bounds, bounds, ref at, locator, options);
        }
예제 #4
0
        public virtual void OneColumn(IEnumerable <TItem> items, AlignerOptions options)
        {
            var comparer = new PointComparer {
                Order = options.PointOrder, Delta = options.PointOrderDelta
            };
            var colItems = items.OrderBy(item => Locator.GetLocation(item), comparer);
            var bounds   = new Rectangle(int.MaxValue, int.MaxValue, 0, 0);

            MeasureColumn(colItems, options, ref bounds);
            var colPos  = bounds.Location;
            var locator = new LocateVisitBuilder <TItem>(this.Locator);

            LocateColumn(colItems, bounds, bounds, ref colPos, locator, options);
        }
예제 #5
0
        public virtual void Columns(IEnumerable <TItem> items, AlignerOptions options)
        {
            var comparer = new PointComparer {
                Order = options.PointOrder, Delta = options.PointOrderDelta
            };

            var walk = items.Select(item => new { location = comparer.Round(Locator.GetLocation(item)), item });

            var bounds = new Rectangle(int.MaxValue, int.MaxValue, 0, 0);
            var cols   = new Queue <Tuple <IEnumerable <TItem>, Rectangle> >();

            foreach (var col in walk.GroupBy(row => row.location.X).OrderBy(row => row.Key))
            {
                var colItems = col.Select(r => r.item).OrderBy(item => Locator.GetLocation(item).Y);
                cols.Enqueue(MeasureColumn(colItems, options, ref bounds));
            }

            LocateColumns(cols, bounds, options);
        }
예제 #6
0
        public virtual void Columns(TItem root, IEnumerable <TItem> items, AlignerOptions options)
        {
            if (root == null || items == null)
            {
                return;
            }

            var itemCache = new HashSet <TItem>(items);

            if (itemCache.Count == 0)
            {
                return;
            }

            var walk = this.Graph.Walk().DeepWalk(root, 1)
                       .Where(l => !(l.Node is TEdge) && itemCache.Contains(l.Node))
                       .ToArray();

            var bounds = new Rectangle(int.MaxValue, int.MaxValue, 0, 0);

            Columns(walk, ref bounds, options);
        }
예제 #7
0
        public static void FullLayout <TItem, TEdge> (this Aligner <TItem, TEdge> aligner, TItem focused, Point pos, AlignerOptions options, IComparer <TItem> comparer)
            where TEdge : IEdge <TItem>, TItem
        {
            var data   = aligner.GraphScene;
            var shaper = aligner.Shaper;

            var roots = data.Graph.FindRoots(focused);

            if (comparer == null)
            {
                roots = roots
                        .OrderBy(e => shaper.GetShape(e).Location, new PointComparer {
                    Order = options.Dimension == Dimension.X ? PointOrder.Y : PointOrder.X
                });
            }
            else
            {
                roots = roots.OrderBy(e => e, comparer);
            }

            var walk = data.Graph.Walk();

            roots.ForEach(root => {
                var steps = new List <LevelItem <TItem> > ();
                walk.DeepWalk(root, 1)
                .ForEach(l => {
                    if (l.Node is TEdge)
                    {
                        // no need; should be done in aligner.Colomns
                        aligner.Locator.AffectedEdges.Add((TEdge)l.Node);
                    }
                    else
                    {
                        steps.Add(l);
                    }
                });
                var bounds = new Rectangle(pos, Size.Zero);
                aligner.Columns(steps, ref bounds, options);
                pos = options.Dimension == Dimension.X ?
                      new Point(pos.X, pos.Y + bounds.Size.Height + options.Distance.Height) :
                      new Point(pos.X + bounds.Size.Width + options.Distance.Width, pos.Y);
            });
        }
예제 #8
0
 public static void OneColumn <TItem, TEdge> (this Aligner <TItem, TEdge> aligner, IEnumerable <TItem> items, AlignerOptions options) where TEdge : IEdge <TItem>, TItem
 {
     if (items.Count() < 2)
     {
         return;
     }
     aligner.OneColumn(items, aligner.Locator.GetLocation(items.First()), options);
 }
예제 #9
0
 public static void OneColumn <TItem, TEdge> (this Aligner <TItem, TEdge> aligner, IEnumerable <TItem> items, Point at, AlignerOptions options) where TEdge : IEdge <TItem>, TItem
 {
     aligner.OneColumn(items, at, options);
 }
예제 #10
0
 public static void SetOptions <TItem, TEdge> (this IGraphSceneLayout <TItem, TEdge> layout, AlignerOptions options) where TEdge : IEdge <TItem>, TItem
 {
     layout.Dimension = options.Dimension;
     if (options.Distance.IsZero)
     {
         options.Distance = layout.Distance;
     }
     else
     {
         layout.Distance = options.Distance;
     }
     if (options.Dimension == Dimension.X)
     {
         layout.Centered = options.AlignX == Alignment.Center;
     }
     else
     {
         layout.Centered = options.AlignY == Alignment.Center;
     }
 }
예제 #11
0
        public void DequeColumn(Queue <Tuple <IEnumerable <TItem>, Rectangle> > cols, ref Rectangle bounds, AlignerOptions options)
        {
            var rootCol = cols.Dequeue();

            if (options.Dimension == Dimension.X)
            {
                bounds.Location = new Point(
                    bounds.X + rootCol.Item2.Width + options.Distance.Width,
                    bounds.Y - options.AlignY.Delta(bounds.Height, rootCol.Item2.Height));
            }
            else
            {
                bounds.Location = new Point(
                    bounds.X - options.AlignX.Delta(bounds.Width, rootCol.Item2.Width),
                    bounds.Y + rootCol.Item2.Height + options.Distance.Height);
            }
        }
예제 #12
0
        protected virtual void LocateColumn(IEnumerable <TItem> colItems, Rectangle colBounds, Rectangle bounds, ref Point colPos, ILocateVisitBuilder <TItem> locate, AlignerOptions options)
        {
            Func <Point, Point> nextFree = pos =>
                                           options.Collisions.HasFlag(Collisions.PerColumn) ?
                                           NearestNextFreeSpace(pos, colBounds.Size, colItems,
                                                                options.Collisions.HasFlag(Collisions.Toggle), options.Dimension, options.Distance).Location :
                                           pos;

            Action <TItem> visit = null;

            if (options.Dimension == Dimension.X)
            {
                colPos.Y = bounds.Y + options.AlignY.Delta(bounds.Height, colBounds.Height);

                colPos = nextFree(colPos);
                locate.Locate(ref visit,
                              locate.Align(colPos.X, colBounds.Width, options.AlignX, Dimension.X),
                              locate.Location(colPos.Y, options.Distance.Height, Dimension.Y)
                              );
                VisitItems(colItems, visit);

                colPos.X += colBounds.Width + options.Distance.Width;
            }
            else
            {
                colPos.X = bounds.X + options.AlignX.Delta(bounds.Width, colBounds.Width);
                colPos   = nextFree(colPos);

                locate.Locate(ref visit,
                              locate.Location(colPos.X, options.Distance.Width, Dimension.X),
                              locate.Align(colPos.Y, colBounds.Height, options.AlignY, Dimension.Y)

                              );
                VisitItems(colItems, visit);

                colPos.Y += colBounds.Height + options.Distance.Height;
            }
        }
예제 #13
0
        public virtual void Columns(IEnumerable <LevelItem <TItem> > walk, ref Rectangle bounds, AlignerOptions options)
        {
            var cols = MeasureWalk(walk, ref bounds, options);

            LocateColumns(cols, bounds, options);
        }
예제 #14
0
        public virtual Tuple <IEnumerable <TItem>, Rectangle> MeasureColumn(IEnumerable <TItem> colItems, AlignerOptions options, ref Rectangle bounds)
        {
            Action <TItem> visit = null;

            var items = new Queue <TItem>();

            visit += i => items.Enqueue(i);
            AffectedEdges(ref visit);

            var measure = new MeasureVisitBuilder <TItem>(this.Locator);
            var fBounds = measure.Bounds(ref visit);
            var fSize   = measure.SizeToFit(ref visit, options.Distance, options.Dimension);

            VisitItems(colItems, visit);

            var colBounds = fBounds();

            if (colBounds.IsEmpty)
            {
                colBounds.Location = bounds.Location;
            }
            colBounds.Size = fSize();

            bounds.Location = bounds.Location.Min(colBounds.Location);
            bounds.Size     = bounds.Size.SizeToFit(colBounds.Size, options.Dimension);

            return(new Tuple <IEnumerable <TItem>, Rectangle>(items, colBounds));
        }
예제 #15
0
        public virtual void LocateColumn(IEnumerable <TItem> col, Rectangle colBounds, ref Point colPos, AlignerOptions options)
        {
            var locate = new LocateVisitBuilder <TItem> (this.Locator);

            LocateColumn(col, colBounds, new Rectangle(colPos, new Size()), ref colPos, locate, options);
        }
예제 #16
0
        public virtual void LocateColumn(IEnumerable <TItem> col, Rectangle colBounds, Rectangle bounds, AlignerOptions options)
        {
            var colPos = bounds.Location;
            var locate = new LocateVisitBuilder <TItem> (this.Locator);

            LocateColumn(col, colBounds, bounds, ref colPos, locate, options);
        }
예제 #17
0
        public virtual void LocateColumns(Queue <Tuple <IEnumerable <TItem>, Rectangle> > cols, Rectangle bounds, AlignerOptions options)
        {
            var colPos = bounds.Location;
            var locate = new LocateVisitBuilder <TItem>(this.Locator);

            while (cols.Count > 0)
            {
                var col = cols.Dequeue();
                LocateColumn(col.Item1, col.Item2, bounds, ref colPos, locate, options);
            }
        }
예제 #18
0
        public virtual Queue <Tuple <IEnumerable <TItem>, Rectangle> > MeasureWalk(IEnumerable <LevelItem <TItem> > walk, ref Rectangle bounds, AlignerOptions options)
        {
            var colPos = bounds.Location;

            var cols = new Queue <Tuple <IEnumerable <TItem>, Rectangle> >();

            foreach (var col in walk.GroupBy(row => row.Level))
            {
                if (col.Count() == 0)
                {
                    continue;
                }

                var colItems = col.Select(r => r.Node);
                if (options.Dimension == Dimension.X)
                {
                    colItems = colItems.OrderBy(item => Locator.GetLocation(item).Y);
                }
                else
                {
                    colItems = colItems.OrderBy(item => Locator.GetLocation(item).X);
                }

                cols.Enqueue(MeasureColumn(colItems, options, ref bounds));
            }

            if (colPos.X == int.MaxValue && colPos.Y == int.MaxValue)
            {
                colPos = bounds.Location;
            }
            else
            {
                bounds.Location = colPos;
            }

            if (options.Collisions.HasFlag(Collisions.NextFree) && !options.Collisions.HasFlag(Collisions.PerColumn))
            {
                var ignore    = walk.Select(i => i.Node).ToArray();
                var newbounds = NearestNextFreeSpace(bounds.Location, bounds.Size, ignore,
                                                     options.Collisions.HasFlag(Collisions.Toggle), options.Dimension, options.Distance);
                bounds = newbounds;
            }

            return(cols);
        }