private void AddNewTransition(string stateName) { ModelItem stateMachineModelItem = StateContainerEditor.GetStateMachineModelItem(this.parentStateModelItem); ModelItem toStateModelItem = null; foreach (ModelItem stateModelItem in stateMachineModelItem.Properties[StateMachineDesigner.StatesPropertyName].Collection) { if (string.Equals(stateName, stateModelItem.Properties[StateDesigner.DisplayNamePropertyName].ComputedValue as string, StringComparison.Ordinal)) { toStateModelItem = stateModelItem; } } if (null == toStateModelItem) { return; } Fx.Assert(toStateModelItem != null, "To state cannot be null."); using (EditingScope editingScope = (EditingScope)this.ModelItem.BeginEdit(SR.CreateTransition)) { ModelItem triggerModelItem = this.ModelItem.Properties[TriggerPropertyName].Value; State toState = toStateModelItem.GetCurrentValue() as State; ModelItem newTransitionItem = this.parentStateModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(new Transition() { Trigger = null == triggerModelItem ? null : triggerModelItem.GetCurrentValue() as Activity, DisplayName = StateContainerEditor.GenerateTransitionName(stateMachineModelItem), To = toState }); this.ViewStateService.StoreViewState(newTransitionItem, ExpandViewStateKey, true); if (null == triggerModelItem) { PointCollection thisPointCollection = this.ViewStateService.RetrieveViewState(this.ModelItem, StateContainerEditor.ConnectorLocationViewStateKey) as PointCollection; if (null != thisPointCollection && thisPointCollection.Any()) { PointCollection newTransitionViewState = new PointCollection { thisPointCollection[0] // start point }; if (toState == this.parentStateModelItem.GetCurrentValue()) { // add an invalid destination point for self-transition, to force a reroute of the connection point newTransitionViewState.Add(new Point(0, 0)); } this.ViewStateService.StoreViewState(newTransitionItem, StateContainerEditor.ConnectorLocationViewStateKey, newTransitionViewState); } } editingScope.Complete(); } this.UpdateTransitionsSharingTrigger(); }
void OnSetAsInitialCanExecute(object sender, CanExecuteRoutedEventArgs e) { ModelItem stateMachineModelItem = StateContainerEditor.GetStateMachineModelItem(this.ModelItem); e.CanExecute = (!this.IsReadOnly && stateMachineModelItem != null && this.ModelItem != stateMachineModelItem.Properties[StateMachineDesigner.InitialStatePropertyName].Value && !this.IsFinalState() && !this.IsRootDesigner && StateContainerEditor.GetEmptyConnectionPoints(this).Count > 0); e.Handled = true; }
void OnSetAsInitialExecute(object sender, ExecutedRoutedEventArgs e) { ModelItem stateMachineModelItem = StateContainerEditor.GetStateMachineModelItem(this.ModelItem); using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.SetInitialState)) { this.ViewStateService.RemoveViewState(stateMachineModelItem, StateContainerEditor.ConnectorLocationViewStateKey); stateMachineModelItem.Properties[StateMachineDesigner.InitialStatePropertyName].SetValue(this.ModelItem.GetCurrentValue()); es.Complete(); } e.Handled = true; }
private IEnumerable <ModelItem> GetAvailableStates() { List <ModelItem> availableStates = new List <ModelItem>(); ModelItem stateMachineModelItem = StateContainerEditor.GetStateMachineModelItem(this.parentStateModelItem); Fx.Assert(null != stateMachineModelItem, "StateMachine must be the ancestor."); Dictionary <ModelItem, int> stateToConnectionMap = new Dictionary <ModelItem, int>(); foreach (ModelItem stateModelItem in stateMachineModelItem.Properties[StateMachineDesigner.StatesPropertyName].Collection) { if (!stateToConnectionMap.ContainsKey(stateModelItem)) { stateToConnectionMap[stateModelItem] = 0; } foreach (ModelItem transitionModelItem in stateModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection) { // to simplify the model, count a source connection as one, regardless of whether it is shared Trigger or not. stateToConnectionMap[stateModelItem]++; ModelItem toStateModelItem = transitionModelItem.Properties[TransitionDesigner.ToPropertyName].Value; Fx.Assert(toStateModelItem != null, "To state of a transition cannot be null."); if (stateToConnectionMap.ContainsKey(toStateModelItem)) { stateToConnectionMap[toStateModelItem]++; } else { stateToConnectionMap[toStateModelItem] = 1; } } } foreach (ModelItem stateModelItem in stateToConnectionMap.Keys) { if (stateToConnectionMap[stateModelItem] < TotalFreeConnectionPointNum) { // only allow connection to state that have available connection points availableStates.Add(stateModelItem); } } return(availableStates.OrderBy(modelItem => modelItem.Properties[StateDesigner.DisplayNamePropertyName].Value == null ? SR.EmptyName : modelItem.Properties[StateDesigner.DisplayNamePropertyName].Value.GetCurrentValue())); }
void UpdateLocationViewStatesToAvoidOverlap(List <ModelItem> itemsPasted) { int offset = 0; if (itemsPasted.Count > 0) { //Check to see if the first element in the input list needs offset. Generalize that information for all ModelItems in the input list. object location = this.ViewStateService.RetrieveViewState(itemsPasted[0], ShapeLocationViewStateKey); HashSet <Point> targetOccupiedLocations = null; if (this.ModelItem.ItemType == typeof(StateMachine)) { targetOccupiedLocations = this.shapeLocations; } else { ModelItem stateMachineModelItem = StateContainerEditor.GetStateMachineModelItem(this.ModelItem); StateMachineDesigner designer = stateMachineModelItem.View as StateMachineDesigner; if (designer != null) { targetOccupiedLocations = designer.StateContainerEditor.shapeLocations; } } if (location != null && targetOccupiedLocations != null) { Point locationOfShape = (Point)location; bool isOverlapped; do { isOverlapped = false; // need to check for each point on the canvas foreach (var point in targetOccupiedLocations) { // When the pasting occurs, the pasted point may not be exactly the same // as the copied point (with a slight margin of offset). Therefore, // we need to detect if the pasted point is within the boundary of the copied // object. If so, offset the pasted position such that the overlap is not observable. if ((locationOfShape.X < point.X + FreeFormPanel.GridSize && locationOfShape.X > point.X - FreeFormPanel.GridSize) && (locationOfShape.Y < point.Y + FreeFormPanel.GridSize && locationOfShape.Y > point.Y - FreeFormPanel.GridSize)) { offset++; locationOfShape.Offset(FreeFormPanel.GridSize, FreeFormPanel.GridSize); isOverlapped = true; break; } } } while (isOverlapped); } } //Update ViewState according to calculated offset. if (offset > 0) { double offsetValue = FreeFormPanel.GridSize * offset; OffsetLocationViewStates(new Vector(offsetValue, offsetValue), itemsPasted, GetTransitionModelItems(itemsPasted), false); } }