/// <summary> /// ChangeRule: typeof(ORMBaseBinaryLinkShape), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AutoLayoutShapesRulePriority; /// Keep relative child elements a fixed distance away from the fact /// when the shape changes. /// </summary> private static void LinkChangeRule(ElementPropertyChangedEventArgs e) { Guid attributeId = e.DomainProperty.Id; if (attributeId == ORMBaseBinaryLinkShape.EdgePointsDomainPropertyId) { ORMBaseBinaryLinkShape parentShape = e.ModelElement as ORMBaseBinaryLinkShape; LinkedElementCollection <ShapeElement> childShapes = parentShape.RelativeChildShapes; int childCount = childShapes.Count; for (int i = 0; i < childCount; ++i) { LinkConnectorShape linkConnector = childShapes[i] as LinkConnectorShape; if (linkConnector != null) { RectangleD bounds = parentShape.AbsoluteBoundingBox; linkConnector.Location = new PointD(bounds.Width / 2, bounds.Height / 2); ReadOnlyCollection <LinkConnectsToNode> links = DomainRoleInfo.GetElementLinks <LinkConnectsToNode>(linkConnector, LinkConnectsToNode.NodesDomainRoleId); int linksCount = links.Count; for (int j = 0; j < linksCount; ++j) { LinkConnectsToNode link = links[j]; BinaryLinkShape linkShape = link.Link as BinaryLinkShape; if (linkShape != null) { // Changing the location is not reliably reconnecting all shapes, especially // during load. Force the link to reconnect with a RecalculateRoute call linkShape.RecalculateRoute(); } } break; } } } }
/// <summary> /// ORM diagrams need to connect links to other links, but this is /// not supported directly by the framework, so we create a dummy /// node shape that tracks the center of the link line and connect /// to the shape instead. The currently ORM diagram requirements /// are simple: we are only called with an opposite ExternalConstraintShape, /// and we can return the same shape for all requests. /// Implements <see cref="IProvideConnectorShape.GetUniqueConnectorShape"/> /// </summary> protected NodeShape GetUniqueConnectorShape(ShapeElement oppositeShape, ModelElement ignoreLinkShapesFor) { LinkConnectorShape retVal = null; LinkedElementCollection <ShapeElement> childShapes = RelativeChildShapes; foreach (ShapeElement shape in childShapes) { retVal = shape as LinkConnectorShape; if (retVal != null) { return(retVal); } } retVal = new LinkConnectorShape(Partition); RectangleD bounds = AbsoluteBoundingBox; childShapes.Add(retVal); retVal.Location = new PointD(bounds.Width / 2, bounds.Height / 2); return(retVal); }