/// <summary> /// Adds new internal point to the junction. /// </summary> /// <param name="position">position where new point is added</param> /// <param name="index">index where new point is inserted in <see cref="Points"/> collection</param> public void BreakLine(Point position, int index) { if (AutoPosModeOnly) { return; } JunctionPoint newPoint = new JunctionPoint(XCaseCanvas) { Junction = this, OrderInJunction = index }; XCaseCanvas.Children.Add(newPoint); if (SourceElement == TargetElement) { newPoint.SnapTo(SourceElement as DragThumb, true); } //newPoint.SetPreferedPosition(position.X - (newPoint.ReferentialElement != null ? newPoint.ReferentialElement.CanvasPosition.X : 0), position.Y - (newPoint.ReferentialElement != null ? newPoint.ReferentialElement.CanvasPosition.Y : 0)); newPoint.SetPreferedPosition(position.X, position.Y); Canvas.SetZIndex(newPoint, Canvas.GetZIndex(this) + 1); for (int i = index; i < Points.Count; i++) { Points[i].OrderInJunction++; } Points.Insert(newPoint.OrderInJunction, newPoint); //only re-rendering is not enough, whole geometry must be invalidated... InvalidateGeometry(); UpdateLayout(); }
/// <summary> /// Changes the <see cref="TargetElement"/> from current target element to /// <paramref name="targetElement"/> /// </summary> /// <param name="targetElement">new target element.</param> internal void ReconnectTargetElement(IConnectable targetElement) { if (targetElement == TargetElement) { return; } if (Points.Count < 2 /*|| EndPoint.Parent == null*/) { return; } if (TargetElement != null) { TargetElement.SizeChanged -= TargetElement_SizeChanged; ((IConnectable)TargetElement).UnHighlight(); TargetElement = null; } Points.RemoveAt(Points.Count - 1); TargetElement = (Control)targetElement; ((IConnectable)TargetElement).Highlight(); JunctionPoint endPoint = targetElement.CreateJunctionEnd(); endPoint.Junction = this; endPoint.OrderInJunction = 1; endPoint.ContextMenu = null; Points.Add(endPoint); //TargetElement.SizeChanged += TargetElement_SizeChanged; Cursor = Cursors.Hand; InvalidateGeometry(); }
/// <summary> /// Creates <see cref="JunctionPoint"/> on a specific position. /// </summary> /// <param name="preferedPosition">The prefered position for a new JunctionPoint</param> /// <returns>new <see cref="JunctionPoint"/></returns> public virtual JunctionPoint CreateJunctionEnd(Point preferedPosition) { JunctionPoint junctionEnd = CreateJunctionEnd(); junctionEnd.SetPreferedPosition(preferedPosition); createdJunctionEnds.Add(junctionEnd); return(junctionEnd); }
/// <summary> /// Creates <see cref="JunctionPoint"/>. /// </summary> /// <returns>new <see cref="JunctionPoint"/></returns> public virtual JunctionPoint CreateJunctionEnd() { JunctionPoint junctionEnd = new JunctionPoint(XCaseCanvas) { OwnerControl = this, Placement = EPlacementKind.ParentAutoPos, ParentControl = this }; ((Canvas)connectorDecorator.Template.FindName("ConnectorDecoratorGrid", connectorDecorator)).Children.Add(junctionEnd); Canvas.SetZIndex(junctionEnd, System.Windows.Controls.Canvas.GetZIndex(connectorDecorator) + 10); junctionEnd.Visibility = Visibility.Visible; createdJunctionEnds.Add(junctionEnd); return(junctionEnd); }
/// <summary> /// Draws junction between <paramref name="c1"/> and <paramref name="endPoint"/>. This method is supposed /// to be used when connection is dragged between two elements (one of them is <paramref name="c1"/>) /// and <paramref name="endPoint"/> is being dragged "on the way" to the second element. /// </summary> /// <param name="c1">connected element</param> /// <param name="endPoint">dragged point</param> /// <param name="canvas">canvas where the junction is created</param> internal void DragConnection(IConnectable c1, JunctionPoint endPoint, XCaseCanvas canvas) { SourceElement = c1 as Control; JunctionPoint startPoint = c1.CreateJunctionEnd(); startPoint.Junction = this; startPoint.OrderInJunction = 0; endPoint.Junction = this; endPoint.OrderInJunction = 1; Points.Add(startPoint); Points.Add(endPoint); TargetElement = null; }
/// <summary> /// Finalizes dragging of a line segment. /// </summary> /// <param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs"/> that contains the event data. The event data reports that the mouse button was released.</param> /// <seealso cref="AutoPosModeOnly"/> protected override void OnMouseUp(MouseButtonEventArgs e) { if (segmentDragging) { segmentDragging = false; JunctionPointCommand.PointMoveDataDictionary pointMoveDataCollection = new JunctionPointCommand.PointMoveDataDictionary(); foreach (KeyValuePair <DragThumb, rPoint> pair in startPositions) { JunctionPoint junctionPoint = (JunctionPoint)pair.Key; if (junctionPoint.Position == pair.Value) { continue; } JunctionPointCommand.PointMoveData data = new JunctionPointCommand.PointMoveData { Index = junctionPoint.OrderInJunction, OldPosition = pair.Value, NewPosition = new rPoint(junctionPoint.Position) { tag = junctionPoint.Placement }, }; if (!pointMoveDataCollection.ContainsKey(viewHelperPointsCollection)) { pointMoveDataCollection[viewHelperPointsCollection] = new List <JunctionPointCommand.PointMoveData>(); } pointMoveDataCollection[viewHelperPointsCollection].Add(data); } if (pointMoveDataCollection.Count > 0) { JunctionPointCommand junctionPointCommand = (JunctionPointCommand)JunctionPointCommandFactory.Factory().Create(XCaseCanvas.Controller); junctionPointCommand.Action = JunctionPointCommand.EJunctionPointAction.MovePoints; junctionPointCommand.PointMoveDataCollection = pointMoveDataCollection; junctionPointCommand.Description = CommandDescription.MOVE_JUNCTION_SEGMENT; junctionPointCommand.Execute(); } } this.ReleaseMouseCapture(); base.OnMouseUp(e); }
/// <summary> /// Override of <see cref="DragThumb.AdjustDrag" /> aligns dragged point to the borders of its <see cref="OwnerControl"/> /// </summary> /// <param name="deltaEventArgs"></param> protected override void AdjustDrag(ref DragDeltaEventArgs deltaEventArgs) { base.AdjustDrag(ref deltaEventArgs); if (OwnerControl != null) { Rect bounds = OwnerControl.GetBounds(); Point p = new Point(CanvasPosition.X + deltaEventArgs.HorizontalChange, CanvasPosition.Y + deltaEventArgs.VerticalChange); Point snapped = bounds.SnapPointToRectangle(p); deltaEventArgs = new DragDeltaEventArgs(snapped.X - CanvasPosition.X, snapped.Y - CanvasPosition.Y); } else { JunctionPoint rightNeighbour = Junction.Points.ElementAtOrDefault(OrderInJunction + 1); JunctionPoint leftNeighbour = Junction.Points.ElementAtOrDefault(OrderInJunction - 1); const double SNAP_RATIO = 14; foreach (JunctionPoint neighbour in new[] { leftNeighbour, rightNeighbour }) { bool isEndPoint = neighbour == Junction.StartPoint || neighbour == Junction.EndPoint; if (neighbour != null && (!isEndPoint || neighbour.Placement == EPlacementKind.AbsoluteSubCanvas)) { double nx = neighbour.CanvasPosition.X; double ny = neighbour.CanvasPosition.Y; double deltax = deltaEventArgs.HorizontalChange; double deltay = deltaEventArgs.VerticalChange; double diff; if (ShouldSnap(MousePoint.Y, ny, SNAP_RATIO, out diff)) { ShouldSnap(CanvasPosition.Y + deltaEventArgs.VerticalChange, ny, SNAP_RATIO, out diff); deltay += diff; deltaEventArgs = new DragDeltaEventArgs(deltax, deltay); } else if (ShouldSnap(MousePoint.X, nx, SNAP_RATIO, out diff)) { ShouldSnap(CanvasPosition.X + deltaEventArgs.HorizontalChange, nx, SNAP_RATIO, out diff); deltax += diff; deltaEventArgs = new DragDeltaEventArgs(deltax, deltay); } } } } }
/// <summary> /// Changes the <see cref="TargetElement"/> from current target element to /// <paramref name="newEndPoint"/> /// </summary> /// <param name="newEndPoint">new end point</param> internal void ReconnectTargetElement(JunctionPoint newEndPoint) { if (TargetElement != null) { TargetElement.SizeChanged -= TargetElement_SizeChanged; ((IConnectable)TargetElement).UnHighlight(); TargetElement = null; } if (EndPoint.Parent != null) { ((Canvas)EndPoint.Parent).Children.Remove(EndPoint); } Points.RemoveAt(Points.Count - 1); newEndPoint.Junction = this; newEndPoint.OrderInJunction = Points.Count; Points.Add(newEndPoint); Cursor = Cursors.Arrow; InvalidateGeometry(); }
/// <summary> /// Dragging beggins, the <paramref name="item"/> will be the source of the connection. /// </summary> /// <param name="item">item clicked</param> /// <param name="e">event arguments</param> public override void SelectableItemPreviewMouseDown(ISelectable item, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Right) { Canvas.State = ECanvasState.Normal; e.Handled = true; return; } base.SelectableItemPreviewMouseDown(item, e); if (item is IConnectable && e.ChangedButton == MouseButton.Left) { Canvas.CaptureMouse(); foreach (ISelectable i in Canvas.SelectedItems) { i.IsSelected = false; } Canvas.SelectedItems.Clear(); draggedPoint = new JunctionPoint(Canvas) { Width = 0, Height = 0 }; Canvas.Children.Add(draggedPoint); draggedPoint.SetPreferedPosition(e.GetPosition(Canvas)); SetZIndex(draggedPoint, -5); draggedPoint.Visibility = Visibility.Visible; //throw new NotImplementedException("Method or operation is not implemented."); draggedConnection = new XCaseJunction(Canvas); draggedPoint.Junction = draggedConnection; (item as IConnectable).Highlight(); InConnectionDrag = true; draggedConnection.DragConnection(item as IConnectable, draggedPoint, Canvas); Canvas.Children.Add(draggedConnection); draggedConnection.EndCapStyle = JunctionGeometryHelper.GetCap(DraggedConnectionType); e.Handled = true; draggedConnection.InvalidateGeometry(); ConnectableItemMouseEnter((IConnectable)item); } }
/// <summary> /// Drags the completed. /// </summary> /// <param name="finalPoint">The final point.</param> /// <param name="totalShift">The total shift.</param> protected virtual void DragCompleted(Point finalPoint, Vector totalShift) { if (visualAidsAdorner != null) { AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(XCaseCanvas); adornerLayer.Remove(visualAidsAdorner); visualAidsAdorner = null; } if (DragStartPoint != finalPoint) { DiagramController controller = XCaseCanvas.Controller; MacroCommand <DiagramController> moveMacroCommand = MacroCommandFactory <DiagramController> .Factory().Create(controller); moveMacroCommand.Description = CommandDescription.MOVE_MACRO; JunctionPointCommand.PointMoveDataDictionary pointMoveDataCollection = null; foreach (KeyValuePair <DragThumb, rPoint> pair in startPositions) { if (pair.Key is IAlignable) { IAlignable element = (IAlignable)pair.Key; DragThumb dragThumb = element as DragThumb; double _x; double _y; if (dragThumb != null && dragThumb.Placement == EPlacementKind.RelativeCanvas) { _x = dragThumb.Left - dragThumb.ReferentialElement.CanvasPosition.X; _y = dragThumb.Top - dragThumb.ReferentialElement.CanvasPosition.Y; } else { _x = element.Left; _y = element.Top; } CommandBase command = ViewController.CreateMoveCommand( _x, _y, element.ViewHelper, controller); moveMacroCommand.Commands.Add(command); } else if (pair.Key is JunctionPoint) { JunctionPoint junctionPoint = (JunctionPoint)pair.Key; JunctionPointCommand.PointMoveData data = new JunctionPointCommand.PointMoveData { Index = junctionPoint.OrderInJunction, OldPosition = pair.Value, NewPosition = new rPoint(junctionPoint.Position) { tag = junctionPoint.Placement }, }; if (pointMoveDataCollection == null) { pointMoveDataCollection = new JunctionPointCommand.PointMoveDataDictionary(); } if (!pointMoveDataCollection.ContainsKey(junctionPoint.Junction.viewHelperPointsCollection)) { pointMoveDataCollection[junctionPoint.Junction.viewHelperPointsCollection] = new List <JunctionPointCommand.PointMoveData>(); } pointMoveDataCollection[junctionPoint.Junction.viewHelperPointsCollection].Add(data); } } // add one command for each affected junction if (pointMoveDataCollection != null) { JunctionPointCommand junctionPointCommand = (JunctionPointCommand)JunctionPointCommandFactory.Factory().Create(controller); junctionPointCommand.Action = JunctionPointCommand.EJunctionPointAction.MovePoints; junctionPointCommand.PointMoveDataCollection = pointMoveDataCollection; junctionPointCommand.Description = CommandDescription.MOVE_JUNCTION_POINTS; moveMacroCommand.Commands.Add(junctionPointCommand); } moveMacroCommand.Execute(); if (Dropped != null) { Dropped(); } } }
/// <summary> /// If mouse is over a connectable item, <see cref="DraggedConnectionProcessor"/>'s /// <see cref="IDraggedConnectionProcessor.DragConnectionCompleted"/> handler is called /// to finilize the operation. Otherwise nothing happens. /// </summary> /// <param name="e"></param> public override void OnMouseUp(MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Right) { Canvas.State = ECanvasState.Normal; e.Handled = true; return; } base.OnMouseUp(e); Canvas.ReleaseMouseCapture(); InConnectionDrag = false; Mouse.SetCursor(Cursors.Arrow); if (draggedConnection != null) { if (draggedConnection.SourceElement != null) { ((IConnectable)draggedConnection.SourceElement).UnHighlight(); } if (draggedConnection.TargetElement != null) { ((IConnectable)draggedConnection.TargetElement).UnHighlight(); } draggedConnection.DeleteFromCanvas(); if (DraggedConnectionProcessor != null) { Element sourceElement = null; Element targetElement = null; if (draggedConnection.SourceElement is XCaseViewBase) { sourceElement = ((XCaseViewBase)draggedConnection.SourceElement).ModelElement; } if (draggedConnection.TargetElement is XCaseViewBase) { targetElement = ((XCaseViewBase)draggedConnection.TargetElement).ModelElement; } if (draggedConnection.SourceElement != null && ItemDraggedOver == draggedConnection.SourceElement) { targetElement = sourceElement; } if (draggedConnection.SourceElement is PIM_Class && draggedConnection.TargetElement is AssociationDiamond) { targetElement = ((PIM_Class)draggedConnection.SourceElement).ModelElement; sourceElement = ((AssociationDiamond)draggedConnection.TargetElement).Association.Association; } if (draggedConnection.SourceElement is AssociationDiamond && draggedConnection.TargetElement is PIM_Class) { targetElement = ((PIM_Class)draggedConnection.TargetElement).ModelElement; sourceElement = ((AssociationDiamond)draggedConnection.SourceElement).Association.Association; } DraggedConnectionProcessor.DragConnectionCompleted(sourceElement, targetElement); ItemDraggedOver = (IConnectable)draggedConnection.TargetElement; } } draggedConnection = null; Canvas.Children.Remove(draggedPoint); draggedPoint = null; }