private static void ApplyShapesLayout(GleeGraph g, Dictionary <string, NodeShape> shapesMap, double graphLeft, double graphTop) { // apply layout information to child shapes foreach (string key in shapesMap.Keys) { NodeShape nodeShape = shapesMap[key]; Node node = g.NodeMap[key]; // appy layout information for shape double shapeTop = (graphTop - node.BBox.Top) + HostMargin; double shapeLeft; if (graphLeft <= 0) { shapeLeft = Math.Abs(graphLeft) + node.BBox.Left + HostMargin; } else { shapeLeft = node.BBox.Left - graphLeft + HostMargin; } if (nodeShape.MovementBehaviour == ShapeMovementBehaviour.PositionOnEdgeOfParent) { if (nodeShape.Parent != null) { nodeShape.SetLocation(NodeShape.CorrectPortLocation(nodeShape.Parent, nodeShape, new PointD(shapeLeft, shapeTop))); } } else { nodeShape.SetLocation(new PointD(shapeLeft, shapeTop)); } } }
/// <summary> /// Creates a shape for the specified model element. /// </summary> /// <param name="element"></param> /// <returns></returns> protected virtual NodeShape CreateShape(ModelElement element) { DiagramDomainDataDirectory data = this.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); Guid domainClassId = element.GetDomainClass().Id; if (data.HasDependenciesShapeForElement(domainClassId)) { return(this.ViewModelStore.TopMostStore.GetDomainModelServices().ShapeProvider.CreateDependenciesShapeForElement(domainClassId, element) as NodeShape); } NodeShape dShape = new NodeShape(this.Store); dShape.Element = element; dShape.SetLocation(new PointD(5, 5)); dShape.SetSize(new SizeD(200, 40)); return(dShape); }
private static void SetPortAtFreePositionOnParent(NodeShape shape) { float width = (float)shape.Bounds.Width; float height = (float)shape.Bounds.Height; float parentWidth = (float)shape.Parent.Bounds.Width; float parentHeight = (float)shape.Parent.Bounds.Height; Dictionary <PortPlacement, int> dict = new Dictionary <PortPlacement, int>(); dict.Add(PortPlacement.Left, 0); dict.Add(PortPlacement.Top, 0); dict.Add(PortPlacement.Bottom, 0); dict.Add(PortPlacement.Right, 0); for (int i = 0; i < shape.Parent.RelativeChildren.Count; i++) { if (shape.Parent.RelativeChildren[i] == shape) { continue; } dict[shape.Parent.RelativeChildren[i].PlacementSide]++; } List <KeyValuePair <PortPlacement, int> > myList = new List <KeyValuePair <PortPlacement, int> >(dict); myList.Sort((firstPair, nextPair) => { return(firstPair.Value.CompareTo(nextPair.Value)); }); foreach (KeyValuePair <PortPlacement, int> p in myList) { RectangleF rectH; switch (p.Key) { case PortPlacement.Left: rectH = new RectangleF(-width / 2, 0, width, parentHeight); break; case PortPlacement.Top: rectH = new RectangleF(0, -height / 2, parentWidth, height); break; case PortPlacement.Right: rectH = new RectangleF(parentWidth - width / 2, 0, width, parentHeight); break; case PortPlacement.Bottom: rectH = new RectangleF(0, parentHeight - height / 2, parentWidth, height); break; default: throw new NotSupportedException(); } if (SetPortAtFreePositionOnParent(shape, p.Key, rectH)) { return; } } shape.SetLocation(NodeShape.CorrectPortLocation(shape.Parent, shape, new PointD(0, 0))); }
public static void SetAtFreePositionOnParent(NodeShape shape) { IList <NodeShape> shapes; if (shape.Parent == null) { // free position on diagram Diagram diagram = shape.Diagram; shapes = diagram.Children; } else { if (shape.IsRelativeChildShape) { SetPortAtFreePositionOnParent(shape); return; } // free position on parent shape shapes = shape.Parent.NestedChildren; } // simple algo - need better? RectangleF rectShape = new RectangleF(0, 0, (float)shape.Size.Width, (float)shape.Size.Height); RectangleF completeBounds = RectangleF.Empty; List <RectangleF> allShapes = new List <RectangleF>(); for (int i = 0; i < shapes.Count; i++) { if (shapes[i] == shape) { continue; } RectangleF r = new RectangleF((float)shapes[i].Location.X, (float)shapes[i].Location.Y, (float)shapes[i].Size.Width, (float)shapes[i].Size.Height); // add DistanceBetweenShapes if (r.X > DistanceBetweenShapes) { r.X -= DistanceBetweenShapes; } if (r.Y > DistanceBetweenShapes) { r.Y -= DistanceBetweenShapes; } if (r.X > DistanceBetweenShapes) { r.Width += DistanceBetweenShapes * 2; } else { r.Width += DistanceBetweenShapes; } if (r.Y > DistanceBetweenShapes) { r.Height += DistanceBetweenShapes * 2; } else { r.Height += DistanceBetweenShapes; } allShapes.Add(r); if (completeBounds == RectangleF.Empty) { // set initial complete bounds completeBounds = r; } else { // extend complete bounds if (completeBounds.X > r.X) { completeBounds.Width += r.X - completeBounds.X; completeBounds.X = r.X; } if (completeBounds.Y > r.Y) { completeBounds.Height += r.Y - completeBounds.Y; completeBounds.Y = r.Y; } if (completeBounds.Right < r.Right) { completeBounds.Width += r.Right - completeBounds.Right; } if (completeBounds.Bottom < r.Bottom) { completeBounds.Height += r.Bottom - completeBounds.Bottom; } } } //float d = DistanceTopLeft; //if (shape.Parent != null) float d = DistanceBetweenShapes; if (completeBounds == RectangleF.Empty) { completeBounds = new RectangleF(d, d, 0, 0); } // 1. see if we can fit a shape over completeBounds or to the left of it if (completeBounds.Top - rectShape.Height - d > d) { shape.SetLocation(new PointD(d, d)); shape.UpdateAbsoluteLocation(); } else if (completeBounds.Left - rectShape.Width - d > d) { shape.SetLocation(new PointD(d, d)); shape.UpdateAbsoluteLocation(); } else { // create region and exclude existing shapes Region region = new Region(new RectangleF(d, d, completeBounds.Width + completeBounds.X - d, completeBounds.Height + completeBounds.Y - d)); foreach (RectangleF r in allShapes) { region.Exclude(r); } double right = completeBounds.Width + completeBounds.X; double bottom = completeBounds.Height + completeBounds.Y; /* * foreach (LinkShape linkShape in shape.Diagram.LinkShapes) * { * List<PointF> points = new List<PointF>(); * for (int i = 0; i < linkShape.EdgePoints.Count; i++) * { * PointF p = new PointF((float)linkShape.EdgePoints[i].X, (float)linkShape.EdgePoints[i].Y); * if (p.X <= right && p.Y <= bottom) * points.Add(p); * } * * //new System.Drawing.Drawing2D.GraphicsPath(points.ToArray(), * if (points.Count > 1) * { * System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); * path.AddLines(points.ToArray()); * region.Exclude(path); * } * }*/ // get free areas var rects = region.GetRegionScans(new System.Drawing.Drawing2D.Matrix()); foreach (RectangleF r in rects) { if (r.Width >= rectShape.Width && r.Height >= rectShape.Height) { shape.SetLocation(new PointD(r.Left, r.Top)); shape.UpdateAbsoluteLocation(); return; } } // 4. if no free are is found, we place the shape under compleBounds or to the right of it if (completeBounds.Width < completeBounds.Height) { shape.SetLocation(new PointD(completeBounds.Right, d)); } else { shape.SetLocation(new PointD(d, completeBounds.Bottom)); } shape.UpdateAbsoluteLocation(); } }
private static void SetPortAtFreePositionOnParent(NodeShape shape) { float width = (float)shape.Bounds.Width; float height = (float)shape.Bounds.Height; float parentWidth = (float)shape.Parent.Bounds.Width; float parentHeight = (float)shape.Parent.Bounds.Height; Dictionary<PortPlacement, int> dict = new Dictionary<PortPlacement, int>(); dict.Add(PortPlacement.Left, 0); dict.Add(PortPlacement.Top, 0); dict.Add(PortPlacement.Bottom, 0); dict.Add(PortPlacement.Right, 0); for (int i = 0; i < shape.Parent.RelativeChildren.Count; i++) { if (shape.Parent.RelativeChildren[i] == shape) continue; dict[shape.Parent.RelativeChildren[i].PlacementSide]++; } List<KeyValuePair<PortPlacement, int>> myList = new List<KeyValuePair<PortPlacement, int>>(dict); myList.Sort((firstPair, nextPair) => { return firstPair.Value.CompareTo(nextPair.Value); }); foreach (KeyValuePair<PortPlacement, int> p in myList) { RectangleF rectH; switch (p.Key) { case PortPlacement.Left: rectH = new RectangleF(-width / 2, 0, width, parentHeight); break; case PortPlacement.Top: rectH = new RectangleF(0, -height / 2, parentWidth, height); break; case PortPlacement.Right: rectH = new RectangleF(parentWidth - width / 2, 0, width, parentHeight); break; case PortPlacement.Bottom: rectH = new RectangleF(0, parentHeight - height / 2, parentWidth, height); break; default: throw new NotSupportedException(); } if (SetPortAtFreePositionOnParent(shape, p.Key, rectH)) { return; } } shape.SetLocation(NodeShape.CorrectPortLocation(shape.Parent, shape, new PointD(0, 0))); }
public static void SetAtFreePositionOnParent(NodeShape shape) { IList<NodeShape> shapes; if (shape.Parent == null) { // free position on diagram Diagram diagram = shape.Diagram; shapes = diagram.Children; } else { if (shape.IsRelativeChildShape) { SetPortAtFreePositionOnParent(shape); return; } // free position on parent shape shapes = shape.Parent.NestedChildren; } // simple algo - need better? RectangleF rectShape = new RectangleF(0, 0, (float)shape.Size.Width, (float)shape.Size.Height); RectangleF completeBounds = RectangleF.Empty; List<RectangleF> allShapes = new List<RectangleF>(); for (int i = 0; i < shapes.Count; i++) { if (shapes[i] == shape) continue; RectangleF r = new RectangleF((float)shapes[i].Location.X, (float)shapes[i].Location.Y, (float)shapes[i].Size.Width, (float)shapes[i].Size.Height); // add DistanceBetweenShapes if( r.X > DistanceBetweenShapes ) r.X -= DistanceBetweenShapes; if( r.Y > DistanceBetweenShapes ) r.Y -= DistanceBetweenShapes; if (r.X > DistanceBetweenShapes) r.Width += DistanceBetweenShapes * 2; else r.Width += DistanceBetweenShapes; if (r.Y > DistanceBetweenShapes) r.Height += DistanceBetweenShapes * 2; else r.Height += DistanceBetweenShapes; allShapes.Add(r); if (completeBounds == RectangleF.Empty) { // set initial complete bounds completeBounds = r; } else { // extend complete bounds if (completeBounds.X > r.X) { completeBounds.Width += r.X - completeBounds.X; completeBounds.X = r.X; } if (completeBounds.Y > r.Y) { completeBounds.Height += r.Y - completeBounds.Y; completeBounds.Y = r.Y; } if (completeBounds.Right < r.Right) completeBounds.Width += r.Right - completeBounds.Right; if (completeBounds.Bottom < r.Bottom) completeBounds.Height += r.Bottom - completeBounds.Bottom; } } //float d = DistanceTopLeft; //if (shape.Parent != null) float d = DistanceBetweenShapes; if (completeBounds == RectangleF.Empty) completeBounds = new RectangleF(d, d, 0, 0); // 1. see if we can fit a shape over completeBounds or to the left of it if (completeBounds.Top - rectShape.Height - d > d) { shape.SetLocation(new PointD(d, d)); shape.UpdateAbsoluteLocation(); } else if (completeBounds.Left - rectShape.Width - d > d) { shape.SetLocation(new PointD(d, d)); shape.UpdateAbsoluteLocation(); } else { // create region and exclude existing shapes Region region = new Region(new RectangleF(d, d, completeBounds.Width + completeBounds.X - d, completeBounds.Height + completeBounds.Y - d)); foreach (RectangleF r in allShapes) region.Exclude(r); double right = completeBounds.Width + completeBounds.X; double bottom = completeBounds.Height + completeBounds.Y; /* foreach (LinkShape linkShape in shape.Diagram.LinkShapes) { List<PointF> points = new List<PointF>(); for (int i = 0; i < linkShape.EdgePoints.Count; i++) { PointF p = new PointF((float)linkShape.EdgePoints[i].X, (float)linkShape.EdgePoints[i].Y); if (p.X <= right && p.Y <= bottom) points.Add(p); } //new System.Drawing.Drawing2D.GraphicsPath(points.ToArray(), if (points.Count > 1) { System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); path.AddLines(points.ToArray()); region.Exclude(path); } }*/ // get free areas var rects = region.GetRegionScans(new System.Drawing.Drawing2D.Matrix()); foreach(RectangleF r in rects ) if (r.Width >= rectShape.Width && r.Height >= rectShape.Height) { shape.SetLocation(new PointD(r.Left, r.Top)); shape.UpdateAbsoluteLocation(); return; } // 4. if no free are is found, we place the shape under compleBounds or to the right of it if (completeBounds.Width < completeBounds.Height) shape.SetLocation(new PointD(completeBounds.Right, d)); else shape.SetLocation(new PointD(d, completeBounds.Bottom)); shape.UpdateAbsoluteLocation(); } }