Ejemplo n.º 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 (in client coords), if either is null</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(
            TNode fromNode,
            NumberedRoute fromRoute,
            TNode toNode,
            NumberedRoute toRoute,
            string label,
            Point endPoint,
            D2dGraphics g)
        {
            var inverse = g.Transform;

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

            TNode   node     = (fromNode != null) ? fromNode : toNode;
            CircleF boundary = GetBoundary(node);
            Vec2F   proj     = new Vec2F();

            if (CircleF.Project(new Vec2F(end), boundary, ref proj))
            {
                PointF start = new PointF(proj.X, proj.Y);
                g.DrawLine(start, end, m_theme.OutlineBrush);

                if (fromNode == null)
                {
                    PointF temp = end;
                    end   = start;
                    start = temp;
                }
                Vec2F endTangent    = new Vec2F(end.X - start.X, end.Y - start.Y);
                Vec2F arrowPosition = new Vec2F(end);
                DrawArrow(arrowPosition, endTangent, m_theme.OutlineBrush, g);

                if (!string.IsNullOrEmpty(label))
                {
                    PointF     textPoint = new PointF((end.X + start.X) * 0.5f, (end.Y + start.Y) * 0.5f);
                    RectangleF textBox   = new RectangleF(textPoint.X - 512, textPoint.Y, 1024, m_theme.TextFormat.FontHeight);
                    //g.DrawString(label, m_theme.Font, m_theme.TextBrush, textBox, m_theme.CenterStringFormat);
                    g.DrawText(label, m_theme.TextFormat, textBox, m_theme.TextBrush);
                }
            }
        }
Ejemplo n.º 2
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 in graph space</param>
        /// <param name="g">D2dGraphics object</param>
        /// <returns>Hit record containing node and/or edge hit by the given point</returns>
        public override GraphHitRecord <TNode, TEdge, NumberedRoute> Pick(
            IGraph <TNode, TEdge, NumberedRoute> graph,
            TEdge priorityEdge,
            PointF p,
            D2dGraphics g)
        {
            TNode         pickedNode = null;
            TEdge         pickedEdge = null;
            NumberedRoute fromRoute  = null;
            NumberedRoute 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 node in graph.Nodes.Reverse())
            {
                if (Pick(node, p))
                {
                    pickedNode = node;

                    CircleF boundary = GetBoundary(node);
                    boundary.Radius -= m_theme.PickTolerance;
                    bool onEdge = !boundary.Contains(v);

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

            var result = new GraphHitRecord <TNode, TEdge, NumberedRoute>(pickedNode, pickedEdge, fromRoute, toRoute);

            PointF clientP = Matrix3x2F.TransformPoint(g.Transform, p);

            if (fromRoute != null)
            {
                result.FromRoutePos = clientP;
            }
            if (toRoute != null)
            {
                result.ToRoutePos = clientP;
            }

            if (pickedNode != null && pickedEdge == null)
            {
                // label is centered in entire node
                RectangleF labelBounds = GetBounds(pickedNode, g);
                float      dHeight     = labelBounds.Height - m_theme.TextFormat.FontHeight;
                labelBounds = new RectangleF(
                    labelBounds.X, labelBounds.Y + dHeight / 2, labelBounds.Width, labelBounds.Height - dHeight);

                if (labelBounds.Contains(p))
                {
                    DiagramLabel label = new DiagramLabel(
                        Rectangle.Truncate(labelBounds),
                        TextFormatFlags.SingleLine |
                        TextFormatFlags.HorizontalCenter);

                    return
                        (new GraphHitRecord <TNode, TEdge, NumberedRoute>(pickedNode, label));
                }
            }
            else if (pickedEdge != null)
            {
                RectangleF   labelBounds = GetLabelBounds(pickedEdge, g);
                DiagramLabel label       = new DiagramLabel(
                    Rectangle.Truncate(labelBounds),
                    TextFormatFlags.SingleLine |
                    TextFormatFlags.HorizontalCenter);

                if (labelBounds.Contains(p))
                {
                    return
                        (new GraphHitRecord <TNode, TEdge, NumberedRoute>(pickedEdge, label));
                }
            }

            return(result);
        }