// 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);
            }
        }
Ejemplo n.º 3
0
    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);
    }