Esempio n. 1
0
        /// <summary>
        /// Get point representing given connector.
        /// </summary>
        /// <param name="connector">Connector which point is requested.</param>
        /// <returns>Point representing given connector if available, <c>null</c> otherwise.</returns>
        private GraphPoint getPoint(ConnectorDrawing connector)
        {
            GraphPoint connectorPoint;

            _connectorPoints.TryGetValue(connector, out connectorPoint);
            return(connectorPoint);
        }
        /// <summary>
        /// Attach behaviour to given connector
        /// </summary>
        /// <param name="connector">Attached connector</param>
        /// <param name="engine">Engine using attached behaviour</param>
        /// <param name="moveHandler">Handler used for move events</param>
        internal static void Attach(ConnectorDrawing connector, DisplayEngine engine, OnConnectorMove moveHandler)
        {
            var item = connector.OwningItem;

            UpdateGlobalPosition.WidthChange.AddValueChanged(item, (e, args) =>
            {
                moveHandler(connector);
            });

            UpdateGlobalPosition.HeightChange.AddValueChanged(item, (e, args) =>
            {
                moveHandler(connector);
            });
        }
Esempio n. 3
0
        internal static void SetProperties(ConnectorDrawing connector, string heading, IEnumerable <KeyValuePair <string, string> > mapping)
        {
            var definition = connector.Definition;

            var propertiesText = new StringBuilder();

            foreach (var map in mapping)
            {
                var property = definition.GetProperty(map.Key);
                if (property == null || property.Value == null)
                {
                    continue;
                }

                propertiesText.AppendFormat("{0}: {1}\n", map.Value, property.Value);
            }

            var metaText = new StringBuilder();

            foreach (var property in definition.Properties)
            {
                var prefix       = "$Meta";
                var propertyName = property.Name;
                if (!propertyName.StartsWith(prefix))
                {
                    continue;
                }

                var name = propertyName.Substring(propertyName.IndexOf('-') + 1);
                metaText.AppendFormat("{0}: {1}\n", name, property.Value);
            }

            var tooltip = DrawingTools.GetHeadingText(heading, propertiesText.ToString());

            if (metaText.Length > 0)
            {
                DrawingTools.AppendHeadingText("Metadata", metaText.ToString(), tooltip);
            }

            DrawingTools.SetToolTip(connector, tooltip);
        }
Esempio n. 4
0
        /// <summary>
        /// Run exploration of path between given connectors
        /// <remarks>Exploration should be runned before path finding</remarks>.
        /// </summary>
        /// <param name="from">Connector from which path is explored.</param>
        /// <param name="to">Connector to which path is explored.</param>
        public void Explore(ConnectorDrawing from, ConnectorDrawing to)
        {
            //initialize global buffers
            _processed.Clear();
            _fromCandidates.Clear();

            //get point representation of source connector
            var fromPoint = getPoint(from);

            if (fromPoint == null)
            {
                return;
            }

            //all points on desired component are possible targets (they all are connected with self)
            var toItem       = to.OwningItem;
            var toCandidates = _itemPoints.Get(toItem);

            //run exploration
            tryEnqueue(fromPoint);
            while (_fromCandidates.Count > 0)
            {
                var fromCandidate = _fromCandidates.Dequeue();
                foreach (var toCandidate in toCandidates)
                {
                    DiagramItem obstacle;
                    tryAddEdge(fromCandidate, toCandidate, toItem, out obstacle);
                    enqueueWithObstacleEdges(fromCandidate, obstacle);
                }

                foreach (var neighbour in fromCandidate.ExploredNeighbours)
                {
                    tryEnqueue(neighbour);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Create point for given connector with given view angle.
        /// </summary>
        /// <param name="connector">Connector which point is created.</param>
        /// <param name="view">View angle of created point.</param>
        /// <returns>Created point.</returns>
        private GraphPoint createPoint(ConnectorDrawing connector, ViewAngle view)
        {
            var position = connector.GlobalConnectPoint;

            return(new GraphPoint(position, view, connector.OwningItem));
        }
Esempio n. 6
0
        /// <summary>
        /// Gets the input slots.
        /// </summary>
        /// <param name="connectorIndex">Index of the connector.</param>
        /// <param name="connectorsCount">The connectors count.</param>
        /// <param name="connector">The connector.</param>
        /// <param name="item">The item.</param>
        /// <param name="contactPoints">The contact points.</param>
        /// <returns>GraphPoint[].</returns>
        /// <exception cref="System.NotSupportedException">Connector align  + connectorAlign</exception>
        private GraphPoint[] getInputSlots(int connectorIndex, int connectorsCount, ConnectorDrawing connector, DiagramItem item, List <GraphPoint> contactPoints)
        {
            var connectorAlign = connector.Align;

            var span = _navigator.GetSpan(item);

            //find positions of slots for inputs according to connector align
            Point slot1End, slot1Start;
            Point slot2End;

            ViewAngle slot1View;
            ViewAngle slot2View;

            GraphPoint slot1Contact;
            GraphPoint slot2Contact;

            //slots has to be parallel with same length
            switch (connectorAlign)
            {
            case ConnectorAlign.Top:
                slot1Contact = contactPoints[2];
                slot2Contact = contactPoints[3];
                slot1View    = TopLeftCorner;
                slot2View    = TopRightCorner;
                slot1End     = span.TopLeft;
                slot2End     = span.TopRight;
                slot1Start   = new Point(slot1End.X, slot1End.Y + item.TopConnectors.DesiredSize.Height);
                break;

            case ConnectorAlign.Bottom:
                slot1Contact = contactPoints[0];
                slot2Contact = contactPoints[1];
                slot1View    = BottomLeftCorner;
                slot2View    = BottomRightCorner;
                slot1End     = span.BottomLeft;
                slot2End     = span.BottomRight;
                slot1Start   = new Point(slot1End.X, slot1End.Y - item.BottomConnectors.DesiredSize.Height);
                break;

            case ConnectorAlign.Left:
                slot1Contact = contactPoints[1];
                slot2Contact = contactPoints[3];
                slot1View    = TopLeftCorner;
                slot2View    = BottomLeftCorner;
                slot1End     = span.TopLeft;
                slot2End     = span.BottomLeft;
                slot1Start   = new Point(slot1End.X + item.LeftConnectors.DesiredSize.Width, slot1End.Y);
                break;

            case ConnectorAlign.Right:
                slot1Contact = contactPoints[0];
                slot2Contact = contactPoints[2];
                slot1View    = TopRightCorner;
                slot2View    = BottomRightCorner;
                slot1End     = span.TopRight;
                slot2End     = span.BottomRight;
                slot1Start   = new Point(slot1End.X - item.RightConnectors.DesiredSize.Width, slot1End.Y);
                break;

            default:
                throw new NotSupportedException("Connector align " + connectorAlign);
            }

            var slotVector = (slot1Start - slot1End) / (connectorsCount + 2);

            var slot1 = new GraphPoint(slot1End + slotVector * connectorIndex, slot1View, item);
            var slot2 = new GraphPoint(slot2End + slotVector * (connectorsCount - connectorIndex), slot2View, item);

            slot1.SetEdgeStatus(slot1Contact);
            slot2.SetEdgeStatus(slot2Contact);

            return(new[] { slot1, slot2 });
        }
Esempio n. 7
0
        /// <summary>
        /// Find path beween from and to connectors.
        /// <remarks>Path finding is processed on current explored state of graph</remarks>.
        /// </summary>
        /// <param name="from">Start of desired path.</param>
        /// <param name="to">End of desired path.</param>
        /// <returns>Path if available, <c>null</c> otherwise.</returns>
        /// <exception cref="System.NotSupportedException"></exception>
        public Point[] FindPath(ConnectorDrawing from, ConnectorDrawing to)
        {
            //get connector representation on graph
            var fromPoint = getPoint(from);
            var toPoint   = getPoint(to);

            //if there is no connector representation we
            //cannot construct path
            if (fromPoint == null || toPoint == null)
            {
                return(null);
            }

            //store points that has been already reached
            var reachedPoints = new Dictionary <GraphPoint, GraphPoint>();

            reachedPoints.Add(fromPoint, null);

            //queue where are stored relaxed graph nodes
            var toRelax = new Dictionary <GraphPoint, double>();

            toRelax.Add(fromPoint, 0);

            while (toRelax.Count > 0)
            {
                var currentPair     = extractMin(toRelax);
                var current         = currentPair.Key;
                var currentDistance = currentPair.Value;

                //relax all neigbours of current node
                foreach (var neighbour in current.ExploredNeighbours)
                {
                    if (reachedPoints.ContainsKey(neighbour))
                    {
                        continue;
                    }

                    var fromCurrentDistance = current.DistanceTo(neighbour);
                    var toNeighbourDistance = currentDistance + fromCurrentDistance;

                    double previousNeighbourDistance;
                    if (!toRelax.TryGetValue(neighbour, out previousNeighbourDistance))
                    {
                        toRelax[neighbour] = previousNeighbourDistance = double.MaxValue;
                    }

                    if (previousNeighbourDistance <= toNeighbourDistance)
                    {
                        //we have already a better path
                        continue;
                    }

                    if (neighbour == current)
                    {
                        throw new NotSupportedException();
                    }

                    //relax path
                    reachedPoints[neighbour] = current;
                    toRelax[neighbour]       = toNeighbourDistance;
                }
            }

            //get representation of path that has been found
            var reconstructed = reconstructPath(toPoint, reachedPoints);
            var simplified    = simplifyPath(reconstructed);

            return(simplified);
        }