// Surchage pour pouvoir accéder à la méthode protégée de PortPlacementHelper /// <summary> /// Gets the next edge children. /// </summary> /// <param name="currentEdge">The current edge.</param> /// <param name="parentShape">The parent shape.</param> /// <param name="edgeList">The edge list.</param> /// <param name="center">The center.</param> /// <returns></returns> protected override PortPlacement GetNextEdgeChildren(PortPlacement currentEdge, NodeShape parentShape, out ArrayList edgeList, out PointD center) { PortPlacement placement = PortPlacement.None; do { placement = base.GetNextEdgeChildren(currentEdge, parentShape, out edgeList, out center); } while (placement == PortPlacement.Top || placement == PortPlacement.Bottom); return(placement); }
/// <summary> /// This function corrects the given proposed location if the given child shape is a relative shape and /// is only allowed to be placed on the edge of its parent. /// </summary> /// <param name="parentShape">Parent shape.</param> /// <param name="childShape">Child shape.</param> /// <param name="proposedLocation">Proposed location.</param> /// <remarks> /// This function needs to be called withing a modeling transaction. /// /// This function assigns new values to Location and PortPlacement if necessary. /// </remarks> /// <returns> /// Location that was assigned to the shape. It might have the same value as the location /// the shape had before calling this function. /// </returns> public static PointD CorrectPortLocation(NodeShape parentShape, NodeShape childShape, PointD proposedLocation) { if (parentShape == null) { throw new ArgumentNullException("parentShape"); } if (childShape == null) { throw new ArgumentNullException("childShape"); } if (!childShape.IsRelativeChildShape || childShape.MovementBehaviour != ShapeMovementBehaviour.PositionOnEdgeOfParent) { return(proposedLocation); } RectangleD rectParent = parentShape.Bounds; RectangleD proposedBounds = new RectangleD(proposedLocation, childShape.Size); PortPlacement placement = NodeShape.GetPortPlacement(rectParent, proposedBounds); return(CorrectPortLocation(placement, parentShape, childShape, proposedLocation)); }
private static bool SetPortAtFreePositionOnParent(NodeShape shape, PortPlacement side, RectangleF freeRectangle) { List <RectangleF> freeRectangles = new List <RectangleF>(); freeRectangles.Add(freeRectangle); for (int i = 0; i < shape.Parent.RelativeChildren.Count; i++) { if (shape.Parent.RelativeChildren[i] == shape) { continue; } if (shape.Parent.RelativeChildren[i].PlacementSide != side) { continue; } RectangleF s = shape.Parent.RelativeChildren[i].Bounds.ToRectangleF(); for (int y = freeRectangles.Count - 1; y >= 0; y--) { RectangleF r = freeRectangles[y]; RectangleF t = r; r.Intersect(s); if (!r.IsEmpty) { // remove r from freeRectangley[y] --> yields <=2 rects // add 2 rects to freeRectangles freeRectangles.RemoveAt(y); switch (side) { case PortPlacement.Left: case PortPlacement.Right: if (t.Y < r.Y) { // first r RectangleF r1 = new RectangleF(t.X, t.Y, t.Width, r.Y - t.Y); freeRectangles.Add(r1); } if (r.Bottom < t.Bottom) { // second r RectangleF r2 = new RectangleF(t.X, r.Bottom, t.Width, t.Bottom - r.Bottom); freeRectangles.Add(r2); } break; case PortPlacement.Top: case PortPlacement.Bottom: if (t.X < r.X) { // first r RectangleF r1 = new RectangleF(t.X, t.Y, r.X - t.X, t.Height); freeRectangles.Add(r1); } if (r.Right < t.Right) { // second r RectangleF r2 = new RectangleF(r.Right, t.Y, t.Right - r.Right, t.Height); freeRectangles.Add(r2); } break; } } } } // try to place at a fitting free rectangle foreach (RectangleF r in freeRectangles) { if (r.Width >= shape.Bounds.Width && r.Height >= shape.Bounds.Height) { shape.Location = new PointD(r.X, r.Y); shape.PlacementSide = side; shape.UpdateAbsoluteLocation(); return(true); } } return(false); }
private static bool SetPortAtFreePositionOnParent(NodeShape shape, PortPlacement side, RectangleF freeRectangle) { List<RectangleF> freeRectangles = new List<RectangleF>(); freeRectangles.Add(freeRectangle); for (int i = 0; i < shape.Parent.RelativeChildren.Count; i++) { if (shape.Parent.RelativeChildren[i] == shape) continue; if (shape.Parent.RelativeChildren[i].PlacementSide != side) continue; RectangleF s = shape.Parent.RelativeChildren[i].Bounds.ToRectangleF(); for (int y = freeRectangles.Count - 1; y >= 0; y--) { RectangleF r = freeRectangles[y]; RectangleF t = r; r.Intersect(s); if (!r.IsEmpty) { // remove r from freeRectangley[y] --> yields <=2 rects // add 2 rects to freeRectangles freeRectangles.RemoveAt(y); switch (side) { case PortPlacement.Left: case PortPlacement.Right: if (t.Y < r.Y) { // first r RectangleF r1 = new RectangleF(t.X, t.Y, t.Width, r.Y - t.Y); freeRectangles.Add(r1); } if (r.Bottom < t.Bottom) { // second r RectangleF r2 = new RectangleF(t.X, r.Bottom, t.Width, t.Bottom - r.Bottom); freeRectangles.Add(r2); } break; case PortPlacement.Top: case PortPlacement.Bottom: if (t.X < r.X) { // first r RectangleF r1 = new RectangleF(t.X, t.Y, r.X - t.X, t.Height); freeRectangles.Add(r1); } if (r.Right < t.Right) { // second r RectangleF r2 = new RectangleF(r.Right, t.Y, t.Right - r.Right, t.Height); freeRectangles.Add(r2); } break; } } } } // try to place at a fitting free rectangle foreach (RectangleF r in freeRectangles) { if (r.Width >= shape.Bounds.Width && r.Height >= shape.Bounds.Height) { shape.Location = new PointD(r.X, r.Y); shape.PlacementSide = side; shape.UpdateAbsoluteLocation(); return true; } } return false; }
/// <summary> /// This function corrects the given proposed location if the given child shape is a relative shape and /// is only allowed to be placed on the edge of its parent. /// </summary> /// <param name="placement">Proposed placement.</param> /// <param name="parentShape">Parent shape.</param> /// <param name="childShape">Child shape.</param> /// <param name="proposedLocation">Proposed location.</param> /// <remarks> /// This function needs to be called withing a modeling transaction. /// /// This function assigns new values to Location and PortPlacement if necessary. /// </remarks> /// <returns> /// Location that was assigned to the shape. It might have the same value as the location /// the shape had before calling this function. /// </returns> public static PointD CorrectPortLocation(PortPlacement placement, NodeShape parentShape, NodeShape childShape, PointD proposedLocation) { PointD newLocation = proposedLocation; RectangleD rectParent = parentShape.Bounds; switch (placement) { case PortPlacement.Left: newLocation.X = -childShape.Size.Width / 2.0; if (newLocation.Y < 0.0) newLocation.Y = 0.0; else if (newLocation.Y > (rectParent.Height - childShape.Size.Height)) newLocation.Y = rectParent.Height - childShape.Size.Height; break; case PortPlacement.Top: newLocation.Y = -childShape.Size.Height / 2.0; if (newLocation.X < 0.0) newLocation.X = 0.0; else if (newLocation.X > (rectParent.Width - childShape.Size.Width)) newLocation.X = rectParent.Width - childShape.Size.Width; break; case PortPlacement.Right: newLocation.X = rectParent.Width - (childShape.Size.Width / 2.0); if (newLocation.Y < 0.0) newLocation.Y = 0.0; else if (newLocation.Y > (rectParent.Height - childShape.Size.Height)) newLocation.Y = rectParent.Height - childShape.Size.Height; break; case PortPlacement.Bottom: newLocation.Y = rectParent.Height - (childShape.Size.Height / 2.0); if (newLocation.X < 0.0) newLocation.X = 0.0; else if (newLocation.X > (rectParent.Width - childShape.Size.Width)) newLocation.X = rectParent.Width - childShape.Size.Width; break; } if (childShape.Location != newLocation) { childShape.Location = newLocation; childShape.PlacementSide = placement; childShape.UpdateAbsoluteLocation(); } return newLocation; }
/// <summary> /// This function corrects the given proposed location if the given child shape is a relative shape and /// is only allowed to be placed on the edge of its parent. /// </summary> /// <param name="placement">Proposed placement.</param> /// <param name="parentShape">Parent shape.</param> /// <param name="childShape">Child shape.</param> /// <param name="proposedLocation">Proposed location.</param> /// <remarks> /// This function needs to be called withing a modeling transaction. /// /// This function assigns new values to Location and PortPlacement if necessary. /// </remarks> /// <returns> /// Location that was assigned to the shape. It might have the same value as the location /// the shape had before calling this function. /// </returns> public static PointD CorrectPortLocation(PortPlacement placement, NodeShape parentShape, NodeShape childShape, PointD proposedLocation) { PointD newLocation = proposedLocation; RectangleD rectParent = parentShape.Bounds; switch (placement) { case PortPlacement.Left: newLocation.X = -childShape.Size.Width / 2.0; if (newLocation.Y < 0.0) { newLocation.Y = 0.0; } else if (newLocation.Y > (rectParent.Height - childShape.Size.Height)) { newLocation.Y = rectParent.Height - childShape.Size.Height; } break; case PortPlacement.Top: newLocation.Y = -childShape.Size.Height / 2.0; if (newLocation.X < 0.0) { newLocation.X = 0.0; } else if (newLocation.X > (rectParent.Width - childShape.Size.Width)) { newLocation.X = rectParent.Width - childShape.Size.Width; } break; case PortPlacement.Right: newLocation.X = rectParent.Width - (childShape.Size.Width / 2.0); if (newLocation.Y < 0.0) { newLocation.Y = 0.0; } else if (newLocation.Y > (rectParent.Height - childShape.Size.Height)) { newLocation.Y = rectParent.Height - childShape.Size.Height; } break; case PortPlacement.Bottom: newLocation.Y = rectParent.Height - (childShape.Size.Height / 2.0); if (newLocation.X < 0.0) { newLocation.X = 0.0; } else if (newLocation.X > (rectParent.Width - childShape.Size.Width)) { newLocation.X = rectParent.Width - childShape.Size.Width; } break; } if (childShape.Location != newLocation) { childShape.Location = newLocation; childShape.PlacementSide = placement; childShape.UpdateAbsoluteLocation(); } return(newLocation); }