/// <summary> /// DeleteRule: typeof(ORMSolutions.ORMArchitect.Core.ObjectModel.ExclusiveOrConstraintCoupler), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AddShapeRulePriority; /// Split a single shape into two shapes when a exclusion constraint /// is decoupled from a mandatory constraint /// </summary> private static void ExclusiveOrCouplerDeletedRule(ElementDeletedEventArgs e) { ExclusiveOrConstraintCoupler link = e.ModelElement as ExclusiveOrConstraintCoupler; MandatoryConstraint mandatory = link.MandatoryConstraint; ExclusionConstraint exclusion = link.ExclusionConstraint; if (!mandatory.IsDeleted && !exclusion.IsDeleted) { LinkedElementCollection <PresentationElement> pels = PresentationViewsSubject.GetPresentation(mandatory); int pelCount = pels.Count; for (int i = 0; i < pelCount; ++i) { ExternalConstraintShape shape = pels[i] as ExternalConstraintShape; if (shape != null) { ORMDiagram diagram = (ORMDiagram)shape.Diagram; RectangleD bounds = shape.AbsoluteBounds; double width = bounds.Width; bounds.Offset(-width / 2, 0); bounds = diagram.BoundsRules.GetCompliantBounds(shape, bounds); shape.AbsoluteBounds = bounds; bounds.Offset(width, 0); diagram.PlaceORMElementOnDiagram(null, exclusion, bounds.Location, ORMPlacementOption.None, null, null); } } } }
/// <summary> /// AddRule: typeof(ORMSolutions.ORMArchitect.Core.ObjectModel.ExclusiveOrConstraintCoupler), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AddShapeRulePriority; /// Remove shapes associated with the exclusion constraint /// when exclusion and mandatory constraints are coupled. /// </summary> private static void ExclusiveOrCouplerAddedRule(ElementAddedEventArgs e) { ExclusiveOrConstraintCoupler link = e.ModelElement as ExclusiveOrConstraintCoupler; MandatoryConstraint mandatory = link.MandatoryConstraint; ExclusionConstraint exclusion = link.ExclusionConstraint; LinkedElementCollection <PresentationElement> pels = PresentationViewsSubject.GetPresentation(exclusion); for (int i = pels.Count - 1; i >= 0; --i) { ExternalConstraintShape shape = pels[i] as ExternalConstraintShape; if (shape != null) { shape.Delete(); } } InvalidateAssociatedDisplay(mandatory); }
/// <summary> /// Overrideable shape painting for use after the paint helper is initialized /// </summary> /// <param name="e">The event arguments</param> /// <param name="helper">The initialized pain helper.</param> protected virtual void OnPaintShape(DiagramPaintEventArgs e, ref PaintHelper helper) { IConstraint constraint = AssociatedConstraint; RectangleD bounds = AbsoluteBounds; RectangleF boundsF = RectangleD.ToRectangleF(bounds); Graphics g = e.Graphics; const double cos45 = 0.70710678118654752440084436210485; Pen pen = helper.Pen; Brush brush = helper.Brush; bool noDeonticDot = false; switch (constraint.ConstraintType) { #region Frequency case ConstraintType.Frequency: { break; } #endregion #region Ring case ConstraintType.Ring: // Note: goto default here restores the frowny face. However, // with the error feedback, we already have UI indicating there // is a problem. noDeonticDot = true; break; #endregion #region ValueComparison case ConstraintType.ValueComparison: noDeonticDot = true; break; #endregion // ValueComparison #region Equality case ConstraintType.Equality: { double xOffset = bounds.Width * .3; float xLeft = (float)(bounds.Left + xOffset); float xRight = (float)(bounds.Right - xOffset); double yCenter = bounds.Top + bounds.Height / 2; double yOffset = (double)pen.Width * 1.0; float y = (float)(yCenter - yOffset); g.DrawLine(pen, xLeft, y, xRight, y); y = (float)(yCenter + yOffset); g.DrawLine(pen, xLeft, y, xRight, y); break; } #endregion #region Mandatory case ConstraintType.DisjunctiveMandatory: { // Draw the dot RectangleF shrinkBounds = boundsF; shrinkBounds.Inflate(-boundsF.Width * .22f, -boundsF.Height * .22f); g.FillEllipse(brush, shrinkBounds); if (null != ExclusiveOrConstraintCoupler.GetExclusiveOrExclusionConstraint((MandatoryConstraint)constraint)) { goto case ConstraintType.Exclusion; } break; } #endregion #region Exclusion case ConstraintType.Exclusion: { // Draw the X double offset = (bounds.Width + pen.Width) * (1 - cos45) / 2; float leftX = (float)(bounds.Left + offset); float rightX = (float)(bounds.Right - offset); float topY = (float)(bounds.Top + offset); float bottomY = (float)(bounds.Bottom - offset); g.DrawLine(pen, leftX, topY, rightX, bottomY); g.DrawLine(pen, leftX, bottomY, rightX, topY); break; } #endregion #region Uniqueness case ConstraintType.ExternalUniqueness: { // Draw a single line for a uniqueness constraint and a double // line for preferred uniqueness UniquenessConstraint euc = constraint as UniquenessConstraint; double widthAdjust = (double)pen.Width / 2; float xLeft = (float)(bounds.Left + widthAdjust); float xRight = (float)(bounds.Right - widthAdjust); if (euc.IsPreferred) { double yCenter = bounds.Top + bounds.Height / 2; double yOffset = (double)pen.Width * .7; float y = (float)(yCenter - yOffset); g.DrawLine(pen, xLeft, y, xRight, y); y = (float)(yCenter + yOffset); g.DrawLine(pen, xLeft, y, xRight, y); } else { float y = (float)(bounds.Top + bounds.Height / 2); g.DrawLine(pen, xLeft, y, xRight, y); } break; } #endregion #region Subset case ConstraintType.Subset: { RectangleD arcBounds = bounds; double shrinkBy = -bounds.Height * .35; double yOffset = pen.Width * .7; double xOffset = shrinkBy * .35; arcBounds.Inflate(shrinkBy, shrinkBy); arcBounds.Offset(xOffset, -yOffset); g.DrawArc(pen, RectangleD.ToRectangleF(arcBounds), 90, 180); float xLeft = (float)arcBounds.Center.X; float xRight = (float)(bounds.Right + shrinkBy - xOffset); float y = (float)arcBounds.Top; g.DrawLine(pen, xLeft, y, xRight, y); y = (float)arcBounds.Bottom; g.DrawLine(pen, xLeft, y, xRight, y); y = (float)(arcBounds.Bottom + yOffset + yOffset); g.DrawLine(pen, (float)arcBounds.Left, y, xRight, y); break; } #endregion #region Fallback (default) default: { // Draws a frowny face float eyeY = boundsF.Y + (boundsF.Height / 3); PointF leftEyeStart = new PointF(boundsF.X + (boundsF.Width * 0.3f), eyeY); PointF leftEyeEnd = new PointF(boundsF.X + (boundsF.Width * 0.4f), eyeY); PointF rightEyeStart = new PointF(boundsF.X + (boundsF.Width * 0.6f), eyeY); PointF rightEyeEnd = new PointF(boundsF.X + (boundsF.Width * 0.7f), eyeY); g.DrawLine(pen, leftEyeStart, leftEyeEnd); g.DrawLine(pen, rightEyeStart, rightEyeEnd); float mouthLeft = boundsF.X + (boundsF.Width * 0.25f); float mouthTop = boundsF.Y + (boundsF.Height * 0.55f); RectangleF mouthRectangle = new RectangleF(mouthLeft, mouthTop, boundsF.Width * 0.5f, boundsF.Height * 0.25f); g.DrawArc(pen, mouthRectangle, 180, 180); break; } #endregion } if (!noDeonticDot && constraint.Modality == ConstraintModality.Deontic) { float startPenWidth = pen.Width; pen.Width = startPenWidth * .70f; float boxSide = (float)((1 - cos45) * bounds.Width); g.FillEllipse(this.StyleSet.GetBrush(DiagramBrushes.DiagramBackground), (float)bounds.Left, (float)bounds.Top, boxSide, boxSide); g.DrawArc(pen, (float)bounds.Left, (float)bounds.Top, boxSide, boxSide, 0, 360); pen.Width = startPenWidth; } }