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); } } } } }