public StateContainerEditor() { InitializeComponent(); this.modelItemToUIElement = new Dictionary<ModelItem, UIElement>(); this.shapeLocations = new HashSet<Point>(); this.listenedTransitionCollections = new HashSet<ModelItem>(); this.transitionModelItemsAdded = new List<ModelItem>(); this.transitionModelItemsRemoved = new List<ModelItem>(); Binding readOnlyBinding = new Binding(); readOnlyBinding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DesignerView), 1); readOnlyBinding.Path = new PropertyPath(DesignerView.IsReadOnlyProperty); readOnlyBinding.Mode = BindingMode.OneWay; this.SetBinding(IsReadOnlyProperty, readOnlyBinding); this.Loaded += (s, e) => { if (this.ShouldInitialize()) { WorkflowViewElement parent = VisualTreeUtils.FindVisualAncestor<WorkflowViewElement>(this); this.ModelItem = parent.ModelItem; this.StateMachineModelItem = StateContainerEditor.GetStateMachineModelItem(this.ModelItem); this.Context = parent.Context; this.compositeViewEvents = parent; if (this.compositeViewEvents != null) { this.compositeViewEvents.RegisterDefaultCompositeView(this); } if (!this.populated) { this.Populate(); Selection.Subscribe(this.Context, this.OnSelectionChangedCallback); this.populated = true; } } }; this.Unloaded += (s, e) => { if (this.compositeViewEvents != null) { (compositeViewEvents).UnregisterDefaultCompositeView(this); this.compositeViewEvents = null; } if (this.populated) { this.Cleanup(); Selection.Unsubscribe(this.Context, this.OnSelectionChangedCallback); this.populated = false; } this.StateMachineModelItem = null; this.activeSrcConnectionPoint = null; this.activeDestConnectionPointForAutoSplit = null; this.activeSrcConnectionPointForAutoSplit = null; // selectedConnector is a placeholder for the last connector selected. this.selectedConnector = null; // Used for connector creation this.lastConnectionPointMouseUpElement = null; this.activeConnectionPointsAdorner = null; this.activeConnectionPoint = null; this.initialNode = null; // The ModelItem for the initial node this.initialModelItem = null; BindingOperations.ClearBinding(this, IsReadOnlyProperty); }; }
void AddConnectionPointsAdorner(UIElement element) { bool isSelected = false; if (element is VirtualizedContainerService.VirtualizingContainer) { isSelected = (((Selection)this.Context.Items.GetValue<Selection>()).SelectedObjects as ICollection<ModelItem>).Contains(((VirtualizedContainerService.VirtualizingContainer)element).ModelItem); } ConnectionPointsAdorner connectionPointsAdorner = new StateMachineConnectionPointsAdorner(element, ConnectionPointsToShow(element), isSelected); if ((element is VirtualizedContainerService.VirtualizingContainer) && ((VirtualizedContainerService.VirtualizingContainer)element).ModelItem.ItemType == typeof(State)) { connectionPointsAdorner.ToolTip = SR.TransitionConnectionPointTooltip; } else if (element is StartSymbol) { connectionPointsAdorner.ToolTip = SR.InitialStateConnectionPointTooltip; } AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(element); Fx.Assert(adornerLayer != null, "Cannot get AdornerLayer."); adornerLayer.Add(connectionPointsAdorner); // The outmostEditor should handle all the connection point related events for all its descendants StateContainerEditor stateMachineContainer = this.GetStateMachineContainerEditor(); connectionPointsAdorner.MouseDown += new MouseButtonEventHandler(stateMachineContainer.OnConnectionPointMouseDown); connectionPointsAdorner.MouseUp += new MouseButtonEventHandler(stateMachineContainer.OnConnectionPointMouseUp); connectionPointsAdorner.MouseLeave += new MouseEventHandler(stateMachineContainer.OnConnectionPointMouseLeave); this.activeConnectionPointsAdorner = connectionPointsAdorner; }
private void RemoveConnectionPointsAdorner(UIElement adornedElement) { IEnumerable<Adorner> adornersRemoved = RemoveAdorner(adornedElement, typeof(ConnectionPointsAdorner)); Fx.Assert(adornersRemoved.Count() <= 1, "There should be at most one ConnectionPointsAdorner"); if (adornersRemoved.Count() == 1) { ConnectionPointsAdorner adorner = (ConnectionPointsAdorner)adornersRemoved.First(); Fx.Assert(object.Equals(this.activeConnectionPointsAdorner, adorner), "The adorner removed should be the same as the active adorner."); this.activeConnectionPointsAdorner = null; foreach (ConnectionPoint connectionPoint in adorner.ConnectionPoints) { connectionPoint.IsEnabled = false; if (object.Equals(this.activeConnectionPoint, connectionPoint)) { this.activeConnectionPoint = null; } } } }
internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, ConnectionPointsAdorner adorner) { FreeFormPanel panel = VisualTreeUtils.FindVisualAncestor<FreeFormPanel>(adorner.AdornedElement); return ConnectionPointHitTest(hitPoint, adorner.ConnectionPoints, panel); }
internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, ConnectionPointsAdorner adorner) { FreeFormPanel panel = VisualTreeUtils.FindVisualAncestor <FreeFormPanel>(adorner.AdornedElement); return(ConnectionPointHitTest(hitPoint, adorner.ConnectionPoints, panel)); }
void UpdateEditPoints(Point newPoint) { if (this.editPoints.Count < 2 || this.editPoints[0].Type != EditPoint.EditPointTypes.ConnectionEditPoint || this.editPoints[this.editPoints.Count - 1].Type != EditPoint.EditPointTypes.ConnectionEditPoint) { Fx.Assert(false, "EditPoints are invalid"); return; } if (this.activeEditPoint != null) { int activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint); EditPoint previous = (activeEditPointIndex > 0) ? this.editPoints[activeEditPointIndex - 1] : null; EditPoint next = (activeEditPointIndex < this.editPoints.Count - 1) ? this.editPoints[activeEditPointIndex + 1] : null; //Note that extra edit points are only added if we are connected to connection point if (previous != null && previous.Type == EditPoint.EditPointTypes.ConnectionEditPoint) { double slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, this.activeEditPoint.Location); Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; int editPointOffset = Convert.ToInt32(DesignerGeometryHelper.DistanceBetweenPoints(previous.Location, (next != null) ? next.Location : this.activeEditPoint.Location)) / 4; if (orientation == Orientation.Horizontal) { editPointOffset *= (previous.Location.X < this.activeEditPoint.Location.X) ? 1 : -1; } else { editPointOffset *= (previous.Location.Y < this.activeEditPoint.Location.Y) ? 1 : -1; } activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint); Point editPointLocation = (orientation == Orientation.Horizontal) ? new Point(previous.Location.X + editPointOffset, previous.Location.Y) : new Point(previous.Location.X, previous.Location.Y + editPointOffset); previous = new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation); this.editPoints.InsertRange(activeEditPointIndex, new EditPoint[] { new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation), previous }); } if (next != null && next.Type == EditPoint.EditPointTypes.ConnectionEditPoint) { double slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(this.activeEditPoint.Location, next.Location); Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; int editPointOffset = Convert.ToInt32(DesignerGeometryHelper.DistanceBetweenPoints((previous != null) ? previous.Location : this.activeEditPoint.Location, next.Location)) / 4; if (orientation == Orientation.Horizontal) { editPointOffset *= (this.activeEditPoint.Location.X < next.Location.X) ? -1 : 1; } else { editPointOffset *= (this.activeEditPoint.Location.Y < next.Location.Y) ? -1 : 1; } activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint); Point editPointLocation = (orientation == Orientation.Horizontal) ? new Point(next.Location.X + editPointOffset, next.Location.Y) : new Point(next.Location.X, next.Location.Y + editPointOffset); next = new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation); this.editPoints.InsertRange(activeEditPointIndex + 1, new EditPoint[] { next, new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation) }); } if (this.activeEditPoint.Type == EditPoint.EditPointTypes.ConnectionEditPoint) { Fx.Assert(this.editPoints[0].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong."); Fx.Assert(this.editPoints[editPoints.Count - 1].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong."); this.activeEditPoint.Location = newPoint; Fx.Assert(this.editPoints.Count > 0, "Some edit point should exist"); ConnectionPoint targetConnPt = null; Point[] points = null; Point begin = this.editPoints[0].Location; Point end = this.editPoints[this.editPoints.Count - 1].Location; if (typeof(ConnectionPointsAdorner).IsAssignableFrom(Mouse.DirectlyOver.GetType())) { ConnectionPointsAdorner connPtsAdorner = Mouse.DirectlyOver as ConnectionPointsAdorner; targetConnPt = FreeFormPanel.ConnectionPointHitTest(newPoint, connPtsAdorner); } if (activeEditPointIndex == 0) { // We are dragging the source point of a connector. ConnectionPoint destConnPt = FreeFormPanel.GetDestinationConnectionPoint(this.editedConnector); if (targetConnPt != null) { points = ConnectorRouter.Route(parentPanel, targetConnPt, destConnPt); this.activeEditPoint.Location = targetConnPt.Location; } else { points = ConnectorRouter.Route(parentPanel, begin, destConnPt); } } else { // We are dragging the destination point of a connector. ConnectionPoint srcConnPt = FreeFormPanel.GetSourceConnectionPoint(this.editedConnector); if (targetConnPt != null) { points = ConnectorRouter.Route(parentPanel, srcConnPt, targetConnPt); this.activeEditPoint.Location = targetConnPt.Location; } else { points = ConnectorRouter.Route(parentPanel, srcConnPt, end); } } //When we start editing the end point we need to clear the slate and start over List <EditPoint> newEditPoints = new List <EditPoint>(); if (points != null && points.Length > 1) { RemoveEditPoints(EditPoint.EditPointTypes.MultiSegmentEditPoint); for (int i = 1; i < points.Length - 1; ++i) { newEditPoints.Add(new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, points[i])); } this.editPoints.InsertRange(1, newEditPoints.ToArray()); } } else if (this.activeEditPoint.Type == EditPoint.EditPointTypes.MultiSegmentEditPoint) { if (previous != null && previous.Type != EditPoint.EditPointTypes.ConnectionEditPoint && next != null && next.Type != EditPoint.EditPointTypes.ConnectionEditPoint) { //Update the previous point double slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, this.activeEditPoint.Location); Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; previous.Location = (orientation == Orientation.Horizontal) ? new Point(previous.Location.X, newPoint.Y) : new Point(newPoint.X, previous.Location.Y); //Update the next point slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(this.activeEditPoint.Location, next.Location); orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; next.Location = (orientation == Orientation.Horizontal) ? new Point(next.Location.X, newPoint.Y) : new Point(newPoint.X, next.Location.Y); //Update the current point this.activeEditPoint.Location = newPoint; } else { Fx.Assert(false, "Should not be here. UpdateEditPoints failed."); } } } // Remove all the redundant edit points RemoveCoincidingEditPoints(); bool validEditPoints = ValidateEditPoints(); Fx.Assert(validEditPoints, "Validating EditPoints failed."); }