private static void DelayValidateExternalConstraintShapeFullyConnected(ModelElement element) { if (!element.IsDeleted) { ExternalConstraintShape shape = (ExternalConstraintShape)element; int linkCount = 0; foreach (LinkConnectsToNode link in LinkConnectsToNode.GetLinksToLink(shape)) { if (link.Link is ExternalConstraintLink) { ++linkCount; } } bool keepShape = false; IConstraint constraint = shape.AssociatedConstraint; switch (constraint.ConstraintStorageStyle) { case ConstraintStorageStyle.SetConstraint: keepShape = ((SetConstraint)constraint).FactTypeCollection.Count == linkCount; break; case ConstraintStorageStyle.SetComparisonConstraint: keepShape = ((SetComparisonConstraint)constraint).FactTypeCollection.Count == linkCount; break; } if (!keepShape) { shape.Delete(); } } }
/// <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> /// ChangeRule: typeof(ORMSolutions.ORMArchitect.Core.ObjectModel.ValueComparisonConstraint), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AddConnectionRulePriority; /// </summary> private static void ValueComparisonConstraintPropertyChangeRule(ElementPropertyChangedEventArgs e) { if (e.DomainProperty.Id == ValueComparisonConstraint.OperatorDomainPropertyId) { ModelElement element = e.ModelElement; if (!element.IsDeleted) { // Redraw the ring constraint wherever it is displayed. foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(element)) { ValueComparisonConstraintShape constraintShape; if (null != (constraintShape = pel as ValueComparisonConstraintShape)) { ((IInvalidateDisplay)constraintShape).InvalidateRequired(true); if (ValueComparisonConstraint.IsDirectionalOperator((ValueComparisonOperator)e.OldValue) ^ ValueComparisonConstraint.IsDirectionalOperator((ValueComparisonOperator)e.NewValue)) { foreach (LinkShape linkShape in LinkConnectsToNode.GetLink(constraintShape)) { ExternalConstraintLink constraintLink; if (null != (constraintLink = linkShape as ExternalConstraintLink)) { ((IInvalidateDisplay)constraintLink).InvalidateRequired(true); } } } } } } } }
/// <summary> /// AddRule: typeof(Microsoft.VisualStudio.Modeling.Diagrams.LinkConnectsToNode) /// Make sure connected fact type shapes properly display their role bars /// </summary> private static void VerifyedConnectedShapeAddedRule(ElementAddedEventArgs e) { LinkConnectsToNode connectLink = (LinkConnectsToNode)e.ModelElement; FactTypeShape factTypeShape; if (connectLink.Link is ExternalConstraintLink && null != (factTypeShape = connectLink.Nodes as FactTypeShape)) { FrameworkDomainModel.DelayValidateElement(factTypeShape, DelayValidateFactTypeShapeSize); } }
/// <summary> /// DeletingRule: typeof(Microsoft.VisualStudio.Modeling.Diagrams.LinkConnectsToNode) /// External constraint shapes can only be drawn if they show all of their /// links, so automatically remove them if a connecting shape is removed. /// </summary> private static void VerifyConnectedShapeShapeDeletingRule(ElementDeletingEventArgs e) { LinkConnectsToNode connectLink = (LinkConnectsToNode)e.ModelElement; ExternalConstraintLink link; ModelElement linkMel; ModelElement shapeMel; if (null != (link = connectLink.Link as ExternalConstraintLink) && null != (linkMel = link.ModelElement) && !linkMel.IsDeleting) { NodeShape linkNode = connectLink.Nodes; ExternalConstraintShape constraintShape = linkNode as ExternalConstraintShape; NodeShape oppositeShape = null; // The ToShape (as opposed to FromShape) here needs to be in // sync with the code in ConfiguringAsChildOf if (constraintShape == null) { constraintShape = link.ToShape as ExternalConstraintShape; oppositeShape = linkNode; } else { oppositeShape = link.FromShape; } if (oppositeShape != null && constraintShape != null && null != (shapeMel = constraintShape.ModelElement) && !shapeMel.IsDeleting) { if (!constraintShape.IsDeleting) { FrameworkDomainModel.DelayValidateElement(constraintShape, DelayValidateExternalConstraintShapeFullyConnected); } // Delay, fact type shape size will not be accurate until deletion is completed. FactTypeShape factTypeShape = MultiShapeUtility.ResolvePrimaryShape(oppositeShape) as FactTypeShape; if (factTypeShape != null && !factTypeShape.IsDeleting) { FrameworkDomainModel.DelayValidateElement(factTypeShape, DelayValidateFactTypeShapeSize); } } } }