コード例 #1
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 <TElement, TWire, TPin> Pick(
            IGraph <TElement, TWire, TPin> graph, TWire priorityEdge, Point p, Graphics g)
        {
            TElement pickedElement = null;
            TPin     pickedInput   = null;
            TPin     pickedOutput  = null;
            TWire    pickedWire    = null;

            if (priorityEdge != null &&
                PickEdge(priorityEdge, p, g))
            {
                pickedWire = priorityEdge;
            }
            else
            {
                foreach (TWire edge in graph.Edges)
                {
                    if (PickEdge(edge, p, g))
                    {
                        pickedWire = edge;
                        break;
                    }
                }
            }

            foreach (TElement element in graph.Nodes.Reverse())
            {
                if (Pick(element, g, p))
                {
                    pickedElement = element;
                    pickedInput   = PickInput(element, g, p);
                    pickedOutput  = PickOutput(element, g, p);
                    break;
                }
            }

            if (pickedElement != null && pickedWire == null)
            {
                Rectangle bounds      = GetElementBounds(pickedElement, g);
                Rectangle labelBounds = new Rectangle(
                    bounds.Left, bounds.Bottom + PinMargin, bounds.Width, m_rowSpacing);
                labelBounds = GdiUtil.Transform(g.Transform, labelBounds);
                if (labelBounds.Contains(p))
                {
                    DiagramLabel label = new DiagramLabel(
                        labelBounds,
                        TextFormatFlags.SingleLine |
                        TextFormatFlags.HorizontalCenter);

                    return(new GraphHitRecord <TElement, TWire, TPin>(pickedElement, label));
                }
            }

            return(new GraphHitRecord <TElement, TWire, TPin>(pickedElement, pickedWire, pickedOutput, pickedInput));
        }
コード例 #2
0
ファイル: StatechartRenderer.cs プロジェクト: zoombapup/ATF
        /// <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));
        }
コード例 #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 <TElement, TWire, TPin> Pick(
            IGraph <TElement, TWire, TPin> graph, TWire priorityEdge, PointF p, D2dGraphics g)
        {
            var hitRecord = base.Pick(graph, priorityEdge, p, g);

            if (hitRecord.Node != null || hitRecord.Edge != null || hitRecord.Part != null)
            {
                return(hitRecord);
            }

            // check whether hits virtual parts of group pin
            var group = graph.Cast <ICircuitGroupType <TElement, TWire, TPin> >();

            foreach (var pin in group.Inputs.Concat(group.Info.HiddenInputPins))
            {
                var grpPin = pin.Cast <ICircuitGroupPin <TElement> >();
                // check whether hit the thumbtack of a floating pin
                var pinRect = GetThumbtackRect(grpPin, true);
                if (pinRect.Contains(p))
                {
                    var pinPart = new DiagramPin(pinRect);
                    return(new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, pinPart));
                }

                // check whether hit the visibility check(eye icon)
                var eyeRect = GetVisibilityCheckRect(grpPin, true);
                if (eyeRect.Contains(p))
                {
                    var eyePart = new DiagramVisibilityCheck(eyeRect);
                    return(new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, eyePart));
                }


                // check whether hit the floating pin label-part
                PointF     grpPos      = GetGroupPinLocation(grpPin, true);
                RectangleF bounds      = new RectangleF(grpPos.X, grpPos.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight);
                SizeF      nameSize    = g.MeasureText(grpPin.Name, Theme.TextFormat);
                RectangleF labelBounds = new RectangleF(bounds.Left, bounds.Bottom + Theme.PinMargin, (int)nameSize.Width, Theme.RowSpacing);
                //labelBounds = GdiUtil.Transform(g.Transform, labelBounds);
                var labelPart = new DiagramLabel(
                    new Rectangle((int)labelBounds.Left, (int)labelBounds.Top, (int)labelBounds.Width, (int)labelBounds.Height),
                    TextFormatFlags.SingleLine | TextFormatFlags.Left);

                if (labelBounds.Contains(p))
                {
                    return(new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, labelPart));
                }

                // check whether hit the floating pin node
                if (bounds.Contains(p))
                {
                    var result = new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, null);
                    result.DefaultPart = labelPart;
                    return(result);
                }
            }

            foreach (var pin in group.Outputs.Concat(group.Info.HiddenOutputPins))
            {
                var grpPin = pin.Cast <ICircuitGroupPin <TElement> >();
                // check whether hit the thumbtack of a floating pin
                var pinRect = GetThumbtackRect(grpPin, false);
                if (pinRect.Contains(p))
                {
                    var pinPart = new DiagramPin(pinRect);
                    return(new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, pinPart));
                }

                // check whether hit the visibility check(eye icon)
                var eyeRect = GetVisibilityCheckRect(grpPin, false);
                if (eyeRect.Contains(p))
                {
                    var eyePart = new DiagramVisibilityCheck(eyeRect);
                    return(new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, eyePart));
                }

                // check whether hit the floating pin label-part
                PointF     grpPos      = GetGroupPinLocation(grpPin, false);
                RectangleF bounds      = new RectangleF(grpPos.X, grpPos.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight);
                SizeF      nameSize    = g.MeasureText(grpPin.Name, Theme.TextFormat);
                RectangleF labelBounds = new RectangleF(bounds.Right - (int)nameSize.Width, bounds.Bottom + Theme.PinMargin, (int)nameSize.Width, Theme.RowSpacing);
                //labelBounds = GdiUtil.Transform(g.Transform, labelBounds);
                var labelPart = new DiagramLabel(
                    new Rectangle((int)labelBounds.Left, (int)labelBounds.Top, (int)labelBounds.Width, (int)labelBounds.Height),
                    TextFormatFlags.SingleLine | TextFormatFlags.Right);

                if (labelBounds.Contains(p))
                {
                    return(new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, labelPart));
                }

                // check whether hit the floating pin node
                if (bounds.Contains(p))
                {
                    var result = new GraphHitRecord <TElement, TWire, TPin>((TPin)grpPin, null);
                    result.DefaultPart = labelPart;
                    return(result);
                }
            }

            return(hitRecord);
        }
コード例 #4
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);
        }
コード例 #5
0
        protected virtual DiagramSelectionBorder CalculateLabelBorder(DiagramLabel label)
        {
            var textGeometry = label.Geometry as Geometry;
            if (textGeometry == null)
                return null;

            var rectGeometry = textGeometry as RectangleGeometry;
            if (rectGeometry == null)
                return null;

            var border = new DiagramSelectionBorder();

            border.ResizeInfos.Add(new ResizeInfo(rectGeometry.Bounds.TopLeft, ResizeDirection.None));
            border.ResizeInfos.Add(new ResizeInfo(rectGeometry.Bounds.TopRight, ResizeDirection.None));
            border.ResizeInfos.Add(new ResizeInfo(rectGeometry.Bounds.BottomRight, ResizeDirection.None));
            border.ResizeInfos.Add(new ResizeInfo(rectGeometry.Bounds.BottomLeft, ResizeDirection.None));

            return border;
        }
コード例 #6
0
        private Geometry CalculateLabelGeometry(DiagramLabel label)
        {
            FontFamily = label.FontFamily;
            FontSize = label.FontSize;
            FontStretch = label.FontStretch;
            FontStyle = label.FontStyle;
            FontWeight = label.FontWeight;
            Foreground = label.Foreground;
            Text = label.Text;

            var node = label.Owner as DiagramNode;
            if (node != null)
            {
                return CalculateLabelOnNode(label, node);
            }

            var edge = label.Owner as DiagramEdge;
            if (edge != null)
            {
                return CalculateLabelOnEdge(label, edge);
            }

            return null;
        }
コード例 #7
0
        protected virtual void DrawLabel(DrawingContext dc, DiagramLabel label)
        {
            var geometry = label.Geometry;
            if (geometry == null)
                return;

            DrawGeometry(dc, label.Geometry, label.Background, label.BorderPen, label.Diagram.Offset, label.Diagram.Scale);
            //dc.DrawGeometry(label.Background, label.BorderPen, geometry);

            var origin = geometry.Bounds.TopLeft;
            var fText = CreateFormattedText(label.Text);

            DrawFormattedText(dc, CreateFormattedText(label.Text), geometry.Bounds.TopLeft, label.Diagram.Offset, label.Diagram.Scale);
            //dc.DrawText(fText, origin);
        }
コード例 #8
0
        //public IShape CalculateShape(DiagramItem item)
        //{
        //    var label = item as DiagramLabel;
        //    if (label == null)
        //        throw new DiagramException("Тип объекта не соответствует типу отрисовщика!");
        //    return CalculateLabelShape(label);
        //}
        //protected IShape CalculateLabelShape(DiagramLabel label)
        //{
        //    FontFamily = label.FontFamily;
        //    FontSize = label.FontSize;
        //    FontStretch = label.FontStretch;
        //    FontStyle = label.FontStyle;
        //    FontWeight = label.FontWeight;
        //    Foreground = label.Foreground;
        //    var node = label.Owner as DiagramNode;
        //    if (node != null)
        //    {
        //        return CalculateLabelOnNode(label, node);
        //    }
        //    var edge = label.Owner as DiagramEdge;
        //    if (edge != null)
        //    {
        //        return CalculateLabelOnEdge(label, edge);
        //    }
        //    return null;
        //}
        protected virtual Geometry CalculateLabelOnNode(DiagramLabel label, DiagramNode node)
        {
            var textSize = GetTextSize(label.Text);
            var nodeRect = node.Bounds;
            var origin = new Point((nodeRect.Right + nodeRect.Left) / 2, (nodeRect.Bottom + nodeRect.Top) / 2);
            origin.Offset(label.RelativePosition.X, label.RelativePosition.Y);

            origin.Offset(-textSize.Width / 2, -textSize.Height / 2);

            return new RectangleGeometry(new Rect(origin.X, origin.Y, textSize.Width,
                textSize.Height));
        }
コード例 #9
0
        protected virtual Geometry CalculateLabelOnEdge(DiagramLabel label, DiagramEdge edge)
        {
            var geometry = edge.Geometry;
            if (geometry == null)
                return null;

            Rect bounds = geometry.Bounds;

            var textSize = GetTextSize(label.Text);
            var origin = new Point(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2);
            origin.Offset(label.RelativePosition.X, label.RelativePosition.Y);
            origin.Offset(-textSize.Width / 2, -textSize.Height / 2);

            return new RectangleGeometry(new Rect(origin.X, origin.Y, textSize.Width,
                textSize.Height));
        }