Example #1
0
        private Microsoft.Msagl.Core.Layout.LayoutAlgorithmSettings GivePresetSettings(int i)
        {
            if (i == 0)
            {
                var settings = new Microsoft.Msagl.Layout.Layered.SugiyamaLayoutSettings();
                return(settings);
            }

            if (i == 1)
            {
                var settings = new Microsoft.Msagl.Layout.Incremental.FastIncrementalLayoutSettings();
                settings.RepulsiveForceConstant = 1.0;
                return(settings);
            }

            if (i == 2)
            {
                var settings = new Microsoft.Msagl.Layout.Incremental.FastIncrementalLayoutSettings();
                settings.RepulsiveForceConstant = 30.0;
                return(settings);
            }

            if (i == 3)
            {
                var settings = new Microsoft.Msagl.Layout.Incremental.FastIncrementalLayoutSettings();
                settings.RepulsiveForceConstant = 100.0;
                return(settings);
            }

            return(null);
        }
Example #2
0
        private void LayoutLinkedShapes(Graph graph, out Microsoft.Msagl.Core.Layout.GeometryGraph geometry)
        {
            var geomGraph      = new Microsoft.Msagl.Core.Layout.GeometryGraph();
            var layoutSettings = new Microsoft.Msagl.Layout.Layered.SugiyamaLayoutSettings();

            Microsoft.Msagl.Core.Layout.Node EnsureNode(Node node)
            {
                var res = geomGraph.Nodes.FirstOrDefault(n => n.UserData == node);

                if (res == null)
                {
                    var geomNode = new Microsoft.Msagl.Core.Layout.Node(
                        Microsoft.Msagl.Core.Geometry.Curves.CurveFactory.CreateRectangle(
                            ShapeSize,
                            ShapeSize,
                            new Microsoft.Msagl.Core.Geometry.Point()
                            ),
                        node
                        );

                    geomGraph.Nodes.Add(geomNode);

                    return(geomNode);
                }

                return(res);
            }

            foreach (var l in graph.Links)
            {
                var n1 = EnsureNode(l.Node1);
                var n2 = EnsureNode(l.Node2);
                var e  = new Microsoft.Msagl.Core.Layout.Edge(n1, n2);
                geomGraph.Edges.Add(e);
            }

            LayoutHelpers.CalculateLayout(geomGraph, layoutSettings, null);

            foreach (var kv in nodesAndShapes)
            {
                var pos = geomGraph.Nodes.FirstOrDefault(n => n.UserData == kv.Key)?.Center;
                if (pos.HasValue)
                {
                    kv.Value.X = (int)pos.Value.X + ShapeSize;
                    kv.Value.Y = Diagram.Height - (int)pos.Value.Y + ShapeSize / 2;
                }
            }

            geometry = geomGraph;
        }
Example #3
0
        private MSAGL.Core.Layout.GeometryGraph CreateMsaglGraph(DirectedGraphLayout layout_diagram)
        {
            var mg_graph = new MSAGL.Core.Layout.GeometryGraph();

            // Create the nodes in MSAGL
            foreach (var layout_shape in layout_diagram.Shapes)
            {
                var nodesize       = this.ToMGCoordinates(layout_shape.Size ?? this.LayoutOptions.DefaultShapeSize);
                var node_user_data = new NodeUserData(layout_shape.ID, layout_shape);
                var center         = new MSAGL.Core.Geometry.Point();
                var rectangle      = MSAGL.Core.Geometry.Curves.CurveFactory.CreateRectangle(nodesize.Width, nodesize.Height, center);
                var mg_node        = new MSAGL.Core.Layout.Node(rectangle, node_user_data);
                mg_graph.Nodes.Add(mg_node);
            }

            this.validate_connectors(layout_diagram);

            var mg_coordinates = this.ToMGCoordinates(this.DefaultBezierConnectorLabelBoxSize);

            var map_id_to_ud = new Dictionary <string, MSAGL.Core.Layout.Node>();

            foreach (var n in mg_graph.Nodes)
            {
                var ud = (NodeUserData)n.UserData;
                if (ud != null)
                {
                    map_id_to_ud[ud.ID] = n;
                }
            }

            // Create the MG Connectors
            foreach (var layout_connector in layout_diagram.Connectors)
            {
                if (layout_connector.From == null)
                {
                    throw new ArgumentException("Connector's From node is null");
                }

                if (layout_connector.To == null)
                {
                    throw new ArgumentException("Connector's To node is null");
                }

                var from_node = map_id_to_ud[layout_connector.From.ID];
                var to_node   = map_id_to_ud[layout_connector.To.ID];

                var new_edge = new MSAGL.Core.Layout.Edge(from_node, to_node);
                // TODO: MSAGL
                //new_edge.ArrowheadAtTarget = false;
                new_edge.UserData = new NodeUserData(layout_connector.ID, layout_connector);
                mg_graph.Edges.Add(new_edge);

                new_edge.Label = new MSAGL.Core.Layout.Label(mg_coordinates.Width, mg_coordinates.Height, new_edge);
            }

            var geom_graph_components = MSAGL.Core.Layout.GraphConnectedComponents.CreateComponents(mg_graph.Nodes, mg_graph.Edges);
            var settings = new MSAGL.Layout.Layered.SugiyamaLayoutSettings();

            foreach (var subgraph in geom_graph_components)
            {
                var layout = new Microsoft.Msagl.Layout.Layered.LayeredLayout(subgraph, settings);
                subgraph.Margins = settings.NodeSeparation / 2;
                layout.Run();
            }

            // Pack the graphs using Golden Aspect Ratio
            MSAGL.Layout.MDS.MdsGraphLayout.PackGraphs(geom_graph_components, settings);

            //Update the graphs bounding box
            mg_graph.UpdateBoundingBox();

            this._mg_bb = new VA.Drawing.Rectangle(
                mg_graph.BoundingBox.Left,
                mg_graph.BoundingBox.Bottom,
                mg_graph.BoundingBox.Right,
                mg_graph.BoundingBox.Top);

            this._layout_bb = new VA.Drawing.Rectangle(0, 0, this._mg_bb.Width, this._mg_bb.Height)
                              .Multiply(this.ScaleToDocument, this.ScaleToDocument);

            return(mg_graph);
        }
Example #4
0
            protected override void OnValueChanged(ModelRoot element, LayoutAlgorithm oldValue, LayoutAlgorithm newValue)
            {
                base.OnValueChanged(element, oldValue, newValue);

                if (!element.Store.InUndoRedoOrRollback)
                {
                    // if this is the first time we've been here, cache what's alread there
                    if (oldValue != LayoutAlgorithm.Default && !settingsCache.ContainsKey(oldValue) && element.LayoutAlgorithmSettings != null)
                    {
                        settingsCache[oldValue] = element.LayoutAlgorithmSettings;
                    }

                    // use the prior settings for this layout type if available
                    if (newValue != LayoutAlgorithm.Default && settingsCache.ContainsKey(newValue))
                    {
                        element.LayoutAlgorithmSettings = settingsCache[newValue];
                    }
                    else
                    {
                        // if not, set some defaults that make sense in our context
                        switch (newValue)
                        {
                        case LayoutAlgorithm.Default:
                            element.LayoutAlgorithmSettings = null;
                            return;

                        case LayoutAlgorithm.FastIncremental:
                            FastIncrementalLayoutSettings fastIncrementalLayoutSettings = new FastIncrementalLayoutSettings();
                            element.LayoutAlgorithmSettings = fastIncrementalLayoutSettings;

                            break;

                        case LayoutAlgorithm.MDS:
                            MdsLayoutSettings mdsLayoutSettings = new MdsLayoutSettings();
                            mdsLayoutSettings.ScaleX         = 1;
                            mdsLayoutSettings.ScaleY         = 1;
                            mdsLayoutSettings.AdjustScale    = true;
                            mdsLayoutSettings.RemoveOverlaps = true;
                            element.LayoutAlgorithmSettings  = mdsLayoutSettings;

                            break;

                        case LayoutAlgorithm.Ranking:
                            RankingLayoutSettings rankingLayoutSettings = new RankingLayoutSettings();
                            rankingLayoutSettings.ScaleX    = 1;
                            rankingLayoutSettings.ScaleY    = 1;
                            element.LayoutAlgorithmSettings = rankingLayoutSettings;

                            break;

                        case LayoutAlgorithm.Sugiyama:
                            SugiyamaLayoutSettings sugiyamaLayoutSettings = new SugiyamaLayoutSettings
                            {
                                LayerSeparation = 1,
                                MinNodeHeight   = 1,
                                MinNodeWidth    = 1
                            };

                            element.LayoutAlgorithmSettings = sugiyamaLayoutSettings;

                            break;
                        }

                        element.LayoutAlgorithmSettings.ClusterMargin  = 1;
                        element.LayoutAlgorithmSettings.NodeSeparation = 1;
                        element.LayoutAlgorithmSettings.EdgeRoutingSettings.Padding         = .3;
                        element.LayoutAlgorithmSettings.EdgeRoutingSettings.PolylinePadding = 1.5;
                        element.LayoutAlgorithmSettings.EdgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode.StraightLine;

                        settingsCache[newValue] = element.LayoutAlgorithmSettings;
                    }
                }
            }
            private void Layout()
            {
                try
                {
                    var scenes = Controller.Instance.ChapterList.getSelectedChapterDataControl().getScenesList();

                    // Layout algorithm
                    var settings = new Microsoft.Msagl.Layout.Layered.SugiyamaLayoutSettings();
                    settings.MaxAspectRatioEccentricity = 1.6;
                    settings.NodeSeparation             = 10;
                    settings.PackingMethod = PackingMethod.Compact;

                    // Graph
                    GeometryGraph graph = new GeometryGraph();
                    graph.BoundingBox = new Microsoft.Msagl.Core.Geometry.Rectangle(0, 0, SpaceWidth, SpaceHeight);
                    graph.UpdateBoundingBox();

                    Dictionary <SceneDataControl, Node>         sceneToNode = new Dictionary <SceneDataControl, Node>();
                    Dictionary <UniRx.Tuple <Node, Node>, bool> present     = new Dictionary <UniRx.Tuple <Node, Node>, bool>();

                    foreach (var scene in scenes.getScenes())
                    {
                        sizes.Remove(scene.getPreviewBackground());
                        var rect = GetSceneRect(scene);
                        var node = new Node(CurveFactory.CreateRectangle(rect.width, rect.height, new Point()), scene.getId());
                        graph.Nodes.Add(node);
                        sceneToNode.Add(scene, node);
                    }

                    foreach (var scene in scenes.getScenes())
                    {
                        var node = sceneToNode[scene];
                        foreach (var exit in scene.getExitsList().getExits())
                        {
                            var index = scenes.getSceneIndexByID(exit.getNextSceneId());

                            // If the exit points to a cutscene it normally is out of the array
                            if (index < 0 || index >= scenes.getScenes().Count)
                            {
                                continue;
                            }

                            var nextScene = scenes.getScenes()[index];

                            var t = new UniRx.Tuple <Node, Node>(node, sceneToNode[nextScene]);
                            if (!present.ContainsKey(t))
                            {
                                present.Add(t, true);
                                graph.Edges.Add(new Edge(node, sceneToNode[nextScene]));

                                var exitOrigin = GetExitArea(scene, exit).ToRect().center;
                                var originRect = GetSceneRect(scene);

                                var pos = exitOrigin - originRect.position;
                                pos.x = Mathf.Clamp01(pos.x / originRect.width);
                                pos.y = Mathf.Clamp01(pos.y / originRect.height);

                                // Positioning constraints
                                if (pos.x < 0.3)
                                {
                                    settings.AddLeftRightConstraint(t.Item2, t.Item1);
                                }
                                if (pos.x > 0.7)
                                {
                                    settings.AddLeftRightConstraint(t.Item1, t.Item2);
                                }
                            }
                        }
                    }


                    // Do the layouting
                    LayoutHelpers.CalculateLayout(graph, settings, null);

                    // Extract the results
                    var graphRect  = new Rect((float)graph.Left, (float)graph.Bottom, (float)graph.Width, (float)graph.Height);
                    var canvasRect = new Rect(0, 0, SpaceWidth, SpaceHeight);

                    foreach (var scene in scenes.getScenes())
                    {
                        var n = sceneToNode[scene];
                        positions[scene.getId()] = TransformPoint(new Vector2((float)(n.Center.X - n.Width / 2f), (float)(n.Center.Y + n.Height / 2f)), graphRect, canvasRect, true);

                        // Update in the project data
                        var id = GetScenePropertyId(Controller.Instance.SelectedChapterDataControl, scene);
                        ProjectConfigData.setProperty(id + ".X", ((int)positions[scene.getId()].x).ToString());
                        ProjectConfigData.setProperty(id + ".Y", ((int)positions[scene.getId()].y).ToString());
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogError(ex.Message + " : " + ex.StackTrace);
                }
            }
        private MSAGL.Core.Layout.GeometryGraph _create_msagl_graph(DirectedGraphLayout dglayout)
        {
            var msagl_graph = new MSAGL.Core.Layout.GeometryGraph();

            // Create the nodes in MSAGL
            foreach (var layout_shape in dglayout.Nodes)
            {
                var nodesize       = this._to_mg_coordinates(layout_shape.Size ?? this.LayoutOptions.DefaultShapeSize);
                var node_user_data = new ElementUserData(layout_shape.ID, layout_shape);
                var center         = new MSAGL.Core.Geometry.Point();
                var rectangle      = MSAGL.Core.Geometry.Curves.CurveFactory.CreateRectangle(nodesize.Width, nodesize.Height, center);
                var mg_node        = new MSAGL.Core.Layout.Node(rectangle, node_user_data);
                msagl_graph.Nodes.Add(mg_node);
            }

            this.validate_connectors(dglayout);

            var mg_coordinates = this._to_mg_coordinates(this.DefaultBezierConnectorLabelBoxSize);

            var map_id_to_ud = new Dictionary <string, MSAGL.Core.Layout.Node>();

            foreach (var n in msagl_graph.Nodes)
            {
                var ud = (ElementUserData)n.UserData;
                if (ud != null)
                {
                    map_id_to_ud[ud.ID] = n;
                }
            }

            // Create the MG Connectors
            foreach (var layout_connector in dglayout.Edges)
            {
                if (layout_connector.From == null)
                {
                    throw new ArgumentException("Connector's From node is null");
                }

                if (layout_connector.To == null)
                {
                    throw new ArgumentException("Connector's To node is null");
                }

                var from_node = map_id_to_ud[layout_connector.From.ID];
                var to_node   = map_id_to_ud[layout_connector.To.ID];

                var new_edge = new MSAGL.Core.Layout.Edge(from_node, to_node);
                // TODO: MSAGL
                //new_edge.ArrowheadAtTarget = false;
                new_edge.UserData = new ElementUserData(layout_connector.ID, layout_connector);
                msagl_graph.Edges.Add(new_edge);

                new_edge.Label = new MSAGL.Core.Layout.Label(mg_coordinates.Width, mg_coordinates.Height, new_edge);
            }

            var msagl_graphs           = MSAGL.Core.Layout.GraphConnectedComponents.CreateComponents(msagl_graph.Nodes, msagl_graph.Edges);
            var msagl_sugiyamasettings = new MSAGL.Layout.Layered.SugiyamaLayoutSettings();

            if (this.LayoutOptions.Direction == MsaglDirection.TopToBottom)
            {
                // do nothing
            }
            else if (this.LayoutOptions.Direction == MsaglDirection.BottomToTop)
            {
                msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(Math.PI);
            }
            else if (this.LayoutOptions.Direction == MsaglDirection.LeftToRight)
            {
                msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(Math.PI / 2);
            }
            else if (this.LayoutOptions.Direction == MsaglDirection.RightToLeft)
            {
                msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(-Math.PI / 2);
            }
            else
            {
                throw new System.ArgumentOutOfRangeException();
            }

            foreach (var subgraph in msagl_graphs)
            {
                var layout = new Microsoft.Msagl.Layout.Layered.LayeredLayout(subgraph, msagl_sugiyamasettings);

                subgraph.Margins = msagl_sugiyamasettings.NodeSeparation / 2;

                layout.Run();
            }

            // Pack the graphs using Golden Aspect Ratio
            MSAGL.Layout.MDS.MdsGraphLayout.PackGraphs(msagl_graphs, msagl_sugiyamasettings);

            //Update the graphs bounding box
            msagl_graph.UpdateBoundingBox();

            this._msagl_bb = new VA.Geometry.Rectangle(
                msagl_graph.BoundingBox.Left,
                msagl_graph.BoundingBox.Bottom,
                msagl_graph.BoundingBox.Right,
                msagl_graph.BoundingBox.Top);

            this._visio_bb = new VA.Geometry.Rectangle(0, 0, this._msagl_bb.Width, this._msagl_bb.Height)
                             .Multiply(this._scale_to_document, this._scale_to_document);

            return(msagl_graph);
        }