// set clip to make sure child shapes will not overlap parent shape public override void OnPaintShape(DiagramPaintEventArgs e) { ShapeElement parentShape = this.ParentShape; if (parentShape == null || (parentShape is Diagram)) { base.OnPaintShape(e); return; } RectangleD thisRect = this.AbsoluteBoundingBox; thisRect.Inflate(new SizeD(this.OutlinePenWidth, this.OutlinePenWidth)); while (parentShape != null && !(parentShape is Diagram)) { RectangleD clipRect = parentShape.AbsoluteBoundingBox; clipRect.Inflate(new SizeD(-parentShape.OutlinePenWidth, -parentShape.OutlinePenWidth)); thisRect.Intersect(clipRect); parentShape = parentShape.ParentShape; } Region clip = e.Graphics.Clip; e.Graphics.SetClip(RectangleD.ToRectangleF(thisRect), CombineMode.Intersect); base.OnPaintShape(e); e.Graphics.Clip = clip; }
// Methods public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape) { base.DoPaint(e, parentShape); Font font = this.GetFont(e.View); string summrytxt = this.GetSummrytxt(parentShape); string perentSummrytxt = this.GetPerentSummrytxt(parentShape); summrytxt = HttpUtility.HtmlDecode(summrytxt); perentSummrytxt = HttpUtility.HtmlDecode(summrytxt); bool flag = false; this.Overrideheight = 0.15f; RectangleF rect = new RectangleF(this.summeryx, this.summeryy, ((float)parentShape.BoundingBox.Width) - (this.summeryx * 2f), this.Overrideheight); //RectangleF rect =RectangleD.ToRectangleF(parentShape.BoundingBox); rect.X = 0.03f; if (!string.IsNullOrEmpty(perentSummrytxt)) { flag = true; this.Overrideheight += this.Overrideheight; rect = new RectangleF(this.summeryx, this.summeryy, ((float)parentShape.BoundingBox.Width) - (this.summeryx * 2f), this.Overrideheight); } LinearGradientBrush brush = new LinearGradientBrush(rect, Color.FromArgb(0xd4, 0xdd, 0xef), Color.White, 0f); e.Graphics.FillRectangle(brush, rect); e.Graphics.DrawString("Àà:" + summrytxt, font, this.SumerBrush, this.summeryx + 0.05f, this.summeryy + 0.03f); if (flag) { Font font2 = this.GetFont(e.View); e.Graphics.DrawString(perentSummrytxt, font2, this.PerentBrush, this.perentx + 0.05f, this.perenty + 0.03f); } }
// set clip to make sure child shapes will not overlap parent's parent shape public override void OnPaintShape(DiagramPaintEventArgs e) { if (this.ParentShape != null && this.ParentShape.ParentShape != null && !(this.ParentShape.ParentShape is Microsoft.VisualStudio.Modeling.Diagrams.Diagram)) { RectangleD clipRect = this.ParentShape.ParentShape.AbsoluteBoundingBox; clipRect.Inflate(new SizeD(-this.ParentShape.OutlinePenWidth, -this.ParentShape.OutlinePenWidth)); RectangleD thisRect = this.AbsoluteBoundingBox; thisRect.Inflate(new SizeD(this.ParentShape.OutlinePenWidth, this.ParentShape.OutlinePenWidth)); clipRect.Intersect(thisRect); Region clip = e.Graphics.Clip; e.Graphics.SetClip(RectangleD.ToRectangleF(clipRect), CombineMode.Intersect); base.OnPaintShape(e); e.Graphics.Clip = clip; } else { base.OnPaintShape(e); } }
protected static new void DrawDecorator(DiagramPaintEventArgs e, IGeometryHost geometryHost, float rotation, PointD centerRight, LinkDecorator decorator) { SizeD size = LinkShapeGeometry.SizeDecorator; #endif double offsetBy = 0d; bool doOffset = false; ILinkDecoratorSettings settings = decorator as ILinkDecoratorSettings; if (settings != null) { size = settings.DecoratorSize; offsetBy = settings.OffsetBy; doOffset = !VGConstants.FuzzZero(offsetBy, VGConstants.FuzzDistance); } Graphics g = e.Graphics; RectangleD boundingRect = new RectangleD(centerRight.X - size.Width, centerRight.Y - (size.Height / 2), size.Width, size.Height); Matrix rotationMatrix = g.Transform; float offsetX = 0f; float offsetY = 0f; if (doOffset) { double rotationRadians = rotation * Math.PI / 180; offsetX = (float)(offsetBy * Math.Cos(rotationRadians)); offsetY = (float)(offsetBy * Math.Sin(rotationRadians)); rotationMatrix.Translate(offsetX, offsetY); } rotationMatrix.RotateAt(rotation, PointD.ToPointF(centerRight)); g.Transform = rotationMatrix; decorator.DoPaintShape(boundingRect, geometryHost, e); rotationMatrix.RotateAt(-rotation, PointD.ToPointF(centerRight)); if (doOffset) { rotationMatrix.Translate(-offsetX, -offsetY); } g.Transform = rotationMatrix; }
/// <summary> /// Measure text size. If text contains complex script, we will be using TextRenderer.DrawText API to calc the size. /// </summary> internal static void Render(DiagramPaintEventArgs e, string text, Font textFont, Brush brush, RectangleF rect, StringFormat format) { if (ScriptIsComplex(text)) { Graphics g = e.Graphics; SolidBrush brush2 = brush as SolidBrush; Color foreColor = (brush2 != null) ? brush2.Color : SystemColors.HighlightText; Rectangle bounds = new Rectangle((int)(((rect.X + g.Transform.OffsetX) * g.DpiX) * g.PageScale), (int)(((rect.Y + g.Transform.OffsetY) * g.DpiY) * g.PageScale), (int)((rect.Width * g.DpiX) * g.PageScale), (int)((rect.Height * g.DpiY) * g.PageScale)); using (Font font = new Font(textFont.Name, textFont.Size * g.PageScale, textFont.Style, GraphicsUnit.Inch, textFont.GdiCharSet, textFont.GdiVerticalFont)) { TextFormatFlags textFormatFlagsFromStringFormat = GetTextFormatFlagsFromStringFormat(format); Font font2 = null; if (e.IsPrinting) { font2 = ScaleFont(g, font); } TextRenderingHint textRenderingHint = g.TextRenderingHint; g.TextRenderingHint = TextRenderingHint.AntiAlias; TextRenderer.DrawText(g, text, (font2 != null) ? font2 : font, bounds, foreColor, textFormatFlagsFromStringFormat); g.TextRenderingHint = textRenderingHint; if (font2 != null) { font2.Dispose(); } return; } } e.Graphics.DrawString(text, textFont, brush, rect, format); }
/// <summary> /// Initialize paint settings. This is initialized after the base shape /// has been painted. /// </summary> public PaintHelper(DiagramPaintEventArgs e, ExternalConstraintShape constraintShape) { StyleSet styleSet = constraintShape.StyleSet; StyleSetResourceId penId = constraintShape.OutlinePenId; Pen pen = styleSet.GetPen(penId); Brush brush = styleSet.GetBrush(ExternalConstraintBrush); SolidBrush coloredBrush = brush as SolidBrush; // Keep the pen color in sync with the color being used for highlighting Color startColor = constraintShape.UpdateDynamicColor(constraintShape.OutlinePenId, pen); if (startColor.IsEmpty) { startColor = constraintShape.UpdateGeometryLuminosity(e.View, pen); } else { constraintShape.UpdateGeometryLuminosity(e.View, pen); } myPenStartColor = startColor; Color newColor = pen.Color; if (coloredBrush != null) { myBrushStartColor = coloredBrush.Color; coloredBrush.Color = newColor; } else { myBrushStartColor = Color.Empty; } myBrush = brush; myPen = pen; }
public override void OnPaintShape(DiagramPaintEventArgs e) { //Grab the dpi values here because we need them to resize the image correctly in GetImage() dpiX = e.Graphics.DpiX; dpiY = e.Graphics.DpiY; base.OnPaintShape(e); }
/// <summary> /// Paint emphasis for selected shape, but first check if we need to update colors. /// </summary> public override void OnPaintEmphasis(DiagramPaintEventArgs e) { if (!IsColorThemeSet) { SetColorTheme(); } base.OnPaintEmphasis(e); }
// Methods public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape) { base.DoPaint(e, parentShape); if (parentShape.ParentShape is AssociationShape) { AssociationShape shape = parentShape.ParentShape as AssociationShape; Font font = this.GetFont(e.View); e.Graphics.FillRectangle(this.BackBrush, 0.18f, 0f, ((float)parentShape.BoundingBox.Width) - 0.18f, (float)parentShape.BoundingBox.Height); e.Graphics.DrawString(shape.Member.DocSummary, font, this.SumerBrush, (float)0.19f, (float)0.02f); } }
/// <summary> /// Draw the various constraint types /// </summary> protected override void OnPaintShape(DiagramPaintEventArgs e, ref PaintHelper paintHelper) { base.OnPaintShape(e, ref paintHelper); RectangleD bounds = AbsoluteBounds; Graphics g = e.Graphics; StringFormat stringFormat = new StringFormat(); stringFormat.LineAlignment = StringAlignment.Center; stringFormat.Alignment = StringAlignment.Center; Font font = StyleSet.GetFont(FrequencyConstraintTextResource); g.DrawString(GetFrequencyString(), font, paintHelper.Brush, RectangleD.ToRectangleF(bounds), stringFormat); }
//Do our own painting to support arbitrary socket orientations and different socket states (normal, highlighted, connected) public override void OnPaintShape(DiagramPaintEventArgs e) { var socket = this.ModelElement as SocketBase; if (socket == null || socket.Definition == null) { Log.WriteWarning("Socket or socket definition not found for socket shape"); return; } var g = e.Graphics; //Important to save and restore because otherwise we disturb the dc for all other shapes var state = g.Save(); g.TranslateTransform((float)(AbsoluteBoundingBox.Left + Size.Width / 2), (float)(AbsoluteBoundingBox.Top + Size.Height / 2)); g.RotateTransform((float)socket.Definition.Orientation * -1); var points = new PointF[] { new PointF(rectW / 2, -rectH / 8), new PointF(rectW / 2, -rectH / 2), new PointF(-rectW / 2, -rectH / 2), new PointF(-rectW / 2, rectH / 2), new PointF(rectW / 2, rectH / 2), new PointF(rectW / 2, rectH / 8) }; var pen = UnconnectedSocketPen; if (highlight) { g.FillRectangle(CanConnectSocketFeedbackFill, -rectW / 2, -rectH / 2, rectW, rectH); pen = CanConnectSocketFeedbackPen; } else if (socket.IsConnected) { g.FillRectangle(ConnectedSocketFill, -rectW / 2, -rectH / 2, rectW, rectH); pen = ConnectedSocketPen; } g.DrawLines(pen, points); //See save above g.Restore(state); ////For debugging ... //var b = this.AbsoluteBoundingBox; //g.DrawRectangle(new Pen(Color.Blue, 0.01f), (float)b.X, (float)b.Y, (float)b.Width, (float)b.Height); base.OnPaintShape(e); }
// Methods public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape) { base.DoPaint(e, parentShape); Font font = this.GetFont(e.View); string summrytxt = this.GetSummrytxt(parentShape); summrytxt = HttpUtility.HtmlDecode(summrytxt); this.Overrideheight = 0.15f; RectangleF rect = new RectangleF(this.summeryx, this.summeryy, ((float)parentShape.BoundingBox.Width) - (this.summeryx * 2f), this.Overrideheight); LinearGradientBrush brush = new LinearGradientBrush(rect, Color.FromArgb(0xe7, 240, 220), Color.White, 0f); e.Graphics.FillRectangle(brush, rect); e.Graphics.DrawString(summrytxt, font, this.SumerBrush, this.summeryx + 0.05f, this.summeryy); }
/// <summary> /// Paint the composite shape decorators. /// </summary> /// <param name="bounds">Forwarded to composite decorators</param> /// <param name="shape">Forwarded to composite decorators</param> /// <param name="e">Forwarded to composite decorators</param> public override void DoPaintShape(RectangleD bounds, IGeometryHost shape, DiagramPaintEventArgs e) { if (myDecorators == null) { myDecorators = DecoratorCollection; if (myDecorators == null) { myDecorators = new LinkDecorator[] {}; } } for (int i = myDecorators.Count - 1; i >= 0; --i) { myDecorators[i].DoPaintShape(bounds, shape, e); } }
/// <summary> /// Paint the composite shape decorators. /// </summary> /// <param name="bounds">Forwarded to composite decorators</param> /// <param name="shape">Forwarded to composite decorators</param> /// <param name="e">Forwarded to composite decorators</param> public override void DoPaintShape(RectangleD bounds, IGeometryHost shape, DiagramPaintEventArgs e) { if (myDecorators == null) { myDecorators = DecoratorCollection; if (myDecorators == null) { myDecorators = new LinkDecorator[]{}; } } for (int i = myDecorators.Count - 1; i >= 0; --i) { myDecorators[i].DoPaintShape(bounds, shape, e); } }
public override void OnPaintShape(DiagramPaintEventArgs e) { // Have we adjusted the other colors in the shape for this fill color? if (!_isAdjustedForFillColor) { AdjustForFillColor(); } base.OnPaintShape(e); if (e.View != null) { // If the shape is in the EmphasizedShapes list, draw the emphasis shape around the shape. if (Diagram.EmphasizedShapes.Contains(new DiagramItem(this))) { ShapeGeometry.DoPaintEmphasis(e, this); } } }
/// <summary> /// Draw the various constraint types /// </summary> /// <param name="e">DiagramPaintEventArgs</param> public sealed override void OnPaintShape(DiagramPaintEventArgs e) { if (null == Utility.ValidateStore(Store)) { return; } base.OnPaintShape(e); PaintHelper helper = new PaintHelper(e, this); try { OnPaintShape(e, ref helper); } finally { helper.Dispose(); } }
public override void OnPaintShape(DiagramPaintEventArgs e) { // Have we adjusted the other colors in the shape for this fill color? if (!_isAdjustedForFillColor) { AdjustForFillColor(); } base.OnPaintShape(e); // DoPaintEmphasis requires some information from canvas (for example: zoom factor), // so we need to skip drawing shapes' emphasis if they are drawn outside of diagram canvas (for example: in thumbnail view). if (e.View != null) { // If the shape is in the EmphasizedShapes list, draw the emphasis shape around the shape. if (Diagram.EmphasizedShapes.Contains(new DiagramItem(this))) { ShapeGeometry.DoPaintEmphasis(e, this); } } }
public override void OnPaintShape(DiagramPaintEventArgs e) { // Check if we have to override colors. if (!IsColorThemeSet) { SetColorTheme(); } base.OnPaintShape(e); if (e.View != null) { // If the shape is in the EmphasizedShapes list, draw the emphasis shape around the shape. var diagram = Diagram as ConfigurationSectionDesignerDiagram; if (diagram.EmphasizedShapes.Contains(new DiagramItem(this))) { ShapeGeometry.DoPaintEmphasis(e, this); } } }
public override void OnPaintShape(DiagramPaintEventArgs e) { // Check if we have to override colors. if (!IsColorThemeSet) { SetColorTheme(); } base.OnPaintShape(e); // DoPaintEmphasis requires some information from canvas (for example: canvas's zoom factor), // so we need to skip drawing shapes' emphasis if they are drawn outside of diagram canvas (for example: in thumbnail view). if (e.View != null) { // If the shape is in the EmphasizedShapes list, draw the emphasis shape around the shape. var entityDesignerDiagram = Diagram as EntityDesignerDiagram; if (entityDesignerDiagram.EmphasizedShapes.Contains(new DiagramItem(this))) { ShapeGeometry.DoPaintEmphasis(e, this); } } }
// set clip to make sure child shapes will not overlap parent's parent shape public override void OnPaintShape(DiagramPaintEventArgs e) { if (this.ParentShape != null && this.ParentShape.ParentShape != null && !(this.ParentShape.ParentShape is Microsoft.VisualStudio.Modeling.Diagrams.Diagram)) { RectangleD clipRect = this.ParentShape.ParentShape.AbsoluteBoundingBox; clipRect.Inflate(new SizeD(-this.ParentShape.OutlinePenWidth, -this.ParentShape.OutlinePenWidth)); RectangleD thisRect = this.AbsoluteBoundingBox; thisRect.Inflate(new SizeD(this.ParentShape.OutlinePenWidth, this.ParentShape.OutlinePenWidth)); clipRect.Intersect(thisRect); Region clip = e.Graphics.Clip; e.Graphics.SetClip(RectangleD.ToRectangleF(clipRect), CombineMode.Intersect); base.OnPaintShape(e); e.Graphics.Clip = clip; } else base.OnPaintShape(e); }
/// <summary> /// Replacement for BinaryLinkShapeGeometry.DoPaintGeometry /// </summary> protected override void DoPaintGeometry(DiagramPaintEventArgs e, IGeometryHost geometryHost) { LinkShape linkShape; IJumpFreeLinkShape jumpFreeShape; VGObjectLineJumpCode expectedJumpCode; if (null != (jumpFreeShape = geometryHost as IJumpFreeLinkShape) && null != (linkShape = geometryHost as LinkShape) && linkShape.RouteJumpType != (expectedJumpCode = (jumpFreeShape.IsJumpFree ? VGObjectLineJumpCode.VGObjectJumpCodeNever : VGObjectLineJumpCode.VGObjectJumpCodePage))) { // Backup plan, sometimes we can't set this during configuration, and // it tends to revert in undo/redo scenarios when the backing graph // wrapper is not preserved. linkShape.RouteJumpType = expectedJumpCode; } Graphics g = e.Graphics; GraphicsPath path = this.GetPath(geometryHost); StyleSetResourceId penId = GetOutlinePenId(geometryHost); Pen pen = geometryHost.GeometryStyleSet.GetPen(penId); if ((path != null) && (pen != null)) { IDynamicColorGeometryHost dynamicColors = geometryHost as IDynamicColorGeometryHost; if (this.HasOutline(geometryHost)) { Color restoreColor; if (null == (dynamicColors = geometryHost as IDynamicColorGeometryHost) || (restoreColor = dynamicColors.UpdateDynamicColor(penId, pen)).IsEmpty) { restoreColor = geometryHost.UpdateGeometryLuminosity(e.View, pen); } else { geometryHost.UpdateGeometryLuminosity(e.View, pen); } GeometryUtility.SafeDrawPath(g, pen, path); pen.Color = restoreColor; } IBinaryLinkGeometryData hostData; EdgePointCollection edgePoints; int edgePointCount; if (null != (hostData = geometryHost as IBinaryLinkGeometryData) && null != (edgePoints = hostData.GeometryEdgePoints) && 1 < (edgePointCount = edgePoints.Count)) { float rotationAngle = 0f; LinkDecorator decorator; if (null != (decorator = hostData.GeometryDecoratorFrom)) { rotationAngle = CalculateRotationAngle(edgePoints[0].Point, edgePoints[1].Point); DrawDecorator(e, geometryHost, rotationAngle, edgePoints[0].Point, decorator #if VISUALSTUDIO_10_0 , hostData.GeometryDecoratorFromSize #endif ); } if (null != (decorator = hostData.GeometryDecoratorTo)) { rotationAngle = CalculateRotationAngle(edgePoints[edgePointCount - 1].Point, edgePoints[edgePointCount - 2].Point); DrawDecorator(e, geometryHost, rotationAngle, edgePoints[edgePointCount - 1].Point, decorator #if VISUALSTUDIO_10_0 , hostData.GeometryDecoratorToSize #endif ); } } } }
/// <summary> /// Paint the solid crowsfoot on the end of an optional line /// </summary> protected override void DoPaintGeometry(DiagramPaintEventArgs e, IGeometryHost geometryHost) { EntityRelationshipBinaryMultiplicityDisplay displaySetting = OptionsPage.CurrentEntityRelationshipBinaryMultiplicityDisplay; RolePlayerLink connector; EdgePointCollection edgePoints; int edgePointCount; Pen pen; ShapeElement shapeHost; IOffsetBorderPoint offsetPointProvider; if (displaySetting == EntityRelationshipBinaryMultiplicityDisplay.Barker && RoleMultiplicity.ZeroToMany == (connector = (RolePlayerLink)geometryHost).GetDisplayRoleMultiplicity(displaySetting) && null != (edgePoints = connector.EdgePoints) && 1 < (edgePointCount = edgePoints.Count) && null != (shapeHost = connector.ToShape) && null != (offsetPointProvider = shapeHost.ShapeGeometry as IOffsetBorderPoint) && null != (pen = geometryHost.GeometryStyleSet.GetPen(DiagramPens.ConnectionLine))) { Color restoreColor = pen.Color; pen.Color = geometryHost.UpdateGeometryLuminosity(e.View, pen); PointD pointOnBorder = edgePoints[edgePointCount - 1].Point; double angle = GeometryUtility.CalculateRadiansRotationAngle(edgePoints[0].Point, pointOnBorder); PointD vertexPoint = pointOnBorder; vertexPoint.Offset(CrowsFootHeight * Math.Cos(angle), CrowsFootHeight * Math.Sin(angle)); e.Graphics.DrawLine(pen, PointD.ToPointF(vertexPoint), PointD.ToPointF(pointOnBorder)); PointD? offsetBorderPoint = offsetPointProvider.OffsetBorderPoint(shapeHost, pointOnBorder, vertexPoint, CrowsFootHalfWidth, CrowsFootParallelMode); if (offsetBorderPoint.HasValue) { e.Graphics.DrawLine(pen, PointD.ToPointF(vertexPoint), PointD.ToPointF(offsetBorderPoint.Value)); } offsetBorderPoint = offsetPointProvider.OffsetBorderPoint(shapeHost, pointOnBorder, vertexPoint, -CrowsFootHalfWidth, CrowsFootParallelMode); if (offsetBorderPoint.HasValue) { e.Graphics.DrawLine(pen, PointD.ToPointF(vertexPoint), PointD.ToPointF(offsetBorderPoint.Value)); } pen.Color = restoreColor; } base.DoPaintGeometry(e, geometryHost); }
/// <summary> /// Override DoPaintFeedback in order to stop connect line from drawing when mouse /// is over invalid object. We won't do anything. /// </summary> /// <param name="e"></param> public override void DoPaintFeedback(DiagramPaintEventArgs e) { }
/// <summary> /// Draws the shape's shadow. /// </summary> /// <remarks> /// The shadow is replaced with a glow. /// </remarks> protected override void DoPaintShadow(DiagramPaintEventArgs e, IGeometryHost geometryHost) { Guard.NotNull(() => geometryHost, geometryHost); Guard.NotNull(() => e, e); Graphics graphics = e.Graphics; GraphicsState state = graphics.Save(); SizeD shadowOffset = this.ShadowOffset; try { GraphicsPath shapePath = this.GetPath(geometryHost); RectangleF shapeRectangle = shapePath.GetBounds(); // Create shadow path GraphicsPath shadowPath = shapePath.Clone() as GraphicsPath; // Enlarge the shadow (by fixed magnifier amount) using (Matrix scaleMatrix = new Matrix()) { scaleMatrix.Scale( (ShadowMagnifier / shapeRectangle.Width) + 1, (ShadowMagnifier / shapeRectangle.Height) + 1); shadowPath.Transform(scaleMatrix); // Center shadow back on the shape RectangleF shadowRectangle = shadowPath.GetBounds(); scaleMatrix.Reset(); scaleMatrix.Translate( -((shadowRectangle.X + (shadowRectangle.Width / 2)) - (shapeRectangle.X + (shapeRectangle.Width / 2))), -((shadowRectangle.Y + (shadowRectangle.Height / 2)) - (shapeRectangle.Y + (shapeRectangle.Height / 2)))); shadowPath.Transform(scaleMatrix); } // Set the clip region (on the shape) using (Region clip = graphics.Clip) { graphics.SetClip(shapePath); // Offset the shadow path (move diagonally down-right) from shape using (Matrix translateMatrix = new Matrix()) { translateMatrix.Translate((float)shadowOffset.Width, (float)shadowOffset.Height); shadowPath.Transform(translateMatrix); } // Mask-off the shadow from the original shape graphics.SetClip(shadowPath, CombineMode.Complement); graphics.SetClip(clip, CombineMode.Intersect); // Fill the shadow using (PathGradientBrush shadowBrush = new PathGradientBrush(shadowPath)) { shadowBrush.CenterColor = Color.FromArgb(ShadowColorOpacity, ShadowColor); shadowBrush.SurroundColors = new Color[] { Color.Transparent }; shadowBrush.FocusScales = new PointF(ShadowGradientFocalPoint, ShadowGradientFocalPoint); graphics.FillPath(shadowBrush, shadowPath); graphics.ResetClip(); } } } finally { graphics.Restore(state); } }
/// <summary> /// Replacement for BinaryLinkShapeGeometry.DoPaintGeometry /// </summary> protected override void DoPaintGeometry(DiagramPaintEventArgs e, IGeometryHost geometryHost) { LinkShape linkShape = geometryHost as LinkShape; if (linkShape != null && linkShape.RouteJumpType != VGObjectLineJumpCode.VGObjectJumpCodeNever) { // Backup plan, sometimes we can't set this during configuration, and // it tends to revert in undo/redo scenarios when the backing graph // wrapper is not preserved. linkShape.RouteJumpType = VGObjectLineJumpCode.VGObjectJumpCodeNever; } Graphics g = e.Graphics; GraphicsPath path = this.GetPath(geometryHost); StyleSetResourceId penId = GetOutlinePenId(geometryHost); Pen pen = geometryHost.GeometryStyleSet.GetPen(penId); if ((path != null) && (pen != null)) { IDynamicColorGeometryHost dynamicColors = geometryHost as IDynamicColorGeometryHost; if (this.HasOutline(geometryHost)) { Color restoreColor; if (null == (dynamicColors = geometryHost as IDynamicColorGeometryHost) || (restoreColor = dynamicColors.UpdateDynamicColor(penId, pen)).IsEmpty) { restoreColor = geometryHost.UpdateGeometryLuminosity(e.View, pen); } else { geometryHost.UpdateGeometryLuminosity(e.View, pen); } GeometryUtility.SafeDrawPath(g, pen, path); pen.Color = restoreColor; } IBinaryLinkGeometryData hostData; EdgePointCollection edgePoints; int edgePointCount; if (null != (hostData = geometryHost as IBinaryLinkGeometryData) && null != (edgePoints = hostData.GeometryEdgePoints) && 1 < (edgePointCount = edgePoints.Count)) { float rotationAngle = 0f; LinkDecorator decorator; if (null != (decorator = hostData.GeometryDecoratorFrom)) { rotationAngle = CalculateRotationAngle(edgePoints[0].Point, edgePoints[1].Point); DrawDecorator(e, geometryHost, rotationAngle, edgePoints[0].Point, decorator #if VISUALSTUDIO_10_0 , hostData.GeometryDecoratorFromSize #endif ); } if (null != (decorator = hostData.GeometryDecoratorTo)) { rotationAngle = CalculateRotationAngle(edgePoints[edgePointCount - 1].Point, edgePoints[edgePointCount - 2].Point); DrawDecorator(e, geometryHost, rotationAngle, edgePoints[edgePointCount - 1].Point, decorator #if VISUALSTUDIO_10_0 , hostData.GeometryDecoratorToSize #endif ); } } } }
/// <summary> /// Paint the background and outline of a <see cref="IGeometryHost"/> using /// dynamic colors provided by the <see cref="IDynamicColorGeometryHost"/> interface. /// This is a helper method designed to be called by an override of the <see cref="NodeShapeGeometry.DoPaintGeometry"/> method. /// </summary> /// <param name="e">The <see cref="DiagramPaintEventArgs"/> passed to DoPaintGeometry</param> /// <param name="geometryHost">The <see cref="IGeometryHost"/> passed to DoPaintGeometry</param> /// <param name="dynamicColors">The <see cref="IDynamicColorGeometryHost"/> retrieved from the <paramref name="geometryHost"/></param> /// <param name="shapeGeometry">The <see cref="ShapeGeometry"/> this is a helper for.</param> /// <param name="hasFilledBackground">The result of the <see cref="ShapeGeometry.HasFilledBackground"/> method</param> /// <param name="hasOutline">The result of the <see cref="ShapeGeometry.HasOutline"/> method</param> /// <remarks> /// The DoPaintGeometry override should look similar to /// <code> /// protected override void DoPaintGeometry(DiagramPaintEventArgs e, IGeometryHost geometryHost) /// { /// IDynamicColorGeometryHost dynamicColors = geometryHost as IDynamicColorGeometryHost; /// if (dynamicColors != null) /// { /// GeometryUtility.PaintDynamicColorGeometry(e, geometryHost, dynamicColors, this, this.HasFilledBackground(geometryHost), this.HasOutline(geometryHost)); /// } /// else /// { /// base.DoPaintGeometry(e, geometryHost); /// } /// } /// </code> /// </remarks> public static void PaintDynamicColorGeometry(DiagramPaintEventArgs e, IGeometryHost geometryHost, IDynamicColorGeometryHost dynamicColors, ShapeGeometry shapeGeometry, bool hasFilledBackground, bool hasOutline) { if (hasFilledBackground || hasOutline) { StyleSet geometryStyleSet = geometryHost.GeometryStyleSet; GraphicsPath path; StyleSetResourceId penId = null; Pen pen = null; StyleSetResourceId brushId = null; Brush brush = null; if (null != (path = shapeGeometry.GetPath(geometryHost)) && (!hasFilledBackground || null != (brush = geometryStyleSet.GetBrush(brushId = shapeGeometry.GetBackgroundBrushId(geometryHost)))) && (!hasOutline || null != (pen = geometryStyleSet.GetPen(penId = shapeGeometry.GetOutlinePenId(geometryHost))))) { Graphics g = e.Graphics; DiagramClientView clientView = e.View; Color restoreColor; if (brush != null) { restoreColor = Color.Empty; if (dynamicColors == null || (restoreColor = dynamicColors.UpdateDynamicColor(brushId, brush)).IsEmpty) { if (clientView != null) { restoreColor = geometryHost.UpdateGeometryLuminosity(clientView, brush); } } else if (clientView != null) { geometryHost.UpdateGeometryLuminosity(clientView, brush); } g.FillPath(brush, path); SolidBrush solidBrush = brush as SolidBrush; if (!restoreColor.IsEmpty && null != (solidBrush = brush as SolidBrush)) { solidBrush.Color = restoreColor; } } if (pen != null) { restoreColor = Color.Empty; if (dynamicColors == null || (restoreColor = dynamicColors.UpdateDynamicColor(penId, pen)).IsEmpty) { if (clientView != null) { restoreColor = geometryHost.UpdateGeometryLuminosity(clientView, pen); } } else if (clientView != null) { geometryHost.UpdateGeometryLuminosity(clientView, pen); } SafeDrawPath(g, pen, path); if (!restoreColor.IsEmpty) { pen.Color = restoreColor; } } } } }
/// <summary> /// Paint the solid crowsfoot on the end of an optional line /// </summary> protected override void DoPaintGeometry(DiagramPaintEventArgs e, IGeometryHost geometryHost) { AssociationConnector connector = (AssociationConnector)geometryHost; BarkerErModelContainsBinaryAssociation link = connector.ModelElement as BarkerErModelContainsBinaryAssociation; EdgePointCollection edgePoints; int edgePointCount; BinaryAssociation association; LinkedElementCollection <Barker.Role> roles; if (null != (edgePoints = connector.EdgePoints) && 1 < (edgePointCount = edgePoints.Count) && null != (association = link.BinaryAssociation) && 2 == (roles = association.RoleCollection).Count) { PointD p1 = edgePoints[edgePointCount - 1].Point; PointD p2 = edgePoints[0].Point; PointD midP = new PointD((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2); #region find correct roles EntityType fromEntity = connector.FromShape.ModelElement as EntityType; EntityType toEntity = connector.ToShape.ModelElement as EntityType; Barker.Role fromRole = null, toRole = null; if (fromEntity == roles[0].EntityType) { fromRole = roles[0]; } else if (fromEntity == roles[1].EntityType) { fromRole = roles[1]; } if (toEntity == roles[0].EntityType) { toRole = roles[0]; } else if (toEntity == roles[1].EntityType) { toRole = roles[1]; } #endregion if (fromRole != null && toRole != null) { bool fromOptional = !fromRole.IsMandatory; bool toOptional = !toRole.IsMandatory; bool bothOptional = fromOptional && toOptional; PointF?v1 = null, v2 = null; DrawAssociationEnd( e, geometryHost, connector.FromShape, p2, midP, fromRole.IsMultiValued, fromOptional, fromRole.IsPrimaryIdComponent, fromRole.PredicateText, ref v1, bothOptional); DrawAssociationEnd( e, geometryHost, connector.ToShape, p1, midP, toRole.IsMultiValued, toOptional, toRole.IsPrimaryIdComponent, toRole.PredicateText, ref v2, bothOptional); if (bothOptional && v1.HasValue && v2.HasValue) { Pen pen = geometryHost.GeometryStyleSet.GetPen(DiagramPens.ConnectionLine); pen = (Pen)pen.Clone(); pen.DashPattern = DashPattern; e.Graphics.DrawLine(pen, v1.Value, v2.Value); } } } }
// Methods public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape) { base.DoPaint(e, parentShape); Font font = this.GetFont(e.View); CDCompartment compartment = parentShape as CDCompartment; if (compartment != null) { ListField listField = null; foreach (ShapeField field2 in compartment.ShapeFields) { if (field2 is ListField) { listField = field2 as ListField; break; } } float MemberLineHeight = (float)listField.GetItemHeight(parentShape); float MemberStartMargin = 0f; float stringMargin = 0.02f; if (listField != null) { int itemCount = compartment.GetItemCount(listField); for (int i = 0; i < itemCount; i++) { ItemDrawInfo itemDrawInfo = new ItemDrawInfo(); MemberStartMargin = (float)listField.GetItemRectangle(parentShape, i, 0).Y; compartment.GetItemDrawInfo(listField, i, itemDrawInfo); if (itemDrawInfo.Disabled) { continue; } string[] strArray = itemDrawInfo.Text.Split(new char[] { ':', '(', '{', '<' }); Member menberByName = this.GetMenberByName(parentShape.ParentShape, strArray[0].Trim()); if ((menberByName == null)) { continue; } string docSummary = menberByName.DocSummary; string genericTypeName = ""; genericTypeName = menberByName.MemberTypeShortName; BackBrush.Color = Color.White; VarBrush.Color = Color.Blue; ModifierBrush.Color = Color.Blue; NameBrush.Color = Color.Black; SummaryBrush.Color = Color.Green; SelectedShapesCollection seleShapes = this._FromAddin.SelectedShapes; if (seleShapes != null) { foreach (DiagramItem item in seleShapes) { if (((item.Shape == compartment) && (item.Field == listField)) && (item.SubField.SubFieldHashCode == i)) { this.BackBrush.Color = SystemColors.Highlight; VarBrush.Color = Color.White; NameBrush.Color = Color.White; SummaryBrush.Color = Color.White; ModifierBrush.Color = Color.White; break; } } } float recX = (float)itemDrawInfo.ImageMargin;//0.16435f RectangleD bound = parentShape.BoundingBox; float width = (float)bound.Width; //float MemberStartMargin = 0.26f; e.Graphics.FillRectangle(this.BackBrush, VSConfigManager.CurConfig.MemberMarginX, MemberStartMargin, width, MemberLineHeight); float curX = VSConfigManager.CurConfig.MemberMarginX; string memberTypeName = menberByName.MemberTypeName.TrimEnd('?', '[', ']'); if (BackBrush.Color == Color.White)//非选中状态 { if ((memberTypeName != "void") && (menberByName.MemberTypeLookupName == memberTypeName)) { VarBrush.Color = Color.DodgerBlue; } //if (!menberByName.IsSpecialName) //{ // VarBrush.Color = Color.DodgerBlue; //} } string curStr = null; if (EnumUnit.ContainerValue((int)_summaryShowInfo, (int)SummaryShowItem.TypeName)) { if (menberByName.IsStatic) { curStr = "static"; e.Graphics.DrawString(curStr, font, ModifierBrush, curX, MemberStartMargin + stringMargin); curX += e.Graphics.MeasureString(curStr, font).Width; } curStr = genericTypeName + " "; e.Graphics.DrawString(curStr, font, this.VarBrush, curX, MemberStartMargin + stringMargin); curX += e.Graphics.MeasureString(curStr, font).Width; } if (EnumUnit.ContainerValue((int)_summaryShowInfo, (int)SummaryShowItem.MemberName)) { curStr = menberByName.Name; if (menberByName is ClrMethod) { curStr += "()"; } e.Graphics.DrawString(curStr, font, this.NameBrush, curX, MemberStartMargin + stringMargin); curX += e.Graphics.MeasureString(curStr, font).Width; } if (EnumUnit.ContainerValue((int)_summaryShowInfo, (int)SummaryShowItem.Summary)) { if (!string.IsNullOrEmpty(curStr)) { curStr = ":"; } else { curStr = ""; } curStr += HttpUtility.HtmlDecode(docSummary); e.Graphics.DrawString(curStr, font, this.SummaryBrush, curX, MemberStartMargin + stringMargin); } } } } }
/// <summary> /// Copy of <see cref="TextField.DoPaint"/> modified to support the /// <see cref="IDynamicColorGeometryHost"/> on the parent shape. /// </summary> public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape) { DiagramClientView clientView = e.View; if (!HasPendingEdit(parentShape, clientView)) { if (GetVisible(parentShape)) { string text = GetDisplayText(parentShape); StyleSet styleSet = parentShape.StyleSet; Graphics g = e.Graphics; RectangleF clip = g.ClipBounds; clip.Inflate(InflateFocus, InflateFocus); clip.Height -= InflateFocus; g.SetClip(clip); RectangleD shapeBounds = GetBounds(parentShape); RectangleF shapeRect = RectangleD.ToRectangleF(shapeBounds); Matrix startTransform = null; if (!DefaultIsHorizontal) { PointF point = PointD.ToPointF(shapeBounds.Center); startTransform = g.Transform; Matrix verticalTransform = g.Transform; verticalTransform.RotateAt(-90f, point); verticalTransform.Translate(0f, (-point.X / 2f) - shapeRect.X); g.Transform = verticalTransform; } if (parentShape.ClipWhenDrawingFields) { RectangleD parentBounds = parentShape.BoundingBox; shapeRect.Intersect(new RectangleF(0f, 0f, (float)parentBounds.Width, (float)parentBounds.Height)); } if (FillBackground) { Color startColor = Color.White; Brush brush = GetBackgroundBrush(clientView, parentShape, ref startColor); g.FillRectangle(brush, shapeRect); SolidBrush solidBrush = brush as SolidBrush; if (solidBrush != null) { solidBrush.Color = startColor; } } if (DrawBorder) { Color oldColor = Color.White; Pen pen = GetPen(clientView, parentShape, ref oldColor); GeometryUtility.SafeDrawRectangle(g, pen, shapeRect.X, shapeRect.Y, shapeRect.Width, shapeRect.Height); pen.Color = oldColor; } if (text.Length > 0x0) { using (Font font = GetFont(parentShape)) { // Note that this ignores the base GetTextBrush, which is trivial // and has no overrides. Note that we follow the convention used with // the base and do not update luminosity on the text. StyleSetResourceId textBrushId = GetTextBrushId(clientView, parentShape); Brush textBrush = styleSet.GetBrush(textBrushId); Color restoreTextColor = Color.Empty; IDynamicColorGeometryHost dynamicColors = parentShape as IDynamicColorGeometryHost; if (dynamicColors != null) { restoreTextColor = dynamicColors.UpdateDynamicColor(textBrushId, textBrush); } g.DrawString(text, font, textBrush, shapeRect, GetStringFormat(parentShape)); SolidBrush solidTextBrush; if (!restoreTextColor.IsEmpty && null != (solidTextBrush = textBrush as SolidBrush)) { solidTextBrush.Color = restoreTextColor; } } } if (HasFocusedAppearance(parentShape, clientView)) { // Note that the base makes a copy of shapeRect and // assymetrically modifies the focus rectangle. I don't // think this adds anything and gives focus floating shapes a // focus rectangle that arbitrarily overlaps nearby shapes. //RectangleF focusRect = shapeRect; //focusRect.Inflate(0f, InflateFocus); //focusRect.Height -= InflateFocus; //GeometryUtility.SafeDrawRectangle(g, styleSet.GetPen(DiagramPens.FocusIndicatorBackground), focusRect.X, focusRect.Y, focusRect.Width, focusRect.Height); //GeometryUtility.SafeDrawRectangle(g, styleSet.GetPen(DiagramPens.FocusIndicator), focusRect.X, focusRect.Y, focusRect.Width, focusRect.Height); // UNDONE: The bottom line is drawing clipped. The original code has the same problem // with both the top and bottom lines. This appears to be an issue with the Center // alignment on the default focus indicator pens. shapeRect.Inflate(0f, TextFocusTopPadding); shapeRect.Height -= TextFocusTopPadding - TextFocusBottomPadding; GeometryUtility.SafeDrawRectangle(g, styleSet.GetPen(DiagramPens.FocusIndicatorBackground), shapeRect.X, shapeRect.Y, shapeRect.Width, shapeRect.Height); GeometryUtility.SafeDrawRectangle(g, styleSet.GetPen(DiagramPens.FocusIndicator), shapeRect.X, shapeRect.Y, shapeRect.Width, shapeRect.Height); } if (startTransform != null) { g.Transform = startTransform; } } } }
/// <summary> /// Draw all ring constraint types /// </summary> protected override void OnPaintShape(DiagramPaintEventArgs e, ref PaintHelper helper) { base.OnPaintShape(e, ref helper); RingConstraint ringConstraint = this.AssociatedRingConstraint; RectangleF boundsF = RectangleD.ToRectangleF(this.AbsoluteBounds); Graphics g = e.Graphics; RingConstraintType ringType = ringConstraint.RingType; RectangleF innerBounds; Pen pen = helper.Pen; Brush brush = helper.Brush; switch (ringType) { case RingConstraintType.Undefined: break; case RingConstraintType.Reflexive: DrawLeftDot(g, boundsF, brush); break; case RingConstraintType.PurelyReflexive: DrawLeftDot(g, boundsF, brush); { float height = boundsF.Height; float left = boundsF.Left + boundsF.Width / 2; DashStyle originalDashStyle = pen.DashStyle; pen.DashStyle = DashStyle.Solid; g.DrawLine(pen, left, boundsF.Top + height * (.5f - SMALL_LENGTH_FACTOR / 2), left, boundsF.Top + height * (.5f + SMALL_LENGTH_FACTOR / 2)); pen.DashStyle = originalDashStyle; } break; case RingConstraintType.Irreflexive: DrawLeftDot(g, boundsF, brush); DrawRightLine(g, boundsF, pen, 1f); break; case RingConstraintType.Asymmetric: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, true); DrawBottomLine(g, boundsF, pen); break; case RingConstraintType.Antisymmetric: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, false); DrawBottomLine(g, boundsF, pen); break; case RingConstraintType.Transitive: DrawTriangleDots(g, boundsF, brush, false); break; case RingConstraintType.Intransitive: case RingConstraintType.StronglyIntransitive: DrawTriangleDots(g, boundsF, brush, ringType == RingConstraintType.StronglyIntransitive); DrawTriangleBottomLine(g, boundsF, pen); break; case RingConstraintType.Acyclic: DrawTriangleDots(g, boundsF, brush, false); DrawBottomLine(g, boundsF, pen); break; case RingConstraintType.AcyclicTransitive: DrawTriangle(g, boundsF, pen); DrawTriangleDots(g, boundsF, brush, false); DrawBottomLine(g, boundsF, pen, .6f); break; case RingConstraintType.AcyclicIntransitive: case RingConstraintType.AcyclicStronglyIntransitive: DrawTriangle(g, boundsF, pen); DrawTriangleBottomLine(g, boundsF, pen); DrawTriangleDots(g, boundsF, brush, ringType == RingConstraintType.AcyclicStronglyIntransitive); DrawBottomLine(g, boundsF, pen); break; case RingConstraintType.TransitiveAsymmetric: case RingConstraintType.TransitiveAntisymmetric: case RingConstraintType.AsymmetricIntransitive: case RingConstraintType.AsymmetricStronglyIntransitive: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, ringType != RingConstraintType.TransitiveAntisymmetric); DrawBottomLine(g, boundsF, pen); innerBounds = GetInnerBounds(boundsF); DrawTriangle(g, innerBounds, pen); DrawTriangleDots(g, innerBounds, brush, ringType == RingConstraintType.AsymmetricStronglyIntransitive); switch (ringType) { case RingConstraintType.AsymmetricIntransitive: case RingConstraintType.AsymmetricStronglyIntransitive: DrawTriangleBottomLine(g, innerBounds, pen); break; } break; case RingConstraintType.ReflexiveTransitive: case RingConstraintType.TransitiveIrreflexive: DrawLeftDot(g, boundsF, brush); if (ringType == RingConstraintType.TransitiveIrreflexive) { DrawRightLine(g, boundsF, pen, .75f); } innerBounds = GetInnerBounds(boundsF); DrawTriangle(g, innerBounds, pen); DrawTriangleDots(g, innerBounds, brush, false); break; case RingConstraintType.Symmetric: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, true); break; case RingConstraintType.SymmetricTransitive: case RingConstraintType.SymmetricIntransitive: case RingConstraintType.SymmetricStronglyIntransitive: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, true); innerBounds = GetInnerBounds(boundsF); DrawTriangle(g, innerBounds, pen); DrawTriangleDots(g, innerBounds, brush, ringType == RingConstraintType.SymmetricStronglyIntransitive); if (ringType != RingConstraintType.SymmetricTransitive) { DrawTriangleBottomLine(g, innerBounds, pen); } break; case RingConstraintType.SymmetricIrreflexive: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, true); innerBounds = GetReflexiveInSymmetricBounds(boundsF); DrawEllipse(g, innerBounds, pen); DrawRightLine(g, innerBounds, pen, 1f); break; case RingConstraintType.ReflexiveSymmetric: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, true); DrawEllipse(g, GetReflexiveInSymmetricBounds(boundsF), pen); break; case RingConstraintType.ReflexiveAntisymmetric: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, false); DrawEllipse(g, GetReflexiveInSymmetricBounds(boundsF), pen); DrawBottomLine(g, boundsF, pen); break; case RingConstraintType.ReflexiveTransitiveAntisymmetric: DrawLeftDot(g, boundsF, brush); DrawRightDot(g, boundsF, pen, brush, false); DrawBottomLine(g, boundsF, pen); innerBounds = GetInnerBounds(boundsF); DrawTriangle(g, innerBounds, pen); DrawTriangleDots(g, innerBounds, brush, false); g.DrawArc(pen, GetReflexiveInSymmetricBounds(boundsF), 27, 300); // Angles determined empirically to stop on triangle, not worth calculating break; } }
// Methods public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape) { base.DoPaint(e, parentShape); Font font = this.GetFont(e.View); CDCompartment compartment = parentShape as CDCompartment; if (compartment != null) { ListField listField = null; foreach (ShapeField field2 in compartment.ShapeFields) { if (field2 is ListField) { listField = field2 as ListField; break; } } float MemberLineHeight = (float)listField.GetItemHeight(parentShape); if (listField != null) { int itemCount = compartment.GetItemCount(listField); for (int i = 0; i < itemCount; i++) { ItemDrawInfo itemDrawInfo = new ItemDrawInfo(); compartment.GetItemDrawInfo(listField, i, itemDrawInfo); if (!itemDrawInfo.Disabled) { string[] strArray = itemDrawInfo.Text.Split(new char[] { ':', '(', '{' }); Member menberByName = this.GetMenberByName(parentShape.ParentShape, strArray[0].Trim()); if ((menberByName != null)) { string docSummary = menberByName.DocSummary; this.BackBrush.Color = Color.White; this.SummaryBrush.Color = Color.Green; this.NameBrush.Color = Color.Black; SelectedShapesCollection seleShapes = this._FromAddin.SelectedShapes; if (seleShapes != null) { foreach (DiagramItem item in seleShapes) { if (((item.Shape == compartment) && (item.Field == listField)) && (item.SubField.SubFieldHashCode == i)) { this.BackBrush.Color = SystemColors.Highlight; this.SummaryBrush.Color = Color.White; this.NameBrush.Color = Color.White; break; } } } float height = 0.19f; float recX = (float)itemDrawInfo.ImageMargin;//0.16435f RectangleD bound = parentShape.BoundingBox; float width = (float)bound.Width; e.Graphics.FillRectangle(this.BackBrush, 0f, (0f + MemberLineHeight * (float)i), width, MemberLineHeight); DBConfigInfo dbInfo = DBConfigInfo.LoadInfo(_FromAddin.GetDesignerInfo()); string curStr = null; float curX = 0f; if (EnumUnit.ContainerValue((int)_summaryShowInfo, (int)SummaryShowItem.MemberName)) { curStr = menberByName.Name; e.Graphics.DrawString(curStr, font, this.NameBrush, curX, (0f + MemberLineHeight * (float)i + 0.02f)); curX += e.Graphics.MeasureString(curStr, font).Width; } if (EnumUnit.ContainerValue((int)_summaryShowInfo, (int)SummaryShowItem.Summary)) { if (!string.IsNullOrEmpty(curStr)) { curStr = ":"; } else { curStr = ""; } curStr += HttpUtility.HtmlDecode(menberByName.DocSummary); e.Graphics.DrawString(curStr, font, this.SummaryBrush, curX, (0f + MemberLineHeight * (float)i + 0.02f)); } } } } } } }
/// <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; 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. break; #endregion #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 (constraint.Modality == ConstraintModality.Deontic && constraint.ConstraintType != ConstraintType.Ring) { 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; } }
/// <summary> /// Replacement for LinkShapeGeometry.DrawDecorator /// </summary> #if VISUALSTUDIO_10_0 protected static new void DrawDecorator(DiagramPaintEventArgs e, IGeometryHost geometryHost, float rotation, PointD centerRight, LinkDecorator decorator, SizeD size) {
private static void DrawAssociationEnd( DiagramPaintEventArgs e, IGeometryHost geometryHost, NodeShape node, PointD pointOnBorder, PointD endPoint, bool many, bool optional, bool id, string predicateText, ref PointF?lineEnd, bool bothOptional) { Pen pen; ShapeElement shapeHost; IOffsetBorderPoint offsetPointProvider; Font font; Brush brush; Graphics g = e.Graphics; if (null != (shapeHost = node) && null != (offsetPointProvider = shapeHost.ShapeGeometry as IOffsetBorderPoint) && null != (pen = geometryHost.GeometryStyleSet.GetPen(DiagramPens.ConnectionLine)) && null != (font = geometryHost.GeometryStyleSet.GetFont(DiagramFonts.ConnectionLine)) && null != (brush = geometryHost.GeometryStyleSet.GetBrush(DiagramBrushes.ConnectionLineText))) { Color restoreColor = pen.Color; pen.Color = geometryHost.UpdateGeometryLuminosity(e.View, pen); double angle = GeometryUtility.CalculateRadiansRotationAngle(endPoint, pointOnBorder); PointD vertexPoint = pointOnBorder; vertexPoint.Offset(CrowsFootHeight * Math.Cos(angle), CrowsFootHeight * Math.Sin(angle)); #region draw the main line Pen mainLinePen = (Pen)pen.Clone(); if (optional) { mainLinePen.DashPattern = DashPattern; mainLinePen.DashOffset = DashPattern[0]; } if (many & optional) { if (!bothOptional) { g.DrawLine(mainLinePen, PointD.ToPointF(endPoint), PointD.ToPointF(vertexPoint)); } else { lineEnd = PointD.ToPointF(vertexPoint); } g.DrawLine(pen, PointD.ToPointF(vertexPoint), PointD.ToPointF(pointOnBorder)); } else { if (!bothOptional) { g.DrawLine(mainLinePen, PointD.ToPointF(endPoint), PointD.ToPointF(pointOnBorder)); } else { lineEnd = PointD.ToPointF(pointOnBorder); } } #endregion #region draw crow's foot if necessary if (many) { PointD?offsetBorderPoint = offsetPointProvider.OffsetBorderPoint(shapeHost, pointOnBorder, vertexPoint, CrowsFootHalfWidth, CrowsFootParallelMode); if (offsetBorderPoint.HasValue) { g.DrawLine(pen, PointD.ToPointF(vertexPoint), PointD.ToPointF(offsetBorderPoint.Value)); } offsetBorderPoint = offsetPointProvider.OffsetBorderPoint(shapeHost, pointOnBorder, vertexPoint, -CrowsFootHalfWidth, CrowsFootParallelMode); if (offsetBorderPoint.HasValue) { g.DrawLine(pen, PointD.ToPointF(vertexPoint), PointD.ToPointF(offsetBorderPoint.Value)); } } #endregion #region draw tick mark if necessary if (id) { PointD oneMarkLeft = vertexPoint; double cosAngle = Math.Cos(angle); double sinAngle = Math.Sin(angle); oneMarkLeft.Offset(InfEngInnerOneMarkOffset * cosAngle, InfEngInnerOneMarkOffset * sinAngle); PointD oneMarkRight = oneMarkLeft; oneMarkLeft.Offset(-InfEngMarkerHalfWidth * sinAngle, InfEngMarkerHalfWidth * cosAngle); oneMarkRight.Offset(InfEngMarkerHalfWidth * sinAngle, -InfEngMarkerHalfWidth * cosAngle); g.DrawLine(pen, PointD.ToPointF(oneMarkLeft), PointD.ToPointF(oneMarkRight)); } #endregion #region draw text //determine the line's properties double edgeX = pointOnBorder.X; double edgeY = pointOnBorder.Y; EntitySideType whichSideShapeIsOn = EntitySide.FindWhichSide(pointOnBorder, shapeHost.GeometryBoundingBox); double w = 0; //, y = 0; angle = Math.Atan2(Math.Abs(endPoint.Y - edgeY), Math.Abs(endPoint.X - edgeX)); double inDegrees = angle * 180 / Math.PI; if (inDegrees < 0) { inDegrees += 360; } SizeF textSize = g.MeasureString(predicateText, font); w = textSize.Width; //y = Math.Abs(w * Math.Tan(angle)); //determine what to offset double textX = edgeX; double textY = edgeY; double h = textSize.Height; bool lessThan45 = inDegrees < 45; switch (whichSideShapeIsOn) { case EntitySideType.OnBottom: textY -= TextPaddingY + h; if (lessThan45) { textX += TextPaddingX; } else { textX -= TextPaddingX + w; } break; case EntitySideType.OnTop: textY += TextPaddingY; if (lessThan45) { textX -= TextPaddingX + w; } else { textX += TextPaddingX; } break; case EntitySideType.OnLeft: textX += TextPaddingX; if (lessThan45) { textY -= TextPaddingY + h; } else { textY += TextPaddingY; } break; case EntitySideType.OnRight: textX -= TextPaddingX + w; if (lessThan45) { textY += TextPaddingY; } else { textY -= TextPaddingY + h; } break; } //perform the drawing g.DrawString(predicateText, font, brush, new PointF((float)textX, (float)textY)); #endregion pen.Color = restoreColor; } }
public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape) { if (this.HasPendingEdit(parentShape, e.View)) return; if (!this.GetVisible(parentShape)) return; float magicNum = 0.04166667f; RectangleF clipBounds = e.Graphics.ClipBounds; clipBounds.Inflate(magicNum, magicNum); clipBounds.Height -= magicNum; e.Graphics.SetClip(clipBounds); RectangleD fieldBounds = this.GetBounds(parentShape); RectangleF fieldRect = RectangleD.ToRectangleF(fieldBounds); // drawing vertically Matrix prevTransform = null; if (!this.DefaultIsHorizontal) { PointF point = PointD.ToPointF(fieldBounds.Center); prevTransform = e.Graphics.Transform; Matrix matrix = e.Graphics.Transform; matrix.RotateAt(-90f, point); matrix.Translate(0f, (-point.X / 2f) - fieldRect.X); e.Graphics.Transform = matrix; } // clip the field bound if (parentShape.ClipWhenDrawingFields) { RectangleD boundingBox = parentShape.BoundingBox; fieldRect.Intersect(new RectangleF(0f, 0f, (float)boundingBox.Width, (float)boundingBox.Height)); } // fill background if (this.FillBackground) { Color oldColor = Color.White; Brush brush = this.GetBackgroundBrush(e.View, parentShape, ref oldColor); e.Graphics.FillRectangle(brush, fieldRect); // restore old color SolidBrush brush2 = brush as SolidBrush; if (brush2 != null) { brush2.Color = oldColor; } } // border if (this.DrawBorder) { Color oldColor = Color.White; Pen pen = this.GetPen(e.View, parentShape, ref oldColor); DrawHelper.SafeDrawRectangle(e.Graphics, pen, fieldRect.X, fieldRect.Y, fieldRect.Width, fieldRect.Height); pen.Color = oldColor; } // display text string displayText = this.GetDisplayText(parentShape); if (displayText.Length > 0) { using (Font font = this.GetFont(parentShape)) { // line number int linecount = 1; linecount = displayText.Split('\r').Length; StringBuilder lineNums = new StringBuilder(); for (int i = 1; i <= linecount; i++) lineNums.Append(i).Append(Environment.NewLine); SizeF lineNumSize = DiagramRenderTextHelper.Measure(e.Graphics, linecount.ToString(), font); lineNumSize.Width += magicNum; RectangleF lineNumRect = new RectangleF(fieldRect.X, fieldRect.Y, lineNumSize.Width, fieldRect.Height); RectangleF dispTxtRect = new RectangleF(lineNumRect.Right, fieldRect.Y, fieldRect.Width - lineNumSize.Width, fieldRect.Height); using (Brush brush = new SolidBrush(Color.LightSeaGreen)) { // draw line numbers DiagramRenderTextHelper.Render(e, lineNums.ToString(), font, brush, lineNumRect, this.GetStringFormat(parentShape)); } // draw display text DiagramRenderTextHelper.Render(e, displayText, font, this.GetTextBrush(e.View, parentShape), dispTxtRect, this.GetStringFormat(parentShape)); } } // draw focus if (base.HasFocusedAppearance(parentShape, e.View)) { RectangleF focusRect = fieldRect; //focusRect.Inflate(0f, magicNum); //focusRect.Height -= magicNum; Pen pen = parentShape.StyleSet.GetPen(DiagramPens.FocusIndicator); Pen bkgPen = parentShape.StyleSet.GetPen(DiagramPens.FocusIndicatorBackground); DrawHelper.SafeDrawRectangle(e.Graphics, bkgPen, focusRect.X, focusRect.Y, focusRect.Width, focusRect.Height); DrawHelper.SafeDrawRectangle(e.Graphics, pen, focusRect.X, focusRect.Y, focusRect.Width, focusRect.Height); } // restore the transform matrix if (prevTransform != null) { e.Graphics.Transform = prevTransform; } }
public override void DrawResizeFeedback(DiagramPaintEventArgs e, RectangleD bounds) { base.DrawResizeFeedback(e, bounds); }
/// <summary> /// Replacement for <see cref="NodeShapeGeometry.DoPaintGeometry"/> that supports /// dynamic background and outline colors. /// </summary> protected override void DoPaintGeometry(DiagramPaintEventArgs e, IGeometryHost geometryHost) { IDynamicColorGeometryHost dynamicColors = geometryHost as IDynamicColorGeometryHost; if (dynamicColors != null) { GeometryUtility.PaintDynamicColorGeometry(e, geometryHost, dynamicColors, this, this.HasFilledBackground(geometryHost), this.HasOutline(geometryHost)); } else { base.DoPaintGeometry(e, geometryHost); } }
/// <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; } }
/// <summary> /// Reimplementation of <see cref="LinkDecorator.DoPaintShape"/> that /// recognizes <see cref="IDynamicColorGeometryHost"/> /// </summary> public override void DoPaintShape(RectangleD bounds, IGeometryHost shape, DiagramPaintEventArgs e) { StyleSet styleSet = shape.GeometryStyleSet; GraphicsPath decoratorPath = GetPath(bounds); StyleSetResourceId penId = PenId; Pen pen = styleSet.GetPen(penId); StyleSetResourceId brushId = BrushId; Brush brush = styleSet.GetBrush(brushId); if (((decoratorPath != null) && (pen != null)) && (brush != null)) { DiagramClientView clientView = e.View; IDynamicColorGeometryHost dynamicColors = shape as IDynamicColorGeometryHost; Graphics g = e.Graphics; Color restoreColor; if (FillDecorator) { restoreColor = Color.Empty; if (dynamicColors == null || (restoreColor = dynamicColors.UpdateDynamicColor(brushId, brush)).IsEmpty) { if (clientView != null) { restoreColor = shape.UpdateGeometryLuminosity(clientView, brush); } } else if (clientView != null) { shape.UpdateGeometryLuminosity(clientView, brush); } g.FillPath(brush, decoratorPath); SolidBrush solidBrush; if (!restoreColor.IsEmpty && null != (solidBrush = brush as SolidBrush)) { solidBrush.Color = restoreColor; } } restoreColor = Color.Empty; if (dynamicColors == null || (restoreColor = dynamicColors.UpdateDynamicColor(penId, pen)).IsEmpty) { if (clientView != null) { restoreColor = shape.UpdateGeometryLuminosity(clientView, pen); } } else if (clientView != null) { shape.UpdateGeometryLuminosity(clientView, pen); } GeometryUtility.SafeDrawPath(e.Graphics, pen, decoratorPath); if (!restoreColor.IsEmpty) { pen.Color = restoreColor; } } }
/// <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; } } }