Beispiel #1
0
 /// <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);
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Beispiel #2
0
        /// <summary>
        /// Paint the shape contents based on the operator type.
        /// </summary>
        protected override void OnPaintShape(DiagramPaintEventArgs e, ref PaintHelper helper)
        {
            base.OnPaintShape(e, ref helper);
            ValueComparisonConstraint comparisonConstraint = this.AssociatedValueComparisonConstraint;
            RectangleD bounds  = this.AbsoluteBounds;
            RectangleF boundsF = RectangleD.ToRectangleF(bounds);
            Graphics   g       = e.Graphics;
            ValueComparisonOperator comparisonOperator = comparisonConstraint.Operator;
            Brush brush = helper.Brush;

            // Draw the left and right comparison dots
            float heightF     = boundsF.Height;
            float dotDiameter = heightF * DOT_FACTOR;
            float dotRadius   = dotDiameter / 2;
            float dotTop      = boundsF.Top + heightF / 2 - dotRadius;

            g.FillEllipse(brush, boundsF.Left - dotRadius, dotTop, dotDiameter, dotDiameter);
            g.FillEllipse(brush, boundsF.Right - dotRadius, dotTop, dotDiameter, dotDiameter);

            if (comparisonOperator != ValueComparisonOperator.Undefined)             // Undefined just draws the error state
            {
                // Draw the operator using a different pen.
                Pen pen = StyleSet.GetPen(OperatorResource);

                // Get the correct pen color from the provided outline pen
                Color startColor = pen.Color;
                Color shapeColor = helper.Pen.Color;                 // The paint helper has already updated the color, just use it.
                bool  updateColor;
                if (updateColor = (startColor != shapeColor))
                {
                    pen.Color = shapeColor;
                }

                // Get a clipping rectangle we can draw inside of. This
                // gives us a nice vertical clip on the open side of the
                // comparator, as well as a region safely inside the shape
                // outline.
                const double inscribedRectAngle    = 1d / 3 * Math.PI; // 60 degrees from center point of shape to shape border.
                const float  equalsOffsetFactor    = .8f;
                const double noEqualityPiDivisor   = 6d;               // 30 degree angle on comparator line
                const double withEqualityPiDivisor = 7.5d;             // 24 degree angle on comparator line
                double       inscribedCos          = Math.Cos(inscribedRectAngle);
                double       inscribedSin          = Math.Sin(inscribedRectAngle);
                double       width  = bounds.Width;
                double       height = bounds.Height;
                bounds = new RectangleD(
                    bounds.Left + (1 - inscribedCos) * width / 2,
                    bounds.Top + (1 - inscribedSin) * height / 2,
                    inscribedCos * width,
                    inscribedSin * height);
                //width = bounds.Width; // not used below
                height  = bounds.Height;
                boundsF = RectangleD.ToRectangleF(bounds);
                bool drawComparator = true;
                bool drawEquality   = false;
                bool slashEquality  = false;

                float penWidth    = pen.Width;
                float openSideX   = 0f;
                float closedSideX = 0f;
                switch (comparisonOperator)
                {
                case ValueComparisonOperator.LessThanOrEqual:
                    drawEquality = true;
                    goto case ValueComparisonOperator.LessThan;

                case ValueComparisonOperator.LessThan:
                    openSideX   = boundsF.Right;
                    closedSideX = boundsF.Left + penWidth / 2;
                    break;

                case ValueComparisonOperator.GreaterThanOrEqual:
                    drawEquality = true;
                    goto case ValueComparisonOperator.GreaterThan;

                case ValueComparisonOperator.GreaterThan:
                    openSideX   = boundsF.Left;
                    closedSideX = boundsF.Right - penWidth / 2;
                    break;

                case ValueComparisonOperator.Equal:
                    drawComparator = false;
                    drawEquality   = true;
                    break;

                case ValueComparisonOperator.NotEqual:
                    drawComparator = false;
                    drawEquality   = true;
                    slashEquality  = true;
                    break;
                }

                double halfHeight = height / 2;
                double top        = bounds.Top;
                float  middle     = (float)(top + halfHeight);
                float  topTip;
                float  bottomTip;
                if (drawComparator)
                {
                    g.SetClip(boundsF);
                    // Use a path so that we get a clean join between the top and bottom lines.
                    float  equalsOffset = drawEquality ? penWidth * equalsOffsetFactor : 0f;
                    double offsetSin    = Math.Sin(Math.PI / (drawEquality ? withEqualityPiDivisor : noEqualityPiDivisor));
                    topTip    = (float)(top + halfHeight * (1d - offsetSin));
                    bottomTip = (float)(top + halfHeight * (1d + offsetSin));
                    using (GraphicsPath path = new GraphicsPath())
                    {
                        path.AddLines(new PointF[] {
                            new PointF(openSideX, topTip - equalsOffset),
                            new PointF(closedSideX, middle - equalsOffset),
                            new PointF(openSideX, bottomTip - equalsOffset)
                        });
                        g.DrawPath(pen, path);
                    }

                    if (drawEquality)
                    {
                        bottomTip += equalsOffset;
                        g.DrawLine(
                            pen,
                            boundsF.Left,
                            bottomTip,
                            boundsF.Right,
                            bottomTip);
                    }
                }
                else if (drawEquality)
                {
                    g.SetClip(boundsF);
                    openSideX   = boundsF.Left;                   // Convenient variables, used for left and right
                    closedSideX = boundsF.Right;
                    float equalsOffset = 1.5f * penWidth;
                    topTip    = middle - equalsOffset;
                    bottomTip = middle + equalsOffset;
                    g.DrawLine(pen, openSideX, topTip, closedSideX, topTip);
                    g.DrawLine(pen, openSideX, bottomTip, closedSideX, bottomTip);
                    if (slashEquality)
                    {
                        // Clip tighter so that the top and bottom of the lines
                        // are clipped horizontally and don't touch the edge lines.
                        g.ResetClip();
                        boundsF.Inflate(0f, -penWidth * 1.25f);
                        g.SetClip(boundsF);
                        g.DrawLine(pen, openSideX + penWidth, boundsF.Bottom, closedSideX - penWidth, boundsF.Top);
                    }
                }
                g.ResetClip();

                // Restore the pen color
                if (updateColor)
                {
                    pen.Color = startColor;
                }
            }
        }