void StoreConnectorLocationViewState(Connector connector, bool isUndoableViewState) { //This method will be called whenever the FreeFormPanel raises a location changed event on a connector. //Such location changed events are a result of changes already committed in the UI. Hence we do not want to react to such view state changes. //Using internalViewStateChange flag for that purpose. this.internalViewStateChange = true; this.StoreConnectorLocationViewState(StateContainerEditor.GetConnectorModelItem(connector), connector.Points, isUndoableViewState); this.internalViewStateChange = false; }
// 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); }
internal int DeleteConnectorModelItem(Connector connector, bool rerouting = false) { ModelItem connectorModelItem = StateContainerEditor.GetConnectorModelItem(connector); if (!rerouting) { if (connector is ConnectorWithStartDot) { connector.StartDot.MouseDown -= new MouseButtonEventHandler(OnConnectorStartDotMouseDown); connector.StartDot.MouseUp -= new MouseButtonEventHandler(OnConnectorStartDotMouseUp); } connector.GotKeyboardFocus -= new KeyboardFocusChangedEventHandler(OnConnectorGotKeyboardFocus); connector.RequestBringIntoView -= new RequestBringIntoViewEventHandler(OnConnectorRequestBringIntoView); connector.GotFocus -= new RoutedEventHandler(OnConnectorGotFocus); connector.MouseDoubleClick -= new MouseButtonEventHandler(OnConnectorMouseDoubleClick); connector.MouseDown -= new MouseButtonEventHandler(OnConnectorMouseDown); connector.KeyDown -= new KeyEventHandler(OnConnectorKeyDown); connector.ContextMenuOpening -= new ContextMenuEventHandler(OnConnectorContextMenuOpening); connector.Unloaded -= new RoutedEventHandler(OnConnectorUnloaded); } int removedIndex = InvalidIndex; if (connectorModelItem.ItemType == typeof(Transition)) { ModelItemCollection transitions = StateContainerEditor.GetParentStateModelItemForTransition(connectorModelItem).Properties[StateDesigner.TransitionsPropertyName].Collection; removedIndex = transitions.IndexOf(connectorModelItem); Fx.Assert(removedIndex >= 0, "can't find the connector ModelItem in collection"); transitions.Remove(connectorModelItem); } // Connector from initial node else if (connectorModelItem.ItemType == typeof(StateMachine)) { using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.ClearInitialState)) { connectorModelItem.Properties[StateMachineDesigner.InitialStatePropertyName].SetValue(null); if (!rerouting) { this.ViewStateService.StoreViewStateWithUndo(connectorModelItem, ConnectorLocationViewStateKey, null); } es.Complete(); } } return(removedIndex); }
static ConnectionPoint GetSrcConnectionPointForSharedTrigger(UIElement sourceDesigner, ModelItem connectorModelItem) { ConnectionPoint sourceConnectionPoint = null; List <Connector> connectors = StateContainerEditor.GetOutgoingConnectors(sourceDesigner); foreach (Connector connector in connectors) { ModelItem modelItem = StateContainerEditor.GetConnectorModelItem(connector); if (modelItem != null && modelItem.ItemType == typeof(Transition)) { if (modelItem.Properties[TransitionDesigner.TriggerPropertyName].Value == connectorModelItem.Properties[TransitionDesigner.TriggerPropertyName].Value) { sourceConnectionPoint = FreeFormPanel.GetSourceConnectionPoint(connector); } } } return(sourceConnectionPoint); }
// 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); } }
void DoDeleteItems(List <ModelItem> itemsToDelete, bool removeIncomingConnectors) { itemsToDelete.Remove(this.initialModelItem); if (itemsToDelete.Count == 1 && itemsToDelete.First().ItemType == typeof(Transition)) { this.DeleteConnectorModelItem(this.selectedConnector); return; } itemsToDelete.RemoveAll(item => item.ItemType == typeof(Transition)); HashSet <Connector> connectorsToDelete = new HashSet <Connector>(); List <ModelItem> allStateModelItemsToDelete = new List <ModelItem>(); IEnumerable <ModelItem> selectedStateModelItems = this.Context.Items.GetValue <Selection>().SelectedObjects .Where <ModelItem>((p) => { return(p.ItemType == typeof(State)); }); foreach (ModelItem stateModelItem in itemsToDelete) { allStateModelItemsToDelete.Add(stateModelItem); } foreach (ModelItem modelItem in allStateModelItemsToDelete) { // We only need to delete incoming connectors to the states to be deleted; outgoing connectors will be deleted // automatically when the containing state is deleted. List <Connector> incomingConnectors = StateContainerEditor.GetIncomingConnectors(GetStateView(modelItem)); foreach (Connector connector in incomingConnectors) { ModelItem transitionModelItem = StateContainerEditor.GetConnectorModelItem(connector); // If the transition is contained by the states to delete, we don't bother to delete it separately. if (!StateContainerEditor.IsTransitionModelItemContainedByStateModelItems(transitionModelItem, selectedStateModelItems)) { connectorsToDelete.Add(connector); } } } // If we don't need to remove incoming connectors, we still remove the transitions but then add them back later. // This is in order to create an undo unit that contains the change notifications needed to make undo/redo work correctly. foreach (Connector connector in connectorsToDelete) { ModelItem connectorModelItem = StateContainerEditor.GetConnectorModelItem(connector); if (removeIncomingConnectors || connectorModelItem.ItemType == typeof(Transition)) { this.DeleteConnectorModelItem(connector); } } if (!removeIncomingConnectors) { foreach (Connector connector in connectorsToDelete) { ModelItem connectorModelItem = StateContainerEditor.GetConnectorModelItem(connector); if (connectorModelItem.ItemType == typeof(Transition)) { StateContainerEditor.GetParentStateModelItemForTransition(connectorModelItem).Properties[StateDesigner.TransitionsPropertyName].Collection.Add(connectorModelItem); } } } if (null != itemsToDelete) { itemsToDelete.ForEach(p => this.DeleteState(p, removeIncomingConnectors)); } }