// Returns the last dropped item - used for auto-connect and auto-split where only one item is allowed ModelItem DoFlowchartGridDrop(DragEventArgs e, AutoConnectDirections autoConnectDirection, Connector connectorToSplit) { ModelItem droppedModelItem = null; ModelItem newFlowStepMI = null; e.Effects = DragDropEffects.None; IEnumerable<object> droppedObjects = DragDropHelper.GetDroppedObjects(this, e, Context); //Marking the event as being handled. In whichever case we want to route the event, it will be unmarked explicitly. e.Handled = true; List<WorkflowViewElement> movedViewElements = new List<WorkflowViewElement>(); ShapeOffsetter shapeOffsetter = new ShapeOffsetter(); Dictionary<WorkflowViewElement, Point> relativeLocations = DragDropHelper.GetDraggedViewElementRelativeLocations(e); ModelItem modelItemDroppedFromToolBox = null; Dictionary<object, FlowNode> objToNewFlowNodeMap = null; Dictionary<FlowNode, ModelItem> flowNodeModelItemMap = null; Dictionary<FlowNode, FlowNode> oldNewFlowNodeMap = null; this.PrepareForDrop(droppedObjects, out objToNewFlowNodeMap, out flowNodeModelItemMap, out oldNewFlowNodeMap); bool shouldStoreCurrentSizeViewState = true; foreach (object droppedObject in droppedObjects) { if (droppedObject == null) { continue; } droppedModelItem = droppedObject as ModelItem; // archor point Point anchorPoint = DragDropHelper.GetDragDropAnchorPoint(e); ICompositeView srcContainer = droppedModelItem != null ? DragDropHelper.GetCompositeView(droppedModelItem.View as WorkflowViewElement) as ICompositeView : null; bool keepRelativePosition = srcContainer is FlowchartDesigner; // This is the case of dragging from toolbox if (anchorPoint.X < 0 && anchorPoint.Y < 0) { keepRelativePosition = false; } // This is the case of dragging from the designer surface else if (droppedModelItem != null) { WorkflowViewElement view = (WorkflowViewElement)droppedModelItem.View; anchorPoint.Offset(-relativeLocations[view].X, -relativeLocations[view].Y); } if (droppedModelItem != null && srcContainer != null && srcContainer.Equals(this)) { if (shouldStoreCurrentSizeViewState) { // Moving may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } //InternalMove PerformInternalMove(modelElement[droppedModelItem], e.GetPosition(this.panel), anchorPoint, autoConnectDirection, connectorToSplit); } else { //External model Item drop. if (droppedModelItem != null) { if ((IsFlowStepAction(droppedModelItem) || IsFlowNode(droppedModelItem)) && !IsParentOf(droppedModelItem, this.ModelItem)) { if (shouldStoreCurrentSizeViewState) { // Drop may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } FlowNode flowElement = objToNewFlowNodeMap[droppedObject]; ModelItem flowElementMI; if (flowNodeModelItemMap.TryGetValue(flowElement, out flowElementMI)) { // FlowNode comes from some other flowchart. this.ModelItem.Properties["Nodes"].Collection.Add(flowElementMI); } else { // FlowNode is a new created one, which means this is an Activity dragged // from somewhere else, outside of Flowchart. flowElementMI = this.ModelItem.Properties["Nodes"].Collection.Add(flowElement); flowNodeModelItemMap[flowElement] = flowElementMI; } newFlowStepMI = flowElementMI; } else { //We want to route the event in the case that the flowchart is dropped upon itself. if (droppedModelItem.Equals(this.ModelItem)) { e.Handled = false; } //Don't add anything for what is neither a Activity nor a flowlink. continue; } if (droppedModelItem != null && droppedModelItem.View != null) { movedViewElements.Add((WorkflowViewElement)droppedModelItem.View); } // the external item may come from other panel (sequence) which is already given // a size by its previous layout panel. That might give an inaccurate size to the // dropped object (i.e. Bug 198290). Therefore, when the object is dropped externally // the FC should erases its previous hint size, forcing the FC to recompute an appropriate // size based on the workflowelementview size. VirtualizedContainerService.SetHintSize(droppedModelItem.GetCurrentValue(), null); } //Tool box drop. else { if (typeof(Activity).IsAssignableFrom(droppedObject.GetType())) { FlowStep flowStep = new FlowStep(); flowStep.Action = (Activity)droppedObject; if (shouldStoreCurrentSizeViewState) { // Drop may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } newFlowStepMI = this.ModelItem.Properties["Nodes"].Collection.Add(flowStep); droppedModelItem = newFlowStepMI.Properties["Action"].Value; } else if (typeof(FlowNode).IsAssignableFrom(droppedObject.GetType())) { if (shouldStoreCurrentSizeViewState) { // Drop may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } droppedModelItem = this.ModelItem.Properties["Nodes"].Collection.Add(droppedObject); newFlowStepMI = droppedModelItem; } // Now, toolbox drop doesn't support multiple drop // If multi-drop from tool box, use an array here. modelItemDroppedFromToolBox = droppedModelItem; keepRelativePosition = false; } // tool box WorkflowViewElement view = droppedModelItem.View as WorkflowViewElement; if (view == null || view.ExpandState) { //Creating a new view to get the size of collapsed view. view = this.ViewService.GetView(droppedModelItem) as WorkflowViewElement; ViewUtilities.MeasureView(view, true); } if (view != null) { PostDropUpdateViewState(view, newFlowStepMI, autoConnectDirection, connectorToSplit, e.GetPosition(this.panel), anchorPoint, keepRelativePosition, shapeOffsetter); } } // external move } // foreach // Remap references. // The re-map here is different from the remaping in copy/paste. // In copy paste, all the values are copied. but here, some value are // set by Properties["key"].SetValue(). // Don't move this into PrepareMove. Some value setting is added to // Change. So the operation here will decide the order of Change.Apply(). // PropertyChange in some case, must happen after ModelItem is moved to // new places. foreach (FlowNode flowNode in oldNewFlowNodeMap.Keys) { UpdateCloneReferenceByModelItem(flowNode, flowNodeModelItemMap, oldNewFlowNodeMap); } DragDropHelper.SetDragDropMovedViewElements(e, movedViewElements); //Backward compatibility for 4.0 if (droppedObjects.Count() == 1 && movedViewElements.Count == 1) { #pragma warning disable 618 DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.Move); #pragma warning restore 618 } if (modelItemDroppedFromToolBox != null) { // if it is dropped from toolbox, select this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() => { UIElement view = (UIElement)(modelItemDroppedFromToolBox.View); if (view != null) { Keyboard.Focus(view); Selection.SelectOnly(this.Context, modelItemDroppedFromToolBox); } })); } if (droppedModelItem != null) { if (IsFlowNode(droppedModelItem)) { return droppedModelItem; } else if (IsFlowStepAction(droppedModelItem)) { if (newFlowStepMI != null) { return newFlowStepMI; } else { return this.GetParentFlowStepModelItem(droppedModelItem); } } return null; } return null; }
// Move the object to correct position after drop private void PostDropUpdateViewState(WorkflowViewElement view, ModelItem flownodeMI, AutoConnectDirections autoConnectDirection, Connector connectorToSplit, Point newPoint, Point anchorPoint, bool keepRelativePosition, ShapeOffsetter shapeOffsetter) { Fx.Assert((view != null && flownodeMI != null), "movedItem != null && flownodeMI != null"); Point shapeLocationPtr; if (autoConnectDirection != AutoConnectDirections.None) { shapeLocationPtr = this.CalculateDropLocationForAutoConnect(autoConnectDirection, view.DesiredSize); } else { shapeLocationPtr = SnapVisualToGrid(view, newPoint, anchorPoint, keepRelativePosition); if (!keepRelativePosition) { // To avoid overlaps shapeLocationPtr = shapeOffsetter.OffsetShapeLocation(shapeLocationPtr); } } if (connectorToSplit != null) { shapeLocationPtr = this.CalculateDropLocationForAutoSplit(newPoint, shapeLocationPtr, connectorToSplit, view.DesiredSize); } // if (keepRelativePosition) { this.OffsetDroppedItemToNewPosition(flownodeMI, shapeLocationPtr); } else { this.StoreShapeViewState(flownodeMI, shapeLocationPtr); } }
public static int GeometryControlsOnGUI(int cur_y, AXNodeGraphEditorWindow editor, AXParametricObject po) { int gap = ArchimatixUtils.gap; int lineHgt = ArchimatixUtils.lineHgt; float x1 = 10; float x2 = 20; float winMargin = ArchimatixUtils.indent; float innerWidth = po.rect.width - 2 * winMargin; AXParameter p = null; // Geometry (and other) controllers if (po.geometryControls != null && po.geometryControls.children != null) { for (int i = 0; i < po.geometryControls.children.Count; i++) { p = po.geometryControls.children[i] as AXParameter; if (p.PType != AXParameter.ParameterType.None && p.PType != AXParameter.ParameterType.GeometryControl) { continue; } // these points are world, not relative to the this GUIWindow p.inputPoint = new Vector2(po.rect.x, po.rect.y + cur_y + lineHgt / 2); p.outputPoint = new Vector2(po.rect.x + po.rect.width, po.rect.y + cur_y + lineHgt / 2); Rect pRect = new Rect(x1, cur_y, innerWidth, lineHgt); try { int hgt = ParameterGUI.OnGUI(pRect, editor, p); cur_y += hgt + gap; } catch { } } } if (po.is2D() || po.generator is Grouper) { if (GUI.Button(new Rect(x2, cur_y, lineHgt * 1.25f, lineHgt), new GUIContent("+", "Create a new Control Parameter"))) { Undo.RegisterCompleteObjectUndo(po.model, "New AXParameter"); AXParameter tmpP = po.addParameter(new AXParameter()); foreach (AXParameter pop in po.parameters) { if (pop != p) { pop.isOpen = false; } } po.model.indexedParameters.Add(tmpP.Guid, tmpP); po.doneEditing(); tmpP.isOpen = true; tmpP.isEditing = false; tmpP.shouldFocus = true; //po.isEditing = true; po.model.cleanGraph(); AXNodeGraphEditorWindow.repaintIfOpen(); } /* * if (GUI.Button (new Rect(x1+editButtonWid+6, cur_y, editButtonWid,lineHgt), "Done" )) * po.doneEditing(); * else * if (GUI.Button (new Rect(x1+editButtonWid+6, cur_y, editButtonWid,lineHgt), "Edit Controls" )) * po.isEditing = true; */ cur_y += lineHgt + gap + 5; } if (po.generator is MaterialTool) { MaterialTool materialTool = (po.generator as MaterialTool); GUIStyle labelstyle = GUI.skin.GetStyle("Label"); labelstyle.alignment = TextAnchor.MiddleLeft; GUI.Label(new Rect(10, cur_y, 250, 32), " Texels/Unit: " + materialTool.texelsPerUnit.ToString("F0")); cur_y += 32; } else if (po.generator is ShapeOffsetter) { ShapeOffsetter offsetter = (po.generator as ShapeOffsetter); AXParameter output_p = offsetter.P_Output; if (output_p == null) { output_p = po.getParameter("Output Shape"); } if (output_p == null) { return(cur_y); } Rect tRect = new Rect(25, cur_y, 150, 16); GUIStyle labelstyle = GUI.skin.GetStyle("Label"); labelstyle.alignment = TextAnchor.MiddleLeft; /* * if (p.PType == AXParameter.ParameterType.Output) * { * labelstyle.alignment = TextAnchor.MiddleRight; * labelstyle.fixedWidth = lRect.width+5; * } */ // JOIN_TYPE: Square, Round, Miter if (offsetter.offset != 0) { string[] options = ArchimatixUtils.getMenuOptions("JoinType"); EditorGUIUtility.labelWidth = 75; //-50; EditorGUI.BeginChangeCheck(); output_p.joinType = (JoinType)EditorGUI.Popup(tRect, "JoinType", (int)output_p.joinType, options); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(po.model, "value change for JoinType"); po.model.autobuild(); } cur_y += ArchimatixUtils.lineHgt + ArchimatixUtils.gap; } // ARC_TOLERANCE (for JoinType.Round) if (output_p.joinType == AXClipperLib.JoinType.jtRound || output_p.endType == AXClipperLib.EndType.etOpenRound) { tRect.y = cur_y; if (float.IsNaN(output_p.arcTolerance)) { output_p.arcTolerance = 50; } if (output_p.arcTolerance < .25f) { output_p.arcTolerance = .25f; } float smooth = (float)(120 / (output_p.arcTolerance * output_p.arcTolerance)); AXEditorUtilities.assertFloatFieldKeyCodeValidity("shapehandler_Text_smoothness_" + output_p.Guid + "_" + output_p.Name); EditorGUI.BeginChangeCheck(); GUI.SetNextControlName("shapehandler" + output_p.Name); smooth = EditorGUI.FloatField(tRect, "smoothness", smooth); if (EditorGUI.EndChangeCheck()) { output_p.arcTolerance = (float)(Mathf.Sqrt(120 / smooth)); Undo.RegisterCompleteObjectUndo(po.model, "value change for " + output_p.Name); if (output_p.arcTolerance < .25f) { output_p.arcTolerance = .25f; } if (output_p.arcTolerance > 50) { output_p.arcTolerance = 50; } if (float.IsNaN(output_p.arcTolerance)) { output_p.arcTolerance = 50; } po.model.isAltered(20); } cur_y += ArchimatixUtils.lineHgt + ArchimatixUtils.gap; } } return(cur_y); }