Пример #1
0
        public virtual void LogicalLayoutLeaf(AlignerOptions options)
        {
            OptionsAndLayout(options);
            var display = this.CurrentDisplay;

            if (display != null)
            {
                var selected = display.Data.Selected.Elements;
                var root     = display.Data.Focused;
                if (selected.Count() == 1)
                {
                    var walk = display.Data.Graph.Walk()
                               .DeepWalk(root, 0, Walk.Leafs <IVisual, IVisualEdge> ())
                               .Where(l => !(l.Node is IVisualEdge))
                               .ToArray();

                    var save = options.Collisions;

                    Call(CurrentDisplay, (aligner, items) => {
                        var bounds         = new Rectangle(aligner.Locator.GetLocation(root), aligner.Locator.GetSize(root));
                        options.Collisions = Collisions.None;
                        var cols           = aligner.MeasureWalk(walk, ref bounds, options);
                        aligner.DequeColumn(cols, ref bounds, options);
                        options.Collisions = Collisions.NextFree | Collisions.PerColumn | Collisions.Toggle;
                        aligner.LocateColumns(cols, bounds, options);
                    }
                         , walk.Select(l => l.Node));
                    options.Collisions = save;
                }
            }
        }
Пример #2
0
 public void OneColumn(AlignerOptions options)
 {
     OptionsAndLayout(options);
     options            = new AlignerOptions(options);
     options.PointOrder = options.Dimension == Dimension.X ?
                          PointOrder.YX : PointOrder.XY;
     options.PointOrderDelta = 0;
     Call(CurrentDisplay, (aligner, items) => aligner.OneColumn(items, options));
 }
Пример #3
0
 public virtual void OptionsAndLayout(AlignerOptions options)
 {
     if (CurrentDisplay == null)
     {
         return;
     }
     options.Distance = CurrentDisplay.Layout.Distance;
     // TODO: CurrentDisplay.Layout.SetOptions(options);
 }
Пример #4
0
        public virtual void FullLayout(AlignerOptions options)
        {
            OptionsAndLayout(options);
            var display = this.CurrentDisplay;

            if (display != null)
            {
                display.BackColor = display.StyleSheet.BackColor;
                display.Reset();
                display.BackendRenderer.Render();
            }
        }
Пример #5
0
        public void TestExpand()
        {
            var options = new AlignerOptions {
                AlignX     = Alignment.Start,
                AlignY     = Alignment.Center,
                Dimension  = Dimension.X,
                PointOrder = PointOrder.XY,
            };

            var worker = SceneWorkerWithTestData2(3, options);

            options.Distance = worker.Layout.Distance;

            var origins   = new IVisual [] { worker.Scene.Focused };
            var aligner   = new Aligner <IVisual, IVisualEdge> (worker.Scene, worker.Layout);
            var deep      = false;
            var graphView = worker.Scene.Graph as SubGraph <IVisual, IVisualEdge>;

            var affected = new SubGraphWorker <IVisual, IVisualEdge>
                               (graphView).Expand(origins, deep);

            var walk = graphView.Walk();

            origins.ForEach(origin => {
                var route = (deep ? walk.DeepWalk(origin, 1) : walk.ExpandWalk(origin, 1))
                            .Where(l => !(l.Node is IVisualEdge)).ToArray();
                var bounds         = new Rectangle(aligner.Locator.GetLocation(origin), aligner.Locator.GetSize(origin));
                options.Collisions = Collisions.None;
                var cols           = aligner.MeasureWalk(route, ref bounds, options);
                var removeCol      = cols.Dequeue();

                if (options.Dimension == Dimension.X)
                {
                    var adjust      = options.AlignY.Delta(bounds.Height, removeCol.Item2.Height);
                    bounds.Location = new Point(bounds.X + removeCol.Item2.Width + options.Distance.Width, bounds.Y - adjust);
                }
                else
                {
                    var adjust      = options.AlignX.Delta(bounds.Width, removeCol.Item2.Width);
                    bounds.Location = new Point(bounds.X + adjust, bounds.Y + removeCol.Item2.Height + options.Distance.Height);
                }
                options.Collisions = Collisions.NextFree | Collisions.PerColumn | Collisions.Toggle;
                aligner.LocateColumns(cols, bounds, options);
            });

            aligner.Commit();
            worker.Modeller.Perform();
            worker.Modeller.Finish();

            ReportPainter.PushPaint(ctx => worker.Painter.Paint(ctx));

            WritePainter();
        }
Пример #6
0
        public virtual void LogicalLayout(AlignerOptions options)
        {
            OptionsAndLayout(options);
            var display = this.CurrentDisplay;

            if (display != null)
            {
                var selected = display.Data.Selected.Elements;
                var root     = display.Data.Focused;
                if (selected.Count() == 1)
                {
                    selected = display.Data.Graph.Walk().DeepWalk(root, 0).Select(l => l.Node);
                }
                Call(CurrentDisplay, (aligner, items) => aligner.Columns(root, items, options), selected);
            }
        }
Пример #7
0
 public virtual void Columns(AlignerOptions options)
 {
     OptionsAndLayout(options);
     Call(CurrentDisplay, (aligner, items) => aligner.Columns(items, options));
 }
Пример #8
0
        public override Rectangle AlignByPath <TItem, TEdge> (IEnumerable <LevelItem <TItem> > walk, AlignerOptions options, Aligner <TItem, TEdge> aligner, Point startPoint)
        {
            TrackBounds = new Rectangle [0];

            var tree = new Tree <TItem> ();
            TreeNode <TItem> cursor     = null;
            TreeNode <TItem> pathCursor = null;

            foreach (var step in walk)
            {
                ReportDetail($"{step}");
                if (tree.Head == null)
                {
                    cursor     = tree.AddHead(step.Node);
                    pathCursor = cursor;
                    continue;
                }
                pathCursor = tree.Where(t => t.Value.Equals(step.Path), pathCursor, false).First();
                // TODO: append = false is not working!
                cursor = tree.AddLeaf(step.Node, pathCursor, true);
            }

            ReportDetail($"->\t{nameof(tree)}\t{tree.WhereLoops}");
            foreach (var t in tree)
            {
                ReportDetail($"{t}");
            }
            return(new Rectangle(startPoint, Size.Zero));
        }
Пример #9
0
        protected virtual void Compose()
        {
            var options = new AlignerOptions {
                Dimension       = Dimension.X,
                PointOrderDelta = 40,
                Collisions      = Collisions.NextFree //| Collisions.Toggle
            };

            Action action = () => Columns(options);

            LogicalLayoutLeafCommand = new CommandView {
                Action = (s) => {
                    action = () => LogicalLayoutLeaf(options);
                    action();
                },
                Image       = Iconery.LogicalLayoutLeaf,
                Size        = DefaultSize,
                ToolTipText = "arrange leaf of selected"
            };

            LogicalLayoutCommand = new CommandView {
                Action = (s) => {
                    action = () => LogicalLayout(options);
                    action();
                },
                Image       = Iconery.LogicalLayout,
                Size        = DefaultSize,
                ToolTipText = "arrange siblings of selected"
            };

            FullLayoutCommand = new CommandView {
                Action = (s) => {
                    action = () => FullLayout(options);
                    action();
                },
                Image       = Iconery.FullLayout,
                Size        = DefaultSize,
                ToolTipText = "arrange all"
            };

            ColumnsCommand = new CommandView {
                Action = (s) => {
                    action = () => Columns(options);
                    action();
                },
                Image       = Iconery.ArrageRows,
                Size        = DefaultSize,
                ToolTipText = "arrange in columns"
            };

            OneColumnCommand = new CommandView {
                Action = (s) => {
                    action = () => OneColumn(options);
                    action();
                },
                Image       = Iconery.ArrangeOneRow,
                Size        = DefaultSize,
                ToolTipText = "arrange in one column"
            };

            ArrangeLeftCommand = new CommandView {
                Action = (s) => {
                    options.AlignX = Alignment.Start;
                    action();
                },
                Image       = Iconery.ArrangeLeft,
                Size        = DefaultSize,
                ToolTipText = "align left"
            };

            ArrangeCenterCommand = new CommandView {
                Action = (s) => {
                    options.AlignX = Alignment.Center;
                    action();
                },
                Image       = Iconery.ArrangeCenter,
                Size        = DefaultSize,
                ToolTipText = "align center"
            };

            ArrangeRightCommand = new CommandView {
                Action = (s) => {
                    options.AlignX = Alignment.End;
                    action();
                },
                Image       = Iconery.ArrangeRight,
                Size        = DefaultSize,
                ToolTipText = "align rigth"
            };

            ArrangeTopCommand = new CommandView {
                Action = (s) => {
                    options.AlignY = Alignment.Start;
                    action();
                },
                Image       = Iconery.ArrangeTop,
                Size        = DefaultSize,
                ToolTipText = "align top"
            };

            ArrangeCenterVCommand = new CommandView {
                Action = (s) => {
                    options.AlignY = Alignment.Center;
                    action();
                },
                Image       = Iconery.ArrangeMiddle,
                Size        = DefaultSize,
                ToolTipText = "align middle"
            };

            ArrangeBottomCommand = new CommandView {
                Action = (s) => {
                    options.AlignY = Alignment.End;
                    action();
                },
                Image       = Iconery.ArrangeBottom,
                Size        = DefaultSize,
                ToolTipText = "align bottom"
            };

            DimensionXCommand = new CommandView {
                Action = (s) => {
                    options.Dimension = Dimension.X;
                    action();
                },
                Image       = Iconery.DimensionX,
                Size        = DefaultSize,
                ToolTipText = "arrange left to right"
            };

            DimensionYCommand = new CommandView {
                Action = (s) => {
                    options.Dimension = Dimension.Y;
                    action();
                },
                Image       = Iconery.DimensionY,
                Size        = DefaultSize,
                ToolTipText = "arrange top to bottom"
            };

            UndoCommand = new CommandView {
                Action      = (s) => Undo(),
                Size        = DefaultSize,
                Image       = Iconery.Undo,
                ToolTipText = "undo last arrange"
            };

            var horizontalButton = new ToolbarDropDownButton(ArrangeLeftCommand);

            horizontalButton.AddItems(
                new ToolbarButton(ArrangeCenterCommand)
            {
                ToggleOnClick = horizontalButton
            },
                new ToolbarButton(ArrangeRightCommand)
            {
                ToggleOnClick = horizontalButton
            }
                );

            var verticalButton = new ToolbarDropDownButton(ArrangeTopCommand);

            verticalButton.AddItems(
                new ToolbarButton(ArrangeCenterVCommand)
            {
                ToggleOnClick = verticalButton
            },
                new ToolbarButton(ArrangeBottomCommand)
            {
                ToggleOnClick = verticalButton
            }
                );

            var layoutButton = new ToolbarDropDownButton(LogicalLayoutLeafCommand);

            layoutButton.AddItems(
                new ToolbarButton(LogicalLayoutCommand)
            {
                ToggleOnClick = layoutButton
            },
                new ToolbarButton(ColumnsCommand)
            {
                ToggleOnClick = layoutButton
            },
                new ToolbarButton(OneColumnCommand)
            {
                ToggleOnClick = layoutButton
            },
                new ToolbarButton(FullLayoutCommand)
                );

            var dimensionButton = new ToolbarDropDownButton(DimensionXCommand);

            dimensionButton.AddItems(
                new ToolbarButton(DimensionYCommand)
            {
                ToggleOnClick = dimensionButton
            }
                );

            this.AddItems(
                layoutButton,
                horizontalButton,
                verticalButton,
                dimensionButton,
                new ToolbarButton(UndoCommand),
                new ToolbarSeparator()
                );
        }
Пример #10
0
        public void ShowDir(string path)
        {
            var oldPath = CurrentPath;

            if (path != null)
            {
                this.CurrentPath = path;
                if (!path.EndsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    path += Path.DirectorySeparatorChar;
                }

                try {
                    if (!OS.Mono)
                    {
                        Directory.EnumerateFiles(path);
                    }
                } catch (UnauthorizedAccessException) {
                    CurrentPath = oldPath;
                    return;
                }
            }

            var scene = this.Scene;

            scene.Clear();
            LevelUp = null;
            Root    = null;

            var graph = scene.Graph;

            var isRoot = path == null;

            if (isRoot)
            {
                foreach (var drive in DriveInfo.GetDrives())
                {
                    try {
                        graph.Add(new VisualDir(DriveIcon,
                                                string.Format("{0} ({1})", drive.VolumeLabel, drive.Name)));
                    }
                    catch (Exception ex) {
                    }
                }
            }
            else
            {
                if (ShowCurrent)
                {
                    graph.Add(new Visual <string> (this.CurrentPath)); // (this.CurrentIcon, this.CurrentPath));
                }
                LevelUp = new VisualDir(LevelUpIcon, "..");            //ShowCurrent ? this.CurrentPath : "..");
                graph.Add(LevelUp);

                try {
                    Action <string> addPath = p => {
                        var name = Path.GetFileName(p);
                        graph.Add(new VisualDir(this.FolderIcon, name));
                    };
                    addPath(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyComputer));
                    foreach (var dir in Directory.EnumerateDirectories(path))
                    {
                        addPath(dir);
                    }
                    var pattern = FileFilter ?? "*.*";
                    foreach (var file in Directory.EnumerateFiles(path, pattern))
                    {
                        var name = Path.GetFileName(file);
                        graph.Add(new VisualDir(this.FileIcon, name));
                    }
                } catch (UnauthorizedAccessException ex) {
                    CurrentPath = oldPath;
                    ShowDir(oldPath);
                    return;
                }
            }

            var layout  = Layout;
            var aligner = new Aligner <IVisual, IVisualEdge> (scene, layout);
            var dd      = layout.Distance.Height;
            var options = new AlignerOptions {
                Distance        = new Size(dd, dd),
                AlignX          = Alignment.Start,
                AlignY          = Alignment.Start,
                Dimension       = Dimension.X,
                PointOrderDelta = 1
            };

            aligner.OneColumn(scene.Graph, (Point)layout.Border, options);

            if (LevelUp != null)
            {
                var home = new VisualDir(HomeIcon, "");
                graph.Add(home);
                options.Distance  = new Size(100 * Scale, 0);
                options.Dimension = Dimension.Y;
                options.AlignY    = Alignment.End;
                aligner.Locator.SetLocation(home, new Point(int.MaxValue, int.MaxValue));
                aligner.OneColumn(new IVisual[] { LevelUp, home }, options);
            }
            aligner.Locator.Commit(scene.Requests);
        }
Пример #11
0
        protected GraphSceneContextVisualizer <IVisual, IVisualEdge> SceneWorkerWithTestData2(int exampleNr, AlignerOptions options)
        {
            var worker = SceneWorkerWithTestData(exampleNr, options);
            var scene  = worker.Scene;

            var scene2 = SceneWithTestData(exampleNr);

            var view   = scene.Graph as SubGraph <IVisual, IVisualEdge>;
            var graph  = view.Source;
            var graph2 = (scene2.Graph as SubGraph <IVisual, IVisualEdge>).Source;

            graph2.Where(e => e is Visual <string>).ForEach(e => { e.Data += "1"; });

            var root = scene.Focused;

            var root2 = graph2.FindRoots(null).First();

            graph2.Elements().ForEach(e => graph.Add(e));
            view.Add(root2);
            new Aligner <IVisual, IVisualEdge> (scene, worker.Layout, p => p.OneColumn(new IVisual [] { root, root2 }, options));

            scene.Focused = root2;

            worker.Modeller.Perform();
            worker.Modeller.Finish();
            return(worker);
        }
Пример #12
0
        protected GraphSceneContextVisualizer <IVisual, IVisualEdge> SceneWorkerWithTestData(int exampleNr, AlignerOptions options, int count = 1)
        {
            var scene = SceneWithTestData(exampleNr, count);

            var worker = new GraphSceneContextVisualizer <IVisual, IVisualEdge> ();

            worker.Compose(scene, new VisualsRenderer());
            worker.StyleSheet.BackColor = Colors.WhiteSmoke;
            worker.Layout.SetOptions(options);
            worker.Folder.ShowAllData();
            worker.Modeller.Perform();
            worker.Modeller.Finish();

            scene.Focused = scene.Graph.FindRoots(null).First();
            return(worker);
        }
Пример #13
0
        protected Rectangle ReportExtent(IEnumerable <IVisual> elms, ILocator <IVisual> locator, AlignerOptions options)
        {
            var measure            = new MeasureVisitBuilder <IVisual> (locator);
            Action <IVisual> visit = null;
            var fSizeToFit         = measure.SizeToFit(ref visit, options.Distance, options.Dimension);
            var fBounds            = measure.Bounds(ref visit);
            var fMinSize           = measure.MinSize(ref visit);

            elms.ForEach(e => visit(e));
            ReportDetail("Bounds {1}\tSizeToFit {0}\tMinSize  {2}", fSizeToFit(), fBounds(), fMinSize());
            return(fBounds());
        }
Пример #14
0
 protected void ReportOptions(AlignerOptions options)
 {
     ReportDetail("Options\t.Distance {0}", options.Distance);
 }
Пример #15
0
 protected void ReportElems(IGraphScene <IVisual, IVisualEdge> scene, IEnumerable <IVisual> elms, ILocator <IVisual> locator, AlignerOptions options)
 {
     elms
     .OrderBy(e => locator.GetLocation(e), new PointComparer {
         Delta = options.Distance.Width, Order = options.PointOrder
     })
     .ForEach(e => ReportDetail("\t{3}{0}\t{1}\t{2}", e.Data, locator.GetLocation(e), locator.GetSize(e), scene.Focused == e ? "*" : ""));
 }
Пример #16
0
        public void TestCollisions0()
        {
            var options = new AlignerOptions {
                AlignX     = Alignment.Start,
                AlignY     = Alignment.Center,
                Dimension  = Dimension.X,
                PointOrder = PointOrder.XY
            };

            var worker = SceneWorkerWithTestData2(0, options);

            options.Distance = worker.Layout.Distance;

            var scene = worker.Scene;

            ILocator <IVisual> locator = new GraphSceneItemShapeLocator <IVisual, IVisualEdge> {
                GraphScene = scene
            };


            Action <IEnumerable <IVisual> >         reportElems  = elms => ReportElems(scene, elms, locator, options);
            Func <IEnumerable <IVisual>, Rectangle> reportExtent = elms => ReportExtent(elms, locator, options);

            var visibleItems  = new HashSet <IVisual> (scene.Elements.Where(e => !(e is IVisualEdge)));
            var visibleBounds = locator.Bounds(visibleItems);

            reportElems(visibleItems);
            reportExtent(visibleItems);


            IEnumerable <IVisual> itemsToPlace = ((scene.Graph as SubGraph <IVisual, IVisualEdge>).Source).Walk()
                                                 .DeepWalk(scene.Focused, 0)
                                                 .Select(l => l.Node)
                                                 .ToArray();

            scene.Focused.Location = Point.Zero + worker.Layout.Distance;
            itemsToPlace.ForEach(e => scene.Graph.Add(e));

            itemsToPlace = itemsToPlace.Where(e => !(e is IVisualEdge));
            var aligner = new Aligner <IVisual, IVisualEdge> (scene, worker.Layout);

            aligner.Columns(scene.Focused, itemsToPlace, options);
            locator = aligner.Locator;
            reportElems(itemsToPlace);
            var bounds = reportExtent(itemsToPlace);
            var free   = aligner.NextFreeSpace(bounds.Location, bounds.Size, itemsToPlace, options.Dimension, options.Distance);

            ReportDetail("Next free space {0}", free);
            var free2 = aligner.NearestNextFreeSpace(bounds.Location, bounds.Size, itemsToPlace, false, options.Dimension, options.Distance);

            ReportDetail("Nearest Next free space {0}", free);

            var dist = new Size(bounds.Location.X - free2.Location.X, bounds.Location.Y - free2.Location.Y);

            itemsToPlace.ForEach(e => aligner.Locator.SetLocation(e, aligner.Locator.GetLocation(e) - dist));

            aligner.Commit();
            worker.Modeller.Perform();
            worker.Modeller.Finish();

            ReportPainter.PushPaint(ctx => worker.Painter.Paint(ctx));

            ReportPainter.PushPaint(ctx => {
                var translate = worker.Painter.Viewport.ClipOrigin;
                ctx.Save();
                ctx.Translate(-translate.X, -translate.Y);
                ctx.SetLineWidth(.5);
                ctx.SetColor(Colors.Black);
                ctx.Rectangle(visibleBounds);
                ctx.Stroke();
                ctx.SetColor(Colors.Red);
                ctx.Rectangle(bounds);
                ctx.Stroke();

                ctx.SetColor(Colors.Green);
                ctx.Rectangle(free);
                ctx.Stroke();

                ctx.SetColor(Colors.LawnGreen);
                ctx.Rectangle(free2);
                ctx.Stroke();
                ctx.Restore();
                ctx.SetColor(Colors.White);
            });

            WritePainter();
        }
Пример #17
0
        public void BlockAlgin()
        {
            var options = new AlignerOptions {
                AlignX     = Alignment.Start,
                AlignY     = Alignment.Start,
                Dimension  = Dimension.X,
                PointOrder = PointOrder.XY,
                Collisions = Collisions.None,
            };

            var scene = SceneWithTestData(3, 1);

            var worker = new GraphSceneContextVisualizer <IVisual, IVisualEdge> ();

            worker.Compose(scene, new VisualsRenderer());
            worker.StyleSheet.BackColor = Colors.WhiteSmoke;
            worker.Layout.SetOptions(options);

            worker.Folder.AddRaw(scene.Graph.RootSource()?.Source);
            worker.Modeller.Perform();
            worker.Modeller.Finish();

            var origins = scene.Graph.FindRoots(null);

            scene.Focused = origins.First();

            options.Distance = worker.Layout.Distance;
            var visualComparer = new VisualComparer();
            var aligner        = new Aligner <IVisual, IVisualEdge> (worker.Scene, worker.Layout);

            var graphView = worker.Scene.Graph as SubGraph <IVisual, IVisualEdge>;

            graphView.Edges().ForEach(e => e.Data = "");

            // var roots = new IVisual [] { worker.Scene.Focused };

            var walk = new Walker1 <IVisual, IVisualEdge> (graphView);

            //walk.Trace = true;
            walk.Comparer = visualComparer;

            var startPoint = (Point)worker.Layout.Border;

            foreach (var origin in origins)
            {
                ReportDetail($"-> {origin}\t{startPoint}");
                var bounds = AlignByPath(walk.DeepWalk(origin, 1, null, false), options, aligner, startPoint);
                startPoint.Y += bounds.Height + options.Distance.Height;
            }

            aligner.Commit();
            worker.Modeller.Perform();
            worker.Modeller.Finish();

            ReportPainter.PushPaint(ctx => worker.Painter.Paint(ctx));
            foreach (var r in TrackBounds.Where(r => !r.IsEmpty))
            {
                ReportPainter.PushPaint(ctx => {
                    var translate = worker.Painter.Viewport.ClipOrigin;
                    ctx.Save();
                    ctx.Translate(-translate.X, -translate.Y);

                    ctx.SetColor(Colors.Red);
                    ctx.SetLineWidth(0.5);
                    ctx.SetLineDash(0, 2, 5);
                    ctx.Rectangle(r);
                    ctx.ClosePath();
                    ctx.Stroke();
                    ctx.Restore();
                });
            }
            WritePainter();
        }
Пример #18
0
        public virtual Rectangle AlignByPath <TItem, TEdge> (IEnumerable <LevelItem <TItem> > walk, AlignerOptions options, Aligner <TItem, TEdge> aligner, Point startPoint)
            where TEdge : IEdge <TItem>, TItem
        {
            var bounds = new Rectangle(startPoint, Size.Zero);

            // contains levelitems with backtracked path
            var trackedSteps = new Dictionary <TItem, LevelItem <TItem> > ();

            // used to backtrack path
            var steps = new Dictionary <TItem, LevelItem <TItem> > ();

            var trackBounds      = new Dictionary <TItem, Rectangle> ();
            var trackBoundsToken = new HashSet <TItem> ();

            Func <TItem, TEdge> asEdge = node => node is TEdge ? (TEdge)node : default(TEdge);

            Func <TItem, bool> isVisibleNode = node => !(node is TEdge);

            Func <LevelItem <TItem>, TItem> findPath = step => {
                var visibleNode = isVisibleNode(step.Node);

                while (step.Path != null)
                {
                    if (isVisibleNode(step.Path))
                    {
                        return(step.Path);
                    }

                    if ((step.Node as IEdge <TItem>).IsEdgeOfEdges())
                    {
                        return(step.Path);
                    }

                    if ((step.Path as IEdge <TItem>).IsEdgeOfEdges())
                    {
                        return(step.Path);
                    }


                    if (step.StepIsEdgeToEdge() && visibleNode)
                    {
                        return(step.Node);
                    }

                    if (trackBounds.ContainsKey(step.Path))
                    {
                        return(step.Path);
                    }

                    step = steps [step.Path];
                }

                TrackBounds = trackBounds.Values;
                return(step.Path);
            };

            // steps up the paths and sums the size of trackBounds
            Action <LevelItem <TItem>, Rectangle> sumTrackBounds = (trackedStep, trackBound) => {
                var adjDimension = options.Dimension.Adjacent();
                while (trackedStep.Path != null)
                {
                    var trackStep = trackedSteps [trackedStep.Path];

                    if (trackStep.Path != null)
                    {
                        var backTrackBound = trackBounds [trackStep.Path].MaxExtend(trackBound, adjDimension);
                        trackBounds [trackStep.Path] = backTrackBound;
                        trackBound = backTrackBound;
                    }
                    trackedStep = trackStep;
                }
            };

            // gets the trackBounds of the trackedStep.Path; ensures that the path has trackBounds
            Func <LevelItem <TItem>, Rectangle, Rectangle> getTrackBounds = (trackedStep, trackBound) => {
                while (trackedStep.Path != null)
                {
                    var gb = new Rectangle();
                    if (trackBounds.TryGetValue(trackedStep.Path, out gb))
                    {
                        return(gb);
                    }
                    else
                    {
                        // TODO: ensure that all paths have trackBounds, not only the first uppath
                        var trackStep = trackedSteps [trackedStep.Path];
                        if (trackStep.Path != null)
                        {
                            var backTrackBound = trackBounds [trackStep.Path];
                            trackBound.X = backTrackBound.Right;
                            trackBound.Y = backTrackBound.Bottom;
                        }
                        trackBounds [trackedStep.Path] = trackBound;
                        break;
                    }
                }
                return(trackBound);
            };


            foreach (var step in walk)
            {
                steps.Add(step.Node, step);

                var visibleNode = isVisibleNode(step.Node);
                var nonAdjacent = !step.StepIsAdjacent();

                var isStepEdgeToEdge  = step.StepIsEdgeToEdge();
                var isNodeEdgeOfEdges = (step.Node as IEdge <TItem>).IsEdgeOfEdges();

                var trackedStep = new LevelItem <TItem> (step.Node, findPath(step), step.Level);
                trackedSteps [step.Node] = trackedStep;
                ReportDetail($"\t{trackedStep}");

                if (!(visibleNode || isStepEdgeToEdge))
                {
                    continue;
                }

                var gb = new Rectangle(startPoint, options.Distance.InitSum(options.Dimension));

                var trackBound = new Rectangle(startPoint, new Size());
                if (trackedStep.Path != null)
                {
                    trackBound = getTrackBounds(trackedStep, gb);
                    gb.X       = trackBound.Right;
                    gb.Y       = trackBound.Bottom;
                }

                if (isStepEdgeToEdge)
                {
                    trackBounds [step.Node] = new Rectangle(gb.Location, new Size());
                    ReportDetail($"{step.Node}\t{trackBounds [step.Node]}\t{trackedStep.Path}\t{trackBound}");
                }

                if (visibleNode)
                {
                    var loc        = gb.Location;
                    var nodeBounds = aligner.MeasureItem(step.Node, options.Dimension, options.Distance, ref gb);
                    nodeBounds.Location = gb.Location.Max(loc);

                    aligner.Locator.SetLocation(step.Node, nodeBounds.Location);

                    trackBounds [step.Node] = new Rectangle(nodeBounds.Location, gb.Size.InitSum(options.Dimension));

                    if (trackedStep.Path != null)
                    {
                        trackBound.Size = trackBound.Size.SumSize(nodeBounds.Size + options.Distance, options.Dimension.Adjacent());
                        trackBounds [trackedStep.Path] = trackBound;
                        trackBoundsToken.Add(trackedStep.Path);
                    }

                    ReportDetail($"{step.Node}\t{nodeBounds}\t{trackedStep.Path}\t{trackBound}");
                }

                sumTrackBounds(trackedStep, trackBound);
            }

            // aligns

            foreach (var trackBound in trackBounds.ToArray())
            {
                if (trackBound.Value.Width == 0)
                {
                    trackBounds [trackBound.Key] = new Rectangle(trackBound.Value.Location, new Size(options.Distance.Width / 2, trackBound.Value.Height));
                }
            }
            foreach (var kvp in trackBounds.ToArray())
            {
                var step = trackedSteps [kvp.Key];
                if (step.Path == null)
                {
                    continue;
                }
                var lbounds = kvp.Value;
                var sum     = 0d;
                while (step.Path != null)
                {
                    var trackBound = trackBounds [step.Path];
                    sum  = Math.Max(trackBound.Right, sum);
                    step = trackedSteps [step.Path];
                }
                if (lbounds.X != sum)
                {
                    trackBounds [kvp.Key] = new Rectangle(new Point(sum, lbounds.Y), lbounds.Size);
                }
            }

            Action <TItem> visitMeasure = null;
            var            measure      = new MeasureVisitBuilder <TItem> (aligner.Locator);
            var            fBounds      = measure.Bounds(ref visitMeasure);

            foreach (var step in trackedSteps.Values.Where(l => !(l.Node is TEdge)))
            {
                var nodeBounds = trackBounds [step.Node];
                var loc        = aligner.Locator.GetLocation(step.Node);
                var size       = aligner.Locator.GetSize(step.Node);

                if (options.Dimension == Dimension.X)
                {
                    if (nodeBounds.Height != 0)
                    {
                        loc.Y += options.AlignY.Delta(nodeBounds.Height - options.Distance.Height, size.Height);;
                    }
                    loc.X = nodeBounds.X;
                }
                else
                {
                    if (nodeBounds.Width != 0)
                    {
                        loc.X += options.AlignX.Delta(nodeBounds.Width - options.Distance.Width, size.Width);
                    }
                    loc.Y = nodeBounds.Y;
                }


                aligner.Locator.SetLocation(step.Node, loc);

                visitMeasure(step.Node);
            }

            bounds = fBounds();
            return(bounds);
        }
Пример #19
0
        public virtual void SetDocument(GraphCursor <IVisual, IVisualEdge> source)
        {
            var pagesDisplay = this.PagesDisplay;

            // bring the docpages into view:
            var docManager = new DigidocViz();
            var pageScene  = new Scene();

            pagesDisplay.Data = pageScene;

            var doc = source.Graph.ThingOf(source.Cursor);
            IGraph <IVisual, IVisualEdge> targetGraph = null;

            targetGraph = Mesh.CreateSinkGraph(source.Graph);

            pageScene.Graph = targetGraph;

            Mesh.AddScene(pageScene);

            var targetDocument = targetGraph.VisualOf(doc);

            this.DocumentVisual = targetDocument;

            // get the pages and add them to scene:
            var pages = docManager.Pages(targetGraph, targetDocument).OrderBy(e => e, new VisualComparer()).ToList();

            pages.ForEach(page => pagesDisplay.Data.Add(page));

            var distance = pagesDisplay.Layout.Distance;

            pagesDisplay.Layout.Border = this.Border;

            var aligner = new Aligner <IVisual, IVisualEdge> (pagesDisplay.Data, pagesDisplay.Layout);
            var dd      = this.Border.Height;
            var options = new AlignerOptions {
                Distance        = new Size(dd, dd),
                AlignX          = Alignment.End,
                AlignY          = Alignment.Start,
                Dimension       = Dimension.X,
                PointOrderDelta = 1
            };

            aligner.OneColumn(pages, (Point)this.Border, options);
            aligner.Locator.Commit(aligner.GraphScene.Requests);

            new State {
                Hollow = true
            }.CopyTo(pagesDisplay.State);
            pagesDisplay.Text = source.Cursor.Data == null ? CommonSchema.NullString : source.Cursor.Data.ToString();
            pagesDisplay.Viewport.Reset();
            pagesDisplay.BackendRenderer.Render();

            // show first page:
            var firstPage = pages.FirstOrDefault();

            if (firstPage != null)
            {
                pageScene.Focused = firstPage;
                pagesDisplay.OnSceneFocusChanged();
            }
            pagesDisplay.Perform();

            var pageCache  = new Set <IVisual> (pages);
            var moveResize = pagesDisplay.ActionDispatcher.GetAction <GraphItemMoveResizeAction <IVisual, IVisualEdge> > ();

            moveResize.FocusFilter = e => pageCache.Contains(e) ? null : e;
        }
Пример #20
0
        public void TestShowAllData()
        {
            var options = new AlignerOptions {
                AlignX     = Alignment.Center,
                AlignY     = Alignment.Start,
                Dimension  = Dimension.X,
                PointOrder = PointOrder.XY,
                //Collisions = Collisions.NextFree
            };

            var scene     = SceneWithTestData(0);
            var graphView = scene.Graph as SubGraph <IVisual, IVisualEdge>;
            var graph     = graphView.Source;

            for (int i = 1; i < 6; i++)
            {
                (SceneWithTestData(i).Graph as SubGraph <IVisual, IVisualEdge>)
                .Source.ForEach(item => graph.Add(item));
            }

            var worker = new GraphSceneContextVisualizer <IVisual, IVisualEdge> ();

            worker.Compose(scene, new VisualsRenderer());
            worker.StyleSheet.BackColor = Colors.WhiteSmoke;
            worker.Layout.SetOptions(options);
            options.Distance = worker.Layout.Distance;

            Action allData = () => {
                var roots = new Queue <IVisual> (graph.FindRoots(null));

                var walk = graph.Walk();

                roots.ForEach(root => walk.DeepWalk(root, 0).ForEach(item => graphView.Sink.Add(item.Node)));

                walk = graphView.Walk();

                var aligner = new Aligner <IVisual, IVisualEdge> (scene, worker.Layout);
                //var bounds = new Rectangle(worker.Layout.Border.Width, worker.Layout.Border.Height, 0, 0);
                var pos = new Point(worker.Layout.Border.Width, worker.Layout.Border.Height);
                roots.ForEach(root => {
                    var steps  = walk.DeepWalk(root, 1).Where(l => !(l.Node is IVisualEdge)).ToArray();
                    var bounds = new Rectangle(pos, Size.Zero);
                    var cols   = aligner.MeasureWalk(steps, ref bounds, options);
                    //bounds = aligner.NextFreeSpace(bounds.Location, bounds.Size, walk.Select(t => t.Node), Dimension.Y, options.Distance);
                    pos = new Point(pos.X, pos.Y + bounds.Size.Height + options.Distance.Height);
                    aligner.LocateColumns(cols, bounds, options);
                    //bounds.Top = bounds.Bottom + options.Distance.Height;
                });

                aligner.Commit();
                worker.Modeller.Perform();
                worker.Modeller.Finish();
            };

            allData();
            allData();

            ReportPainter.PushPaint(ctx => worker.Painter.Paint(ctx));

            WritePainter();
        }