/// <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)); }
/// <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)); }
/// <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); }
/// <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); }
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; }
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; }
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); }
//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)); }
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)); }