/// <summary> /// Create relationship if possible. Release mouse afterwards. /// </summary> /// <param name="e"></param> protected override void OnMouseUp(MouseButtonEventArgs e) { if (hitItem != null) { object targetElement = hitItem.SelectedData; if (sourceItem != null && hitItem != null && this.diagramDesigner.CreateRelationshipCommand != null) { ViewModelRelationshipCreationInfo info = new ViewModelRelationshipCreationInfo(sourceItem.SelectedData, hitItem.SelectedData); // calcualte source and target points if (hitItem is FrameworkElement) { FrameworkElement sourceFElement = sourceConnector.DiagramItem; double sourceLeft = Canvas.GetLeft(sourceFElement); double sourceTop = Canvas.GetTop(sourceFElement); FrameworkElement targetFElement = hitItem as FrameworkElement; double targetLeft = Canvas.GetLeft(targetFElement); double targetTop = Canvas.GetTop(targetFElement); if (!double.IsNaN(sourceLeft) && !double.IsNaN(sourceTop) && !double.IsNaN(targetLeft) && !double.IsNaN(targetTop)) { Point proposedTarget = e.GetPosition(this.diagramDesigner); PointD proposedSourcePoint = new PointD(startPoint.X, startPoint.Y); PointD proposedTargetPoint = new PointD(proposedTarget.X, proposedTarget.Y); // calculate points //Point sourcePointT = sourceFElement.TranslatePoint(new Point(0, 0), this.diagramDesigner); //Point targetPointT = targetFElement.TranslatePoint(new Point(0, 0), this.diagramDesigner); Point sourcePoint = sourceFElement.TransformToAncestor(this.diagramDesigner).Transform(new Point(0, 0)); Point targetPoint = targetFElement.TransformToAncestor(this.diagramDesigner).Transform(new Point(0, 0)); // calculate side for source RectangleD sourceBounds = new RectangleD(sourcePoint.X, sourcePoint.Y, sourceFElement.Width, sourceFElement.Height); info.ProposedSourcePoint = LinkShape.CalculateLocation(sourceBounds, proposedSourcePoint); // calculate side for target RectangleD targeteBounds = new RectangleD(targetPoint.X, targetPoint.Y, targetFElement.Width, targetFElement.Height); info.ProposedTargetPoint = LinkShape.CalculateLocation(targeteBounds, proposedTargetPoint); } } this.diagramDesigner.CreateRelationshipCommand.Execute(info); } } if (this.IsMouseCaptured) { this.ReleaseMouseCapture(); } AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.diagramDesigner); if (adornerLayer != null) { adornerLayer.Remove(this); } }
/// <summary> /// Create connection points on the mid point of all 4 sides of the socket rectangle /// </summary> /// <param name="link"></param> public override void EnsureConnectionPoints(LinkShape link) { //Don't call the base because that creates the default connection points, which we don't want //base.EnsureConnectionPoints(link); if (this.ConnectionPoints.Count == 4) { return; //Already created } this.ConnectionPoints.Clear(); PointD c = this.AbsoluteBoundingBox.Center; //Create a connection point on each edge of the socket var points = new PointD[] { new PointD(c.X - rectW / 2, c.Y), new PointD(c.X + rectW / 2, c.Y), new PointD(c.X, c.Y - rectH / 2), new PointD(c.X, c.Y + rectH / 2) }; //Rotate points according to the socket orientation double angle = (((SocketBase)(this.ModelElement)).Definition.Orientation / 180.0) * Math.PI; var rotatedPoints = from p in points select Rotate(p, c, angle); foreach (PointD p in rotatedPoints) { CreateConnectionPoint(p); } }
/// <summary> /// Called on every connector creation. /// Should only define connection points once. /// </summary> /// <param name="link"></param> public override void CreateConnectionPoint(LinkShape link) { if (this.ConnectionPoints == null || this.ConnectionPoints.Count == 0) { // Contrary to appearances, connection points aren't specific to link type. this.CreateConnectionPoint( new PointD(AbsoluteBoundingBox.Center.X, AbsoluteBoundingBox.Bottom), link); this.CreateConnectionPoint( new PointD(AbsoluteBoundingBox.Center.X, AbsoluteBoundingBox.Top), link); } }
private static void CorrectStartEndpoints(LinkShape linkShape, Point startPointTemp, Point endPointTemp, out Point startPoint, out Point endPoint) { startPoint = startPointTemp; endPoint = endPointTemp; double marginPath = DistanceToElement; switch (linkShape.LinkPlacementStart) { case LinkPlacement.Left: startPoint.X -= marginPath; break; case LinkPlacement.Top: startPoint.Y -= marginPath; break; case LinkPlacement.Right: startPoint.X += marginPath; break; case LinkPlacement.Bottom: startPoint.Y += marginPath; break; default: break; } switch (linkShape.LinkPlacementEnd) { case LinkPlacement.Left: endPoint.X -= marginPath; break; case LinkPlacement.Top: endPoint.Y -= marginPath; break; case LinkPlacement.Right: endPoint.X += marginPath; break; case LinkPlacement.Bottom: endPoint.Y += marginPath; break; default: break; } }
/// <summary> /// Defines the connection points for the shape. /// </summary> public override void EnsureConnectionPoints(LinkShape link) { PointD[] connectionPoints = this.geometry.GetGeometryConnectionPoints(this); if (connectionPoints != null) { foreach (PointD connectionPoint in connectionPoints) { this.CreateConnectionPoint(connectionPoint); } } else { base.EnsureConnectionPoints(link); } }
/// <summary> /// Set an anchor position based on a horizontal and verical changes proposed. /// </summary> /// <param name="horizontalChange">Horizontal change.</param> /// <param name="verticalChange">Vertical change.</param> /// <returns>Calculated position.</returns> public virtual void SetToAnchorPosition(double horizontalChange, double verticalChange) { PointD proposedPoint = new PointD(this.EndEdgePoint.X + horizontalChange, this.EndEdgePoint.Y + verticalChange); LinkPlacement placement = LinkShape.GetLinkPlacement(this.ShapeElement.ToShape.AbsoluteBounds, proposedPoint); PointD calculatedLocation = LinkShape.CalculateLocation(placement, this.ShapeElement.ToShape.AbsoluteBounds, proposedPoint); if (this.ShapeElement.EndPoint != calculatedLocation) { using (Transaction transaction = this.Store.TransactionManager.BeginTransaction("Move To Anchor")) { this.ShapeElement.LinkPlacementEnd = placement; this.ShapeElement.SetEndPoint(calculatedLocation); this.ShapeElement.Layout(FixedGeometryPoints.Target); transaction.Commit(); } } }
/// <summary> /// Constructeur prenant le shape courant /// </summary> /// <param name="obj">The obj.</param> public PropagatesOperationsCommand(object obj) { LinkShape shape = obj as LinkShape; if (shape != null && shape.ModelElement is ClassUsesOperations) { ClassImplementation clazz = ((ClassUsesOperations)shape.ModelElement).Source as ClassImplementation; if (clazz == null) { return; } _sources.Add(clazz); if (clazz.Contract != null) { _sources.Add(clazz.Contract); } TypeWithOperations target = (TypeWithOperations)((ClassUsesOperations)shape.ModelElement).TargetService; if (target == null) { Debug.Assert(((ClassUsesOperations)shape.ModelElement).ExternalTargetService != null); _targets.Add(((ClassUsesOperations)shape.ModelElement).ExternalTargetService.ReferencedServiceContract); } else { _targets.Add(target); } } if (shape != null && shape.ModelElement is Implementation) { _sources.Add(((Implementation)shape.ModelElement).Contract); ClassImplementation clazz = ((Implementation)shape.ModelElement).ClassImplementation; _targets.Add(clazz); if (clazz.Contract != null) { _targets.Add(clazz.Contract); } } }
// connector type private void _connectorTypeCombo_SelectedValueChanged(object sender, EventArgs e) { LinkShape shape = LinkShape.Polyline; short segments = 1; switch (_connectorTypeCombo.SelectedIndex) { case 0: shape = LinkShape.Polyline; break; case 1: shape = LinkShape.Bezier; break; case 2: shape = LinkShape.Cascading; segments = 3; break; } diagram1.LinkShape = shape; diagram1.LinkSegments = segments; }
/// <summary> /// Creates the view model for the given link shape. /// </summary> /// <param name="nodeShapeType">Shape type for which the view model is to be created.</param> /// <param name="diagram">Diagram surface vm.</param> /// <param name="nodeShape">Link shape.</param> /// <returns> /// View model of type BaseDiagramItemLinkViewModel if a view model can be created for the given element. Null otherwise.</returns> public abstract BaseDiagramItemLinkViewModel CreateDiagramLinkViewModel(Guid nodeShapeType, DiagramSurfaceViewModel diagram, LinkShape nodeShape);
internal static List <PointD> GetConnectionLineSimple(LinkShape linkShape, NodeShape source, PointD startPointE, NodeShape target, PointD endPointE, LinkPlacement targetPlacement) { List <PointD> linePointsRet = new List <PointD>(); List <Point> linePoints = new List <Point>(); Rect rectSource = GetRectWithMargin(linkShape.LinkPlacementStart, source, 7.0); Point startPoint = GetOffsetPoint(linkShape.LinkPlacementStart, startPointE, rectSource); Point endPoint = endPointE.ToPoint(); linePoints.Add(startPoint); Point currentPoint = startPoint; if (!rectSource.Contains(endPoint)) { while (true) { if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource })) { linePoints.Add(endPoint); break; } bool sideFlag; Point n = GetNearestNeighborSource(linkShape.LinkPlacementStart, endPoint, rectSource, out sideFlag); linePoints.Add(n); currentPoint = n; if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource })) { linePoints.Add(endPoint); break; } else { Point n1, n2; GetOppositeCorners(linkShape.LinkPlacementStart, rectSource, out n1, out n2); if (sideFlag) { linePoints.Add(n1); } else { linePoints.Add(n2); } linePoints.Add(endPoint); break; } } } else { linePoints.Add(endPoint); } linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, linkShape.LinkPlacementStart, targetPlacement); foreach (Point p in linePoints) { linePointsRet.Add(new PointD(p)); } return(linePointsRet); }
internal static List <PointD> GetConnectionLine(LinkShape linkShape, NodeShape source, PointD startPointE, NodeShape target, PointD endPointE) { List <PointD> linePointsRet = new List <PointD>(); List <Point> linePoints = new List <Point>(); Rect rectSource = GetRectWithMargin(linkShape.LinkPlacementStart, source, 7.0); Rect rectTarget = GetRectWithMargin(linkShape.LinkPlacementEnd, target, 7.0); //Point startPointTemp = GetOffsetPoint(linkShape.LinkPlacementStart, linkShape.SourceAnchor, rectSource); //Point endPointTemp = GetOffsetPoint(linkShape.LinkPlacementEnd, linkShape.TargetAnchor, rectTarget); Point startPointTemp = GetOffsetPoint(linkShape.LinkPlacementStart, startPointE, rectSource); Point endPointTemp = GetOffsetPoint(linkShape.LinkPlacementEnd, endPointE, rectTarget); // Path start and end ... rectSource = CorrectRect(rectSource, linkShape.LinkPlacementStart, DistanceToElement); rectTarget = CorrectRect(rectTarget, linkShape.LinkPlacementEnd, DistanceToElement); Point startPoint, endPoint; CorrectStartEndpoints(linkShape, startPointTemp, endPointTemp, out startPoint, out endPoint); linePoints.Add(startPoint); Point currentPoint = startPoint; if (!rectTarget.Contains(currentPoint) && !rectSource.Contains(endPoint)) { while (true) { #region source node if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource, rectTarget })) { linePoints.Add(endPoint); currentPoint = endPoint; break; } Point neighbour = GetNearestVisibleNeighborTarget(currentPoint, endPoint, linkShape.TargetAnchor, linkShape.LinkPlacementEnd, rectSource, rectTarget); if (!double.IsNaN(neighbour.X)) { linePoints.Add(neighbour); linePoints.Add(endPoint); currentPoint = endPoint; break; } if (currentPoint == startPoint) { bool flag; Point n = GetNearestNeighborSource(linkShape.LinkPlacementStart, endPoint, rectSource, rectTarget, out flag); linePoints.Add(n); currentPoint = n; if (!IsRectVisible(currentPoint, rectTarget, new Rect[] { rectSource })) { Point n1, n2; GetOppositeCorners(linkShape.LinkPlacementStart, rectSource, out n1, out n2); if (flag) { linePoints.Add(n1); currentPoint = n1; } else { linePoints.Add(n2); currentPoint = n2; } if (!IsRectVisible(currentPoint, rectTarget, new Rect[] { rectSource })) { if (flag) { linePoints.Add(n2); currentPoint = n2; } else { linePoints.Add(n1); currentPoint = n1; } } } } #endregion #region target node else // from here on we jump to the sink node { Point n1, n2; // neighbour corner Point s1, s2; // opposite corner GetNeighborCorners(linkShape.LinkPlacementEnd, rectTarget, out s1, out s2); GetOppositeCorners(linkShape.LinkPlacementEnd, rectTarget, out n1, out n2); bool n1Visible = IsPointVisible(currentPoint, n1, new Rect[] { rectSource, rectTarget }); bool n2Visible = IsPointVisible(currentPoint, n2, new Rect[] { rectSource, rectTarget }); if (n1Visible && n2Visible) { if (rectSource.Contains(n1)) { linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else { linePoints.Add(s2); } linePoints.Add(endPoint); currentPoint = endPoint; break; } if (rectSource.Contains(n2)) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else { linePoints.Add(s1); } linePoints.Add(endPoint); currentPoint = endPoint; break; } if ((Distance(n1, endPoint) <= Distance(n2, endPoint))) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else { linePoints.Add(s1); } linePoints.Add(endPoint); currentPoint = endPoint; break; } else { linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else { linePoints.Add(s2); } linePoints.Add(endPoint); currentPoint = endPoint; break; } } else if (n1Visible) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else { linePoints.Add(s1); } linePoints.Add(endPoint); currentPoint = endPoint; break; } else { linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else { linePoints.Add(s2); } linePoints.Add(endPoint); currentPoint = endPoint; break; } } #endregion } } else { linePoints.Add(endPoint); } linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource, rectTarget }, linkShape.LinkPlacementStart, linkShape.LinkPlacementEnd); // insert temp startPoints linePoints.Insert(0, startPointTemp); linePoints.Add(endPointTemp); foreach (Point p in linePoints) { linePointsRet.Add(new PointD(p)); } return(linePointsRet); }
protected BaseDiagramItemLinkViewModel(ViewModelStore viewModelStore, DiagramSurfaceViewModel diagram, LinkShape linkShape) : base(viewModelStore, diagram, linkShape) { this.Geometry = ConvertEdgePointsToGeometry(linkShape.EdgePoints); this.edgePointsVM = new ObservableCollection <EdgePointViewModel>(); UpdateEdgePoints(); Subscribe(); }
/// <summary> /// Calculates an anchor position based on a horizontal and verical changes proposed. /// </summary> /// <param name="horizontalChange">Horizontal change.</param> /// <param name="verticalChange">Vertical change.</param> /// <returns>Calculated position.</returns> public virtual PointD CalcToAnchorPosition(double horizontalChange, double verticalChange) { PointD proposedPoint = new PointD(this.EndEdgePoint.X + horizontalChange, this.EndEdgePoint.Y + verticalChange); return(LinkShape.CalculateLocation(this.ShapeElement.ToShape.AbsoluteBounds, proposedPoint)); }
protected virtual void UpdateEdgePoints() { if (EdgePoints == null) { this.edgePointsVM = new ObservableCollection <EdgePointViewModel>(); } EdgePoints.Clear(); for (int i = 0; i < this.ShapeElement.EdgePoints.Count; i++) { EdgePointVMType t = EdgePointVMType.Normal; if (i == 0) { t = EdgePointVMType.Start; } else if (i == this.ShapeElement.EdgePoints.Count - 1) { t = EdgePointVMType.End; } else { continue; // TODO } EdgePointViewModel vm = new EdgePointViewModel(this.ViewModelStore, this.ShapeElement.EdgePoints[i], t); if (i > 0 && i < this.ShapeElement.EdgePoints.Count - 1) { //vm.EdgePointOperation = EdgePointVMOperation.m } else { RectangleD bounds; if (t == EdgePointVMType.Start) { bounds = this.ShapeElement.FromShape.AbsoluteBounds; } else { bounds = this.ShapeElement.ToShape.AbsoluteBounds; } EdgePoint p = this.ShapeElement.EdgePoints[i]; LinkPlacement placement = LinkShape.GetLinkPlacement(bounds, new PointD(p.X, p.Y)); switch (placement) { case LinkPlacement.Bottom: vm.EdgePointSide = EdgePointVMSide.Bottom; break; case LinkPlacement.Left: vm.EdgePointSide = EdgePointVMSide.Left; break; case LinkPlacement.Right: vm.EdgePointSide = EdgePointVMSide.Right; break; case LinkPlacement.Top: vm.EdgePointSide = EdgePointVMSide.Top; break; } } EdgePoints.Add(vm); } OnPropertyChanged("EdgePoints"); OnPropertyChanged("StartEdgePoint"); OnPropertyChanged("EndEdgePoint"); OnPropertyChanged("MiddleEdgePoint"); }