Example #1
0
        public override void Execute()
        {
            if (Elements == null)
            {
                return;
            }

            MouseElements mouseElements = MouseElements;

            foreach (Element element in Elements)
            {
                if (element.Visible)
                {
                    if (element.ActionElement == null)
                    {
                        throw new ComponentException("Element action may not be null.");
                    }
                    if (element is Shape)
                    {
                        Shape shape       = (Shape)element;
                        Shape actionShape = (Shape)element.ActionElement;

                        //Round values if appropriate
                        if (Controller.RoundPixels)
                        {
                            shape.Location = Point.Round(shape.Location);
                            shape.Size     = System.Drawing.Size.Round(shape.Size);
                        }

                        //Move and scale. Shape size property does not check equality
                        if (!actionShape.Location.Equals(shape.Location))
                        {
                            actionShape.Location = shape.Location;                                               //new PointF(shape.X,shape.Y);
                        }
                        if (!actionShape.Size.Equals(shape.Size))
                        {
                            actionShape.Size = shape.Size;
                        }

                        //Update children of a complex shape
                        if (shape is ComplexShape)
                        {
                            ComplexShape complex = (ComplexShape)shape;

                            foreach (Solid solid in complex.Children.Values)
                            {
                                Solid actionSolid = (Solid)solid.ActionElement;
                                actionSolid.SetPath(solid.GetPath());
                                actionSolid.SetRectangle(solid.Location);
                                actionSolid.SetTransformRectangle(solid.Location);
                            }
                        }
                    }

                    //Update rotation
                    if (element is ITransformable)
                    {
                        ITransformable transform       = element as ITransformable;
                        ITransformable actionTransform = element.ActionElement as ITransformable;

                        if (actionTransform.Rotation != transform.Rotation)
                        {
                            actionTransform.Rotation = transform.Rotation;
                        }
                    }

                    if (element is Port)
                    {
                        Port port       = (Port)element;
                        Port actionPort = (Port)element.ActionElement;

                        //Move and scale. Port size property does not check equality
                        if (!actionPort.Location.Equals(port.Location))
                        {
                            actionPort.Location = port.Location;                                             //new PointF(port.X,port.Y);
                        }
                        //Update the port percentage
                        IPortContainer ports = (IPortContainer)actionPort.Parent;
                        ports.GetPortPercentage(actionPort, actionPort.Location);
                    }

                    //Update the locations of the line origins
                    if (element is Link)
                    {
                        Link clone = (Link)element;

                        //Undock any origins
                        if (mouseElements.MouseStartOrigin != null && mouseElements.MouseStartOrigin.Docked && mouseElements.MouseStartOrigin.AllowMove)
                        {
                            Origin origin = mouseElements.MouseStartOrigin;
                            if (origin == origin.Parent.Start)
                            {
                                origin.Location = origin.Parent.FirstPoint;
                            }
                            if (origin == origin.Parent.End)
                            {
                                origin.Location = origin.Parent.LastPoint;
                            }
                        }

                        if (element is ComplexLine)
                        {
                            ComplexLine complexLine   = (ComplexLine)element;
                            ComplexLine actionLine    = (ComplexLine)element.ActionElement;
                            Segment     segment       = null;
                            Segment     actionSegment = null;

                            for (int i = 0; i < complexLine.Segments.Count; i++)
                            {
                                segment       = complexLine.Segments[i];
                                actionSegment = actionLine.Segments[i];
                                if (!actionSegment.Start.Docked)
                                {
                                    actionSegment.Start.Location = segment.Start.Location;
                                }
                            }

                            //Update end of last segment
                            if (segment != null && actionSegment != null && !actionSegment.End.Docked)
                            {
                                actionSegment.End.Location = segment.End.Location;
                            }

                            actionLine.DrawPath();
                            actionLine.LocatePorts();
                        }
                        else if (element is Curve)
                        {
                            Curve curve       = (Curve)element;
                            Curve actionCurve = (Curve)element.ActionElement;

                            if (!actionCurve.Start.Docked)
                            {
                                actionCurve.Start.Location = curve.Start.Location;
                            }
                            if (!actionCurve.End.Docked)
                            {
                                actionCurve.End.Location = curve.End.Location;
                            }

                            actionCurve.ControlPoints = curve.ControlPoints;
                            actionCurve.DrawPath();
                            actionCurve.LocatePorts();
                        }
                        else if (element is Connector)
                        {
                            //Update connector oblong handle
                            if (mouseElements.MouseHandle.Type == HandleType.UpDown || mouseElements.MouseHandle.Type == HandleType.LeftRight)
                            {
                                Connector connectorLine = element as Connector;
                                Connector actionLine    = element.ActionElement as Connector;

                                //Get the two points of the segment
                                ConnectorHandle handle = mouseElements.MouseHandle as ConnectorHandle;
                                if (handle != null)
                                {
                                    actionLine.Points[handle.Index - 1] = (PointF)connectorLine.Points[handle.Index - 1];
                                    actionLine.Points[handle.Index]     = (PointF)connectorLine.Points[handle.Index];
                                    actionLine.RefinePoints();
                                    actionLine.DrawPath();
                                    actionLine.LocatePorts();
                                    actionLine.CreateHandles();
                                }
                            }
                            //Update start or end of connector
                            else if (mouseElements.MouseHandle.Type == HandleType.Origin)
                            {
                                Connector connectorLine = element as Connector;
                                Connector actionLine    = element.ActionElement as Connector;

                                actionLine.SetPoints(connectorLine.Points);
                                actionLine.RefinePoints();

                                //Set origins
                                if (!actionLine.Start.Docked)
                                {
                                    actionLine.Start.Location = connectorLine.FirstPoint;
                                }
                                if (!actionLine.End.Docked)
                                {
                                    actionLine.End.Location = connectorLine.LastPoint;
                                }

                                actionLine.GetPortPercentages();
                                actionLine.DrawPath();
                                actionLine.LocatePorts();
                            }
                            //Move all points if connector is not connected
                            else if (mouseElements.MouseHandle.Type == HandleType.Move)
                            {
                                Connector connectorLine = element as Connector;
                                Connector actionLine    = element.ActionElement as Connector;

                                if (actionLine.AllowMove && !actionLine.Start.Docked && !actionLine.End.Docked)
                                {
                                    actionLine.Points.Clear();

                                    foreach (PointF point in connectorLine.Points)
                                    {
                                        actionLine.Points.Add(point);
                                    }

                                    actionLine.DrawPath();
                                    actionLine.LocatePorts();
                                }
                            }
                        }
                        else
                        {
                            Link line       = (Link)element;
                            Link actionLine = (Link)element.ActionElement;

                            //Round values if appropriate
                            if (Controller.RoundPixels)
                            {
                                line.Start.Location = Point.Round(line.Start.Location);
                                line.End.Location   = Point.Round(line.End.Location);
                            }

                            if (!actionLine.Start.Docked)
                            {
                                actionLine.Start.Location = line.Start.Location;
                            }
                            if (!actionLine.End.Docked)
                            {
                                actionLine.End.Location = line.End.Location;
                            }

                            actionLine.DrawPath();
                            actionLine.LocatePorts();
                        }
                    }

                    if (element is Port)
                    {
                        Port actionPort = element as Port;
                        Port port       = actionPort.ActionElement as Port;

                        port.Location = actionPort.Location;
                    }
                }
            }

            //Update the line docking
            if (mouseElements != null && mouseElements.MouseStartOrigin != null && mouseElements.MouseStartOrigin.AllowMove && mouseElements.MouseMoveElement != null && mouseElements.IsDockable() && Controller.CanDock(InteractiveMode, mouseElements))
            {
                Link line = mouseElements.MouseStartElement as Link;

                //Dock start to shape
                if (mouseElements.MouseStartOrigin == line.Start && mouseElements.MouseMoveElement is Shape)
                {
                    line.Start.Shape = mouseElements.MouseMoveElement as Shape;
                }
                //Dock end to shape
                if (mouseElements.MouseStartOrigin == line.End && mouseElements.MouseMoveElement is Shape)
                {
                    line.End.Shape = mouseElements.MouseMoveElement as Shape;
                }
                //Dock start to port
                if (mouseElements.MouseStartOrigin == line.Start && mouseElements.MouseMoveElement is Port)
                {
                    line.Start.Port = mouseElements.MouseMoveElement as Port;
                }
                //Dock end to port
                if (mouseElements.MouseStartOrigin == line.End && mouseElements.MouseMoveElement is Port)
                {
                    line.End.Port = mouseElements.MouseMoveElement as Port;
                }
            }

            Executed = true;
        }
        //Loop through each item in the copycut buffer and add it back to the diagram
        //Paste into centre of container
        private void DoPaste(PointF location)
        {
            if (Controller.Clipboard.Elements == null)
            {
                return;
            }

            //Create a renderlist and add the elements
            ElementList list = new ElementList();

            foreach (Element element in Controller.Clipboard.Elements.Values)
            {
                list.Add(element);
            }

            //Get the bounds
            RectangleF bounds = list.GetBounds();

            //Calculate
            float dx = -bounds.X + ((Controller.Model.Size.Width - bounds.Width) / 2);
            float dy = -bounds.Y + ((Controller.Model.Size.Height - bounds.Height) / 2);

            dx = Convert.ToSingle(Math.Round(dx, 0));
            dy = Convert.ToSingle(Math.Round(dy, 0));

            //Loop through each element and add
            if (Controller.Clipboard.Elements != null)
            {
                //Add Shapes
                foreach (Element element in Controller.Clipboard.Elements.Values)
                {
                    if (element is Shape)
                    {
                        Shape  shape    = (Shape)element;
                        Shape  newShape = (Shape)shape.Clone();
                        string key      = null;

                        //Set key
                        key = (Controller.Model.Shapes.ContainsKey(shape.Key)) ? Controller.Model.Shapes.CreateKey() : shape.Key;

                        //Set temporary action element
                        shape.ActionElement = newShape;

                        //Change any settings required
                        newShape.SetLayer(null);
                        newShape.Selected = true;

                        //Offset by container offset
                        newShape.Move(dx, dy);

                        //Round values if appropriate
                        if (Controller.RoundPixels)
                        {
                            newShape.Location = Point.Round(newShape.Location);
                            newShape.Size     = System.Drawing.Size.Round(newShape.Size);
                        }

                        //Add if allowed by the runtime
                        if (Controller.CanAdd(newShape))
                        {
                            Controller.Model.Shapes.Add(key, newShape);
                        }
                    }
                }

                //Add Lines
                foreach (Element element in Controller.Clipboard.Elements.Values)
                {
                    if (element is Link)
                    {
                        Link   line    = (Link)element;
                        Link   newLine = (Link)line.Clone();
                        string key     = null;

                        //Define the key
                        key = (Controller.Model.Lines.ContainsKey(line.Key)) ? Controller.Model.Lines.CreateKey() : key = line.Key;

                        //Change any settings required
                        newLine.SetLayer(null);
                        newLine.Selected = true;

                        if (element is ComplexLine)
                        {
                            ComplexLine complexLine = (ComplexLine)newLine;
                            Segment     segment     = null;

                            for (int i = 0; i < complexLine.Segments.Count; i++)
                            {
                                segment = complexLine.Segments[i];
                                segment.Start.Move(dx, dy);
                            }
                        }
                        else if (element is Curve)
                        {
                            Curve curve = (Curve)newLine;

                            curve.Start.Move(dx, dy);
                            curve.End.Move(dx, dy);

                            PointF[] newPoints = new PointF[curve.ControlPoints.GetUpperBound(0) + 1];
                            for (int i = 0; i <= curve.ControlPoints.GetUpperBound(0); i++)
                            {
                                newPoints[i] = new PointF(curve.ControlPoints[i].X + dx, curve.ControlPoints[i].Y + dy);
                            }
                            curve.ControlPoints = newPoints;
                        }
                        else if (element is Connector) //Connectors cannot be moved in this way
                        {
                            Connector     conn   = (Connector)newLine;
                            List <PointF> points = new List <PointF>();

                            foreach (PointF point in conn.Points)
                            {
                                points.Add(new PointF(point.X + dx, point.Y + dy));
                            }
                            conn.SetPoints(points);
                            conn.DrawPath();
                        }
                        else
                        {
                            newLine.Start.Move(dx, dy);
                            newLine.End.Move(dx, dy);
                            newLine.DrawPath();
                        }

                        //Reconnect start origins
                        if (line.Start.DockedElement != null)
                        {
                            if (line.Start.Shape != null && line.Start.Shape.ActionElement != null)
                            {
                                newLine.Start.Shape = (Shape)line.Start.Shape.ActionElement;
                            }
                            else if (line.Start.Port != null && line.Start.Port.Parent is Shape)
                            {
                                Shape shape    = (Shape)line.Start.Port.Parent;
                                Shape newShape = (Shape)shape.ActionElement;

                                newLine.Start.Port = (Port)newShape.Ports[line.Start.Port.Key];
                            }
                        }

                        //Reconnect end origins
                        if (line.End.DockedElement != null)
                        {
                            if (line.End.Shape != null && line.End.Shape.ActionElement != null)
                            {
                                newLine.End.Shape = (Shape)line.End.Shape.ActionElement;
                            }
                            else if (line.End.Port != null && line.End.Port.Parent is Shape)
                            {
                                Shape shape    = (Shape)line.End.Port.Parent;
                                Shape newShape = (Shape)shape.ActionElement;

                                newLine.End.Port = (Port)newShape.Ports[line.End.Port.Key];
                            }
                        }

                        //Create and add to lines collection
                        if (Controller.CanAdd(newLine))
                        {
                            Controller.Model.Lines.Add(key, newLine);
                        }
                    }
                }

                //Remove any temporary action elements
                foreach (Element element in Controller.Clipboard.Elements.Values)
                {
                    element.ActionElement = null;
                }
            }
        }
        //Methods

        //Translates an action, typically in response to mouse movement
        public virtual void Translate()
        {
            SizeF delta = new SizeF(Dx, Dy);

            delta = Controller.BoundsCheck(Elements, new SizeF(Dx, Dy));
            if (delta.IsEmpty)
            {
                return;
            }

            bool snapped = false;

            //Reset any vectors
            SetVectors(null);

            //Initial loop to check for location snapping
            foreach (Element element in Elements)
            {
                if (element.Visible)
                {
                    //Offset shapes
                    if (element is Shape)
                    {
                        Shape shape       = element as Shape;
                        Shape actionshape = shape.ActionElement as Shape; //the actual shape being moved

                        if (shape.AllowMove && shape.AllowSnap)
                        {
                            PointF location = Geometry.CombinePoint(actionshape.Location, new PointF(Dx, Dy));
                            PointF snap     = Controller.SnapToLocation(location, shape.Size, this); //Sets the vector

                            //If a shape is snapped to a location then readjust the dx and dy values
                            if (!snapped && !location.Equals(snap))
                            {
                                Dx      = Dx + snap.X - location.X;
                                Dy      = Dy + snap.Y - location.Y;
                                snapped = true;
                            }
                        }
                    }
                }
            }

            //Change position of each element
            foreach (Element element in Elements)
            {
                if (element.Visible)
                {
                    //Offset shapes
                    if (element is Shape)
                    {
                        Shape shape       = element as Shape;
                        Shape actionshape = shape.ActionElement as Shape; //the actual shape being moved

                        if (shape.AllowMove)
                        {
                            PointF location = Geometry.CombinePoint(actionshape.Location, new PointF(Dx, Dy));
                            shape.Location = location;
                        }

                        if (Controller.Model.Route != null)
                        {
                            Controller.Model.Route.Reform();
                        }
                    }

                    //Offset ports
                    if (element is Port)
                    {
                        Port port       = element as Port;
                        Port actionPort = element.ActionElement as Port;

                        if (port.AllowMove)
                        {
                            PointF location = new PointF(actionPort.X + Dx, actionPort.Y + Dy);

                            //Call a method on the container to adjust the point so that it lies outside the path
                            if (port.Parent.Contains(location))
                            {
                                location = port.Parent.Forward(location);
                            }

                            //Port is outside the path
                            port.Location = port.Parent.Intercept(location);
                        }

                        if (Controller.Model.Route != null)
                        {
                            Controller.Model.Route.Reform();
                        }
                    }

                    //Offset line
                    if (element is Link)
                    {
                        //Offset all segments in complex line
                        if (element is ComplexLine)
                        {
                            ComplexLine complexLine   = element as ComplexLine;
                            ComplexLine actionLine    = element.ActionElement as ComplexLine;
                            Segment     segment       = null;
                            Segment     actionSegment = null;

                            if (actionLine.AllowMove)
                            {
                                for (int i = 0; i < complexLine.Segments.Count; i++)
                                {
                                    segment       = complexLine.Segments[i];
                                    actionSegment = actionLine.Segments[i];

                                    if (!actionSegment.Start.Docked)
                                    {
                                        segment.Start.Move(Dx, Dy);
                                    }
                                }
                                if (!actionSegment.End.Docked)
                                {
                                    segment.End.Move(Dx, Dy);
                                }
                            }
                        }
                        else if (element is Curve)
                        {
                            Curve curve       = (Curve)element;
                            Curve actionCurve = (Curve)curve.ActionElement;
                            if (actionCurve.AllowMove)
                            {
                                if (!actionCurve.Start.Docked || (actionCurve.Start.Shape != null && actionCurve.Start.Shape.Selected) || (actionCurve.Start.Port != null && ((ISelectable)actionCurve.Start.Port.Parent).Selected))
                                {
                                    curve.Start.Move(Dx, Dy);
                                }
                                if (!actionCurve.End.Docked || (actionCurve.End.Shape != null && actionCurve.End.Shape.Selected) || (actionCurve.End.Port != null && ((ISelectable)actionCurve.End.Port.Parent).Selected))
                                {
                                    curve.End.Move(Dx, Dy);
                                }

                                PointF[] newPoints = new PointF[actionCurve.ControlPoints.GetUpperBound(0) + 1];
                                for (int i = 0; i <= actionCurve.ControlPoints.GetUpperBound(0); i++)
                                {
                                    newPoints[i] = new PointF(curve.ControlPoints[i].X + Dx, curve.ControlPoints[i].Y + Dy);
                                }
                                curve.ControlPoints = newPoints;
                            }
                        }
                        else if (element is Connector)
                        {
                            Connector connector       = (Connector)element;
                            Connector actionConnector = (Connector)connector.ActionElement;

                            if (actionConnector.AllowMove && !actionConnector.Start.Docked && !actionConnector.End.Docked)
                            {
                                List <PointF> newPoints = new List <PointF>();

                                foreach (PointF point in actionConnector.Points)
                                {
                                    newPoints.Add(new PointF(point.X + Dx, point.Y + Dy));
                                }
                                connector.SetPoints(newPoints);
                                connector.DrawPath();
                            }
                        }
                        else
                        {
                            Link line       = (Link)element;
                            Link actionLine = (Link)line.ActionElement;

                            if (actionLine.AllowMove)
                            {
                                if (!actionLine.Start.Docked)
                                {
                                    line.Start.Location = Geometry.CombinePoint(actionLine.Start.Location, new PointF(Dx, Dy));
                                }
                                if (!actionLine.End.Docked)
                                {
                                    line.End.Location = Geometry.CombinePoint(actionLine.End.Location, new PointF(Dx, Dy));
                                }

                                line.DrawPath();
                            }
                        }
                    }

                    //Offset stand-alone port
                    if (element is Port)
                    {
                        Port port = (Port)element;
                        if (port.AllowMove)
                        {
                            port.Move(Dx, Dy);
                        }
                    }
                }
            }
        }