//Calls the Line routing algorithm and populates the points collection of the connector.
        void RoutePolyLine(Connector connector)
        {
            Point[]      pts    = ConnectorRouter.Route(this, FreeFormPanel.GetSourceConnectionPoint(connector), FreeFormPanel.GetDestinationConnectionPoint(connector));
            List <Point> points = new List <Point>(pts);

            if (pts != null)
            {
                UpdateConnectorPoints(connector, points);
            }
        }
        // referenceConnector is used when we are re-linking the connector.
        internal ConnectorCreationResult CreateConnectorGesture(ConnectionPoint sourceConnectionPoint, ConnectionPoint destConnectionPoint, Connector referenceConnector, bool isConnectorStartMoved)
        {
            Fx.Assert(sourceConnectionPoint != null, "sourceConnectionPoint is null.");
            Fx.Assert(destConnectionPoint != null, "destConnectionPoint is null.");
            ConnectorCreationResult result = ConnectorCreationResult.OtherFailure;

            if (destConnectionPoint.PointType != ConnectionPointKind.Outgoing && sourceConnectionPoint.PointType != ConnectionPointKind.Incoming)
            {
                if (sourceConnectionPoint.ParentDesigner is VirtualizedContainerService.VirtualizingContainer)
                {
                    //bool sameDestination = false;
                    ModelItem refTransitionModelItem = null;
                    if (referenceConnector != null)
                    {
                        refTransitionModelItem = StateContainerEditor.GetConnectorModelItem(referenceConnector);
                    }

                    using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.CreateTransition))
                    {
                        if (refTransitionModelItem != null)
                        {
                            this.CreateTransition(sourceConnectionPoint, destConnectionPoint, refTransitionModelItem, isConnectorStartMoved);
                        }
                        else
                        {
                            this.CreateTransition(sourceConnectionPoint, destConnectionPoint, null, false);
                        }
                        result = ConnectorCreationResult.Success;
                        es.Complete();
                    }
                }
                else if (sourceConnectionPoint.ParentDesigner is StartSymbol)
                {
                    ModelItem stateModelItem = ((VirtualizedContainerService.VirtualizingContainer)destConnectionPoint.ParentDesigner).ModelItem;

                    if (IsFinalState(stateModelItem))
                    {
                        result = ConnectorCreationResult.CannotSetFinalStateAsInitialState;
                    }
                    else
                    {
                        using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.SetInitialState))
                        {
                            this.StateMachineModelItem.Properties[StateMachineDesigner.InitialStatePropertyName].SetValue(stateModelItem);
                            PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnectionPoint, destConnectionPoint));
                            this.StoreConnectorLocationViewState(this.StateMachineModelItem, connectorViewState, true);
                            result = ConnectorCreationResult.Success;
                            es.Complete();
                        }
                    }
                }
            }
            return(result);
        }
 void RerouteIfInvalid(Connector connector, ModelItem linkModelItem)
 {
     if (connector.Points != null)
     {
         Point[] points = new Point[connector.Points.Count];
         connector.Points.CopyTo(points, 0);
         if (!ConnectorRouter.AreSegmentsValid(points))
         {
             Reroute(connector, false);
         }
     }
 }
Exemplo n.º 4
0
        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)
            {
                Debug.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)
                {
                    Debug.Assert(this.editPoints[0].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong.");
                    Debug.Assert(this.editPoints[editPoints.Count - 1].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong.");
                    this.activeEditPoint.Location = newPoint;

                    Point begin, end;
                    Debug.Assert(this.editPoints.Count > 0, "Some edit point should exist");
                    begin = this.editPoints[0].Location;
                    end   = this.editPoints[this.editPoints.Count - 1].Location;

                    //When we start editing the end point we need to clear the slate and start over
                    List <EditPoint> newEditPoints = new List <EditPoint>();
                    Point[]          points        = ConnectorRouter.Route(parentPanel, begin, end);
                    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
                    {
                        Debug.Assert(false, "Should not be here. UpdateEditPoints failed.");
                    }
                }
            }

            // Remove all the redundant edit points
            RemoveCoincidingEditPoints();

            bool validEditPoints = ValidateEditPoints();

            Debug.Assert(validEditPoints, "Validating EditPoints failed.");
        }
        // referenceTransitionModelItem is used when a connector is re-linked.
        void CreateTransition(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, ModelItem referenceTransitionModelItem, bool isSourceMoved)
        {
            VirtualizedContainerService.VirtualizingContainer srcDesigner = sourceConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            Fx.Assert(srcDesigner != null, "srcDesigner should not be null.");
            VirtualizedContainerService.VirtualizingContainer destDesigner = destConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            Fx.Assert(destDesigner != null, "destDesigner should not be null.");

            ModelItem srcModelItem        = srcDesigner.ModelItem;
            ModelItem destModelItem       = destDesigner.ModelItem;
            ModelItem transitionModelItem = null;

            // We are moving the connector.
            if (referenceTransitionModelItem != null && referenceTransitionModelItem.ItemType == typeof(Transition))
            {
                transitionModelItem = referenceTransitionModelItem;
                // We are moving the start of the connector. We only preserve the trigger if it is not shared.
                if (isSourceMoved)
                {
                    Transition referenceTransition = referenceTransitionModelItem.GetCurrentValue() as Transition;
                    ModelItem  stateModelItem      = GetParentStateModelItemForTransition(referenceTransitionModelItem);
                    State      state           = stateModelItem.GetCurrentValue() as State;
                    bool       isTriggerShared = false;
                    foreach (Transition transition in state.Transitions)
                    {
                        if (transition != referenceTransition && transition.Trigger == referenceTransition.Trigger)
                        {
                            isTriggerShared = true;
                            break;
                        }
                    }
                    if (isTriggerShared)
                    {
                        transitionModelItem.Properties[TransitionDesigner.TriggerPropertyName].SetValue(null);
                    }
                }
                transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destModelItem);
                srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem);
            }
            // We are creating a new connector.
            else
            {
                ModelItem  stateMachineModelItem = GetStateMachineModelItem(srcModelItem);
                Transition newTransition         = new Transition()
                {
                    DisplayName = StateContainerEditor.GenerateTransitionName(stateMachineModelItem)
                };
                newTransition.To = destModelItem.GetCurrentValue() as State;
                // Assign the shared trigger.
                if (sourceConnPoint.AttachedConnectors.Count > 0)
                {
                    Connector  connector          = sourceConnPoint.AttachedConnectors[0];
                    Transition existingTransition = StateContainerEditor.GetConnectorModelItem(connector).GetCurrentValue() as Transition;
                    newTransition.Trigger = existingTransition.Trigger;
                }
                transitionModelItem = srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(newTransition);
            }
            if (transitionModelItem != null)
            {
                // if the transition connection is re-routed, the SrcConnPointIndex needs to be updated.
                PointCollection connectorViewState       = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));
                int             srcConnectionPointIndex  = StateContainerEditor.GetConnectionPoints(sourceConnPoint.ParentDesigner).IndexOf(sourceConnPoint);
                int             destConnectionPointIndex = StateContainerEditor.GetConnectionPoints(destConnPoint.ParentDesigner).IndexOf(destConnPoint);
                this.StoreConnectorLocationViewState(transitionModelItem, connectorViewState, true);
                this.ViewStateService.StoreViewStateWithUndo(transitionModelItem, SrcConnectionPointIndexStateKey, srcConnectionPointIndex);
                this.ViewStateService.StoreViewStateWithUndo(transitionModelItem, DestConnectionPointIndexStateKey, destConnectionPointIndex);
            }
        }
Exemplo n.º 6
0
        // referenceTransitionModelItem is used when a connector is re-linked.
        void CreateTransition(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, ModelItem referenceTransitionModelItem, bool isSourceMoved)
        {
            Debug.Assert(this.IsOutmostStateContainerEditor(), "Should only be called by the outmost editor.");

            WorkflowViewElement srcDesigner  = sourceConnPoint.ParentDesigner as WorkflowViewElement;
            WorkflowViewElement destDesigner = destConnPoint.ParentDesigner as WorkflowViewElement;

            Debug.Assert(srcDesigner is StateDesigner && destDesigner is StateDesigner, "The source and destination designers should both be StateDesigner");

            ModelItem srcModelItem        = srcDesigner.ModelItem;
            ModelItem destModelItem       = destDesigner.ModelItem;
            ModelItem transitionModelItem = null;

            // We are moving the connector.
            if (referenceTransitionModelItem != null && referenceTransitionModelItem.ItemType == typeof(Transition))
            {
                transitionModelItem = referenceTransitionModelItem;
                // We are moving the start of the connector. We only preserve the trigger if it is not shared.
                if (isSourceMoved)
                {
                    Transition referenceTransition = referenceTransitionModelItem.GetCurrentValue() as Transition;
                    ModelItem  stateModelItem      = GetParentStateModelItemForTransition(referenceTransitionModelItem);
                    State      state           = stateModelItem.GetCurrentValue() as State;
                    bool       isTriggerShared = false;
                    foreach (Transition transition in state.Transitions)
                    {
                        if (transition != referenceTransition && transition.Trigger == referenceTransition.Trigger)
                        {
                            isTriggerShared = true;
                            break;
                        }
                    }
                    if (isTriggerShared)
                    {
                        transitionModelItem.Properties[TransitionDesigner.TriggerPropertyName].SetValue(null);
                    }
                }
                transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destModelItem);
                srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem);
            }
            // We are creating a new connector.
            else
            {
                Transition newTransition = new Transition()
                {
                    DisplayName = string.Empty
                };
                newTransition.To = destModelItem.GetCurrentValue() as State;
                // Assign the shared trigger.
                if (sourceConnPoint.AttachedConnectors.Count > 0)
                {
                    Connector  connector          = sourceConnPoint.AttachedConnectors[0];
                    Transition existingTransition = StateContainerEditor.GetConnectorModelItem(connector).GetCurrentValue() as Transition;
                    newTransition.Trigger = existingTransition.Trigger;
                }
                transitionModelItem = srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(newTransition);
            }
            if (transitionModelItem != null)
            {
                PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));
                this.StoreConnectorLocationViewState(transitionModelItem, connectorViewState, true);
            }
        }
Exemplo n.º 7
0
        // referenceConnector is used when we are re-linking the connector.
        internal ConnectorCreationResult CreateConnectorGesture(ConnectionPoint sourceConnectionPoint, ConnectionPoint destConnectionPoint, Connector referenceConnector, bool isConnectorStartMoved)
        {
            Debug.Assert(this.IsOutmostStateContainerEditor(), "Should only be called by the outmost editor.");
            Debug.Assert(sourceConnectionPoint != null, "sourceConnectionPoint is null.");
            Debug.Assert(destConnectionPoint != null, "destConnectionPoint is null.");
            ConnectorCreationResult result = ConnectorCreationResult.OtherFailure;

            if (destConnectionPoint.PointType != ConnectionPointType.Outgoing && sourceConnectionPoint.PointType != ConnectionPointType.Incoming)
            {
                if (sourceConnectionPoint.ParentDesigner is StateDesigner)
                {
                    bool      sameDestination        = false;
                    ModelItem refTransitionModelItem = null;
                    if (referenceConnector != null)
                    {
                        refTransitionModelItem = StateContainerEditor.GetConnectorModelItem(referenceConnector);
                        ModelItem destStateModelItem = ((StateDesigner)destConnectionPoint.ParentDesigner).ModelItem;
                        if (refTransitionModelItem != null && refTransitionModelItem.Properties[TransitionDesigner.ToPropertyName].Value == destStateModelItem)
                        {
                            sameDestination = true;
                        }
                    }

                    // We do not allow transitions to composite states unless we don't change the transition destination
                    // (e.g., we are moving the start of a connector).
                    if (!sameDestination && !((StateDesigner)destConnectionPoint.ParentDesigner).IsSimpleState())
                    {
                        result = ConnectorCreationResult.CannotCreateTransitionToCompositeState;
                    }
                    // We do not allow transitions from an ancestor to its descendant
                    else if (StateContainerEditor.IsDescendantStateOf(((StateDesigner)destConnectionPoint.ParentDesigner).ModelItem, ((StateDesigner)sourceConnectionPoint.ParentDesigner).ModelItem))
                    {
                        result = ConnectorCreationResult.CannotCreateTransitionFromAncestorToDescendant;
                    }
                    else
                    {
                        using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.CreateTransition))
                        {
                            if (refTransitionModelItem != null)
                            {
                                this.CreateTransition(sourceConnectionPoint, destConnectionPoint, refTransitionModelItem, isConnectorStartMoved);
                            }
                            else
                            {
                                this.CreateTransition(sourceConnectionPoint, destConnectionPoint, null, false);
                            }
                            result = ConnectorCreationResult.Success;
                            es.Complete();
                        }
                    }
                }
                else if (sourceConnectionPoint.ParentDesigner is InitialNode)
                {
                    StateDesigner destDesigner = (StateDesigner)destConnectionPoint.ParentDesigner;
                    // We only allow simple states to be set as the initial state
                    if (!destDesigner.IsSimpleState())
                    {
                        result = ConnectorCreationResult.CannotSetCompositeStateAsInitialState;
                    }
                    else if (destDesigner.IsFinalState())
                    {
                        result = ConnectorCreationResult.CannotSetFinalStateAsInitialState;
                    }
                    else
                    {
                        ModelItem destModelItem = destDesigner.ModelItem;
                        using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.SetInitialState))
                        {
                            this.StateMachineModelItem.Properties[StateMachineDesigner.InitialStatePropertyName].SetValue(destModelItem);
                            PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnectionPoint, destConnectionPoint));
                            this.StoreConnectorLocationViewState(this.StateMachineModelItem, connectorViewState, true);
                            result = ConnectorCreationResult.Success;
                            es.Complete();
                        }
                    }
                }
            }
            return(result);
        }
Exemplo n.º 8
0
        bool UpdateFlowChartObject(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, out string errorMessage, bool isLinkValidDueToLinkMove, IFlowSwitchLink caseKey)
        {
            //srcDesigner will be null for the case where source designer is StartSymbol.
            VirtualizedContainerService.VirtualizingContainer srcDesigner  = sourceConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            VirtualizedContainerService.VirtualizingContainer destDesigner = destConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            ModelItem       linkSource;
            ModelItem       linkDest           = destDesigner.ModelItem;
            ModelItem       destFlowElementMI  = GetFlowElementMI(linkDest);
            PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));

            errorMessage = string.Empty;

            if (sourceConnPoint.ParentDesigner is StartSymbol)
            {
                linkSource = this.ModelItem;
                if (linkSource.Properties["StartNode"].Value == null || isLinkValidDueToLinkMove)
                {
                    this.StoreConnectorViewState(linkSource, connectorViewState, sourceConnPoint);
                    linkSource.Properties["StartNode"].SetValue(destFlowElementMI);
                }
                else
                {
                    errorMessage = SR.FCNextLinkDefined;
                }
            }
            else
            {
                linkSource = srcDesigner.ModelItem;
                ModelItem srcFlowElementMI = GetFlowElementMI(linkSource);

                if (typeof(FlowStep).IsAssignableFrom(srcFlowElementMI.ItemType))
                {
                    if (srcFlowElementMI.Properties["Next"].Value == null || isLinkValidDueToLinkMove)
                    {
                        this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                        srcFlowElementMI.Properties["Next"].SetValue(destFlowElementMI);
                    }
                    else
                    {
                        errorMessage = SR.FCNextLinkDefined;
                    }
                }
                else if (typeof(FlowDecision).IsAssignableFrom(srcFlowElementMI.ItemType))
                {
                    if (sourceConnPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkSource])))
                    {
                        if (linkSource.Properties["True"].Value == null || isLinkValidDueToLinkMove)
                        {
                            this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                            linkSource.Properties["True"].SetValue(destFlowElementMI);
                        }
                        else
                        {
                            errorMessage = SR.FCTrueBranchExists;
                        }
                    }
                    else if (sourceConnPoint.Equals(FlowchartDesigner.GetFalseConnectionPoint(this.modelElement[linkSource])))
                    {
                        if (linkSource.Properties["False"].Value == null || isLinkValidDueToLinkMove)
                        {
                            this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                            linkSource.Properties["False"].SetValue(destFlowElementMI);
                        }
                        else
                        {
                            errorMessage = SR.FCFalseBranchExists;
                        }
                    }
                    else
                    {
                        errorMessage = SR.FCFlowConditionLinkError;
                    }
                }
                else //FlowSwitch
                {
                    if (!CreateFlowSwitchLink(sourceConnPoint, srcFlowElementMI, destFlowElementMI, caseKey, connectorViewState, ref errorMessage))
                    {
                        return(false);
                    }
                }
            }
            return(errorMessage.Equals(string.Empty));
        }