示例#1
0
        /// <summary>
        /// Draws a partially defined graph edge</summary>
        /// <param name="fromNode">Source node, or null</param>
        /// <param name="fromRoute">Source route, or null</param>
        /// <param name="toNode">Destination node, or null</param>
        /// <param name="toRoute">Destination route, or null</param>
        /// <param name="label">Edge label</param>
        /// <param name="endPoint">Endpoint to substitute for source or destination, if either is null</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(
            TNode fromNode,
            BoundaryRoute fromRoute,
            TNode toNode,
            BoundaryRoute toRoute,
            string label,
            Point endPoint,
            D2dGraphics g)
        {
            // put endpoint into statechart space
            var inverse = g.Transform;

            inverse.Invert();
            PointF end = Matrix3x2F.TransformPoint(inverse, endPoint);

            PointF p1;
            PointF normal1;

            if (fromNode != null)
            {
                p1 = ParameterToPoint(fromNode.Bounds, fromRoute.Position, out normal1);
            }
            else
            {
                p1      = end;
                normal1 = new Point();
            }

            PointF p4;
            PointF normal2;

            if (toNode != null)
            {
                p4 = ParameterToPoint(toNode.Bounds, toRoute.Position, out normal2);
            }
            else
            {
                p4      = end;
                normal2 = new Point();
            }

            PointF p2, p3;
            float  d = GetTransitionPoints(p1, normal1, p4, normal2, out p2, out p3);

            DrawEdgeSpline(p1, p2, p3, p4, d, m_theme.OutlineBrush, g);

            if (!string.IsNullOrEmpty(label))
            {
                BezierCurve2F curve    = new BezierCurve2F(p1, p2, p3, p4);
                Vec2F         midpoint = curve.Evaluate(0.5f);
                g.DrawText(label, m_centerText, new PointF(midpoint.X, midpoint.Y), m_theme.TextBrush);
            }
        }
示例#2
0
        /// <summary>
        /// Draws a partially defined graph edge</summary>
        /// <param name="fromNode">Source node, or null</param>
        /// <param name="fromRoute">Source route, or null</param>
        /// <param name="toNode">Destination node, or null</param>
        /// <param name="toRoute">Destination route, or null</param>
        /// <param name="label">Edge label</param>
        /// <param name="endPoint">Endpoint to substitute for source or destination, if either is null</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(
            TNode fromNode,
            BoundaryRoute fromRoute,
            TNode toNode,
            BoundaryRoute toRoute,
            string label,
            Point endPoint,
            Graphics g)
        {
            // put endpoint into statechart space
            endPoint = GdiUtil.InverseTransform(g.Transform, endPoint);

            Point p1;
            Point normal1;

            if (fromNode != null)
            {
                p1 = ParameterToPoint(fromNode.Bounds, fromRoute.Position, out normal1);
            }
            else
            {
                p1      = endPoint;
                normal1 = new Point();
            }

            Point p4;
            Point normal2;

            if (toNode != null)
            {
                p4 = ParameterToPoint(toNode.Bounds, toRoute.Position, out normal2);
            }
            else
            {
                p4      = endPoint;
                normal2 = new Point();
            }

            Point p2, p3;
            float d = GetTransitionPoints(p1, normal1, p4, normal2, out p2, out p3);

            DrawEdgeSpline(p1, p2, p3, p4, d, m_theme.OutlinePen, g);

            BezierCurve2F curve    = new BezierCurve2F(p1, p2, p3, p4);
            Vec2F         midpoint = curve.Evaluate(0.5f);

            midpoint.X += 2;
            g.DrawString(label, m_theme.Font, m_theme.TextBrush, new PointF(midpoint.X, midpoint.Y));
        }
示例#3
0
        /// <summary>
        /// Finds node and/or edge hit by the given point</summary>
        /// <param name="graph">Graph to test</param>
        /// <param name="priorityEdge">Graph edge to test before others</param>
        /// <param name="p">Point to test</param>
        /// <param name="g">Graphics object</param>
        /// <returns>Hit record containing node and/or edge hit by the given point</returns>
        public override GraphHitRecord <TNode, TEdge, BoundaryRoute> Pick(
            IGraph <TNode, TEdge, BoundaryRoute> graph,
            TEdge priorityEdge,
            Point p,
            Graphics g)
        {
            int tolerance = m_theme.PickTolerance;

            TNode         pickedNode = null;
            TEdge         pickedEdge = null;
            BoundaryRoute fromRoute  = null;
            BoundaryRoute toRoute    = null;

            Vec2F v = new Vec2F(p.X, p.Y);

            if (priorityEdge != null &&
                Pick(priorityEdge, v))
            {
                pickedEdge = priorityEdge;
            }
            else
            {
                foreach (TEdge edge in graph.Edges.Reverse())
                {
                    if (Pick(edge, v))
                    {
                        pickedEdge = edge;
                        break;
                    }
                }
            }

            foreach (TNode state in graph.Nodes.Reverse())
            {
                Rectangle bounds = state.Bounds;
                bounds.Inflate(tolerance, tolerance);

                if (bounds.Contains(p))
                {
                    pickedNode = state;

                    float position = PointToParameter(bounds, p);

                    bounds.Inflate(-2 * tolerance, -2 * tolerance);
                    bool onEdge = !bounds.Contains(p);

                    if (pickedEdge == null)
                    {
                        if (onEdge)
                        {
                            // edge of node can be source or destination
                            fromRoute = new BoundaryRoute(position);
                            toRoute   = new BoundaryRoute(position);
                        }
                    }
                    else // hit on edge and node
                    {
                        if (onEdge)
                        {
                            if (pickedEdge.FromNode == pickedNode)
                            {
                                fromRoute = new BoundaryRoute(position);
                            }
                            else if (pickedEdge.ToNode == pickedNode)
                            {
                                toRoute = new BoundaryRoute(position);
                            }
                        }
                    }
                    break;
                }
            }

            IComplexState <TNode, TEdge> complexState = pickedNode as IComplexState <TNode, TEdge>;

            if (complexState != null && pickedEdge == null)
            {
                Rectangle bounds      = pickedNode.Bounds;
                Rectangle labelBounds = new Rectangle(
                    bounds.X + CornerRadius,
                    bounds.Y + Margin,
                    bounds.Width - 2 * CornerRadius,
                    m_theme.Font.Height);

                if (labelBounds.Contains(p))
                {
                    DiagramLabel label = new DiagramLabel(labelBounds, TextFormatFlags.SingleLine);
                    return
                        (new GraphHitRecord <TNode, TEdge, BoundaryRoute>(pickedNode, label));
                }
            }

            return
                (new GraphHitRecord <TNode, TEdge, BoundaryRoute>(pickedNode, pickedEdge, fromRoute, toRoute));
        }