//************************************************************************* // Method: DrawSimpleShape() // /// <summary> /// Draws a vertex as a simple shape. /// </summary> /// /// <param name="oVertex"> /// The vertex to draw. /// </param> /// /// <param name="eShape"> /// The vertex shape to use. Can't be <see cref="VertexShape.Image" /> or /// <see cref="VertexShape.Label" />. /// </param> /// /// <param name="oGraphDrawingContext"> /// Provides access to objects needed for graph-drawing operations. /// </param> /// /// <param name="oDrawingContext"> /// The DrawingContext to use. /// </param> /// /// <param name="oDrawingVisual"> /// The <see cref="DrawingVisual" /> object from which <paramref /// name="oDrawingContext" /> was obtained. /// </param> /// /// <param name="eVisibility"> /// The visibility of the vertex. /// </param> /// /// <param name="bDrawAsSelected"> /// true to draw the vertex as selected. /// </param> /// /// <param name="sAnnotation"> /// The annotation to draw next to the shape, or null if there is no /// annotation. /// </param> /// /// <param name="oVertexLabelDrawer"> /// Object that draws a vertex label as an annotation. /// </param> /// /// <returns> /// A VertexDrawingHistory object that retains information about how the /// vertex was drawn. /// </returns> /// /// <remarks> /// "Simple" means "not <see cref="VertexShape.Image" /> and not <see /// cref="VertexShape.Label" />." /// </remarks> //************************************************************************* protected VertexDrawingHistory DrawSimpleShape( IVertex oVertex, VertexShape eShape, GraphDrawingContext oGraphDrawingContext, DrawingContext oDrawingContext, DrawingVisual oDrawingVisual, VisibilityKeyValue eVisibility, Boolean bDrawAsSelected, String sAnnotation, VertexLabelDrawer oVertexLabelDrawer ) { Debug.Assert(oVertex != null); Debug.Assert(oGraphDrawingContext != null); Debug.Assert(oDrawingContext != null); Debug.Assert(oDrawingVisual != null); Debug.Assert(oVertexLabelDrawer != null); AssertValid(); Double dRadius = GetRadius(oVertex); Color oColor = GetColor(oVertex, eVisibility, bDrawAsSelected); Point oVertexLocation = GetVertexLocation(oVertex); Rect oVertexBounds; if (eShape == VertexShape.Triangle || eShape == VertexShape.SolidTriangle) { oVertexBounds = WpfGraphicsUtil.TriangleBoundsFromCenterAndHalfWidth( oVertexLocation, dRadius); } else { oVertexBounds = WpfGraphicsUtil.SquareFromCenterAndHalfWidth( oVertexLocation, dRadius); } // Move the vertex if it falls outside the graph rectangle. MoveVertexIfNecessary(oVertex, ref oVertexBounds, oGraphDrawingContext); Point oLocation = GetVertexLocation(oVertex); VertexDrawingHistory oVertexDrawingHistory = null; // Note that for the "hollow" shapes -- Circle, Square, Diamond, and // Triangle -- Brushes.Transparent is used instead of a null brush. // This allows the entire area of these shapes to be hit-tested. Using // a null brush would cause hit-testing to fail if the shapes' // interiors were clicked. switch (eShape) { case VertexShape.Circle: case VertexShape.Disk: Boolean bIsDisk = (eShape == VertexShape.Disk); oDrawingContext.DrawEllipse( bIsDisk ? GetBrush(oColor) : Brushes.Transparent, bIsDisk ? null : GetPen(oColor, DefaultPenThickness), oLocation, dRadius, dRadius ); oVertexDrawingHistory = bIsDisk ? new DiskVertexDrawingHistory( oVertex, oDrawingVisual, bDrawAsSelected, dRadius) : new CircleVertexDrawingHistory( oVertex, oDrawingVisual, bDrawAsSelected, dRadius); break; case VertexShape.Sphere: RadialGradientBrush oRadialGradientBrush = new RadialGradientBrush(); oRadialGradientBrush.GradientOrigin = oRadialGradientBrush.Center = new Point(0.3, 0.3); GradientStopCollection oGradientStops = oRadialGradientBrush.GradientStops; oGradientStops.Add( new GradientStop(Colors.White, 0.0) ); oGradientStops.Add( new GradientStop(oColor, 1.0) ); WpfGraphicsUtil.FreezeIfFreezable(oRadialGradientBrush); oDrawingContext.DrawEllipse(oRadialGradientBrush, null, oLocation, dRadius, dRadius); oVertexDrawingHistory = new SphereVertexDrawingHistory( oVertex, oDrawingVisual, bDrawAsSelected, dRadius); break; case VertexShape.Square: case VertexShape.SolidSquare: Boolean bIsSolidSquare = (eShape == VertexShape.SolidSquare); oDrawingContext.DrawRectangle( bIsSolidSquare ? GetBrush(oColor) : Brushes.Transparent, bIsSolidSquare? null : GetPen(oColor, DefaultPenThickness), oVertexBounds ); oVertexDrawingHistory = bIsSolidSquare ? new SolidSquareVertexDrawingHistory(oVertex, oDrawingVisual, bDrawAsSelected, oVertexBounds) : new SquareVertexDrawingHistory(oVertex, oDrawingVisual, bDrawAsSelected, oVertexBounds); break; case VertexShape.Diamond: case VertexShape.SolidDiamond: Boolean bIsSolidDiamond = (eShape == VertexShape.SolidDiamond); PathGeometry oDiamond = WpfGraphicsUtil.DiamondFromCenterAndHalfWidth( oLocation, dRadius); oDrawingContext.DrawGeometry( bIsSolidDiamond ? GetBrush(oColor) : Brushes.Transparent, bIsSolidDiamond ? null : GetPen(oColor, DefaultPenThickness), oDiamond ); oVertexDrawingHistory = bIsSolidDiamond ? new SolidDiamondVertexDrawingHistory( oVertex, oDrawingVisual, bDrawAsSelected, dRadius) : new DiamondVertexDrawingHistory( oVertex, oDrawingVisual, bDrawAsSelected, dRadius); break; case VertexShape.Triangle: case VertexShape.SolidTriangle: Boolean bIsSolidTriangle = (eShape == VertexShape.SolidTriangle); PathGeometry oTriangle = WpfGraphicsUtil.TriangleFromCenterAndHalfWidth( oLocation, dRadius); oDrawingContext.DrawGeometry( bIsSolidTriangle ? GetBrush(oColor) : Brushes.Transparent, bIsSolidTriangle ? null : GetPen(oColor, DefaultPenThickness), oTriangle ); oVertexDrawingHistory = bIsSolidTriangle ? new SolidTriangleVertexDrawingHistory( oVertex, oDrawingVisual, bDrawAsSelected, dRadius) : new TriangleVertexDrawingHistory( oVertex, oDrawingVisual, bDrawAsSelected, dRadius); break; default: Debug.Assert(false); break; } if (sAnnotation != null) { oVertexLabelDrawer.DrawLabel( oDrawingContext, oGraphDrawingContext, oVertexDrawingHistory, oVertexBounds, CreateFormattedText(sAnnotation, oColor) ); } if ( oVertex.ContainsKey(ReservedMetadataKeys.PerVertexDrawPlusSign) ) { DrawPlusSign(eShape, oVertexLocation, oVertexBounds, oColor, oGraphDrawingContext, oDrawingContext, oVertexLabelDrawer, oVertexDrawingHistory); } Debug.Assert(oVertexDrawingHistory != null); return (oVertexDrawingHistory); }
//************************************************************************* // Method: DrawImageShape() // /// <summary> /// Draws a vertex as a specified image. /// </summary> /// /// <param name="oVertex"> /// The vertex to draw. /// </param> /// /// <param name="oGraphDrawingContext"> /// Provides access to objects needed for graph-drawing operations. /// </param> /// /// <param name="oDrawingContext"> /// The DrawingContext to use. /// </param> /// /// <param name="oDrawingVisual"> /// The <see cref="DrawingVisual" /> object from which <paramref /// name="oDrawingContext" /> was obtained. /// </param> /// /// <param name="eVisibility"> /// The visibility of the vertex. /// </param> /// /// <param name="bDrawAsSelected"> /// true to draw the vertex as selected. /// </param> /// /// <param name="sAnnotation"> /// The annotation to draw next to the image, or null if there is no /// annotation. /// </param> /// /// <param name="oImageSource"> /// The image to draw. /// </param> /// /// <param name="oVertexLabelDrawer"> /// Object that draws a vertex label as an annotation. /// </param> /// /// <returns> /// A VertexDrawingHistory object that retains information about how the /// vertex was drawn. /// </returns> //************************************************************************* protected VertexDrawingHistory DrawImageShape( IVertex oVertex, GraphDrawingContext oGraphDrawingContext, DrawingContext oDrawingContext, DrawingVisual oDrawingVisual, VisibilityKeyValue eVisibility, Boolean bDrawAsSelected, String sAnnotation, ImageSource oImageSource, VertexLabelDrawer oVertexLabelDrawer ) { Debug.Assert(oVertex != null); Debug.Assert(oGraphDrawingContext != null); Debug.Assert(oDrawingContext != null); Debug.Assert(oDrawingVisual != null); Debug.Assert(oImageSource != null); Debug.Assert(oVertexLabelDrawer != null); AssertValid(); // Move the vertex if it falls outside the graph rectangle. Rect oVertexRectangle = GetVertexRectangle( GetVertexLocation(oVertex), oImageSource.Width * m_dGraphScale, oImageSource.Height * m_dGraphScale); MoveVertexIfNecessary(oVertex, ref oVertexRectangle, oGraphDrawingContext); Byte btAlpha = 255; if (!bDrawAsSelected) { // Check for a non-opaque alpha value. btAlpha = GetAlpha(oVertex, eVisibility, btAlpha); } VertexDrawingHistory oVertexDrawingHistory = new ImageVertexDrawingHistory(oVertex, oDrawingVisual, bDrawAsSelected, oVertexRectangle); if (btAlpha > 0) { oDrawingContext.DrawImage(oImageSource, oVertexRectangle); Color oColor = GetColor(oVertex, eVisibility, bDrawAsSelected); // Draw an outline rectangle. oDrawingContext.DrawRectangle(null, GetPen(oColor, DefaultPenThickness), oVertexRectangle); if (btAlpha < 255) { // Real transparency can't be achieved with arbitrary images, // so simulate transparency by drawing on top of the image with // a translucent brush the same color as the graph's // background. // // This really isn't a good solution. Is there are better way // to simulate transparency? Color oTranslucentColor = oGraphDrawingContext.BackColor; oTranslucentColor.A = (Byte)( (Byte)255 - btAlpha ); oDrawingContext.DrawRectangle( CreateFrozenSolidColorBrush(oTranslucentColor), null, oVertexRectangle); } if (sAnnotation != null) { oVertexLabelDrawer.DrawLabel(oDrawingContext, oGraphDrawingContext, oVertexDrawingHistory, oVertexRectangle, CreateFormattedText(sAnnotation, oColor) ); } } return (oVertexDrawingHistory); }
//************************************************************************* // Method: DrawPlusSign() // /// <summary> /// Draws a plus sign on top of the vertex. /// </summary> /// /// <param name="eShape"> /// The simple vertex shape. /// </param> /// /// <param name="oGraphDrawingContext"> /// Provides access to objects needed for graph-drawing operations. /// </param> /// /// <param name="oVertexLocation"> /// The location of the vertex. /// </param> /// /// <param name="oDrawingContext"> /// The DrawingContext to use. /// </param> /// /// <param name="oVertexColor"> /// The color of the vertex. /// </param> /// /// <param name="oVertexLabelDrawer"> /// Object that draws a vertex label as an annotation. /// </param> /// /// <param name="oVertexDrawingHistory"> /// A <see cref="VertexDrawingHistory" /> object that retains information /// about how the vertex was drawn. /// </param> /// /// <param name="oVertexBounds"> /// The rectangle defining the bounds of the vertex. /// </param> //************************************************************************* protected void DrawPlusSign( VertexShape eShape, Point oVertexLocation, Rect oVertexBounds, Color oVertexColor, GraphDrawingContext oGraphDrawingContext, DrawingContext oDrawingContext, VertexLabelDrawer oVertexLabelDrawer, VertexDrawingHistory oVertexDrawingHistory ) { Debug.Assert(oGraphDrawingContext != null); Debug.Assert(oDrawingContext != null); Debug.Assert(oVertexLabelDrawer != null); Debug.Assert(oVertexDrawingHistory != null); AssertValid(); Color oFillColor; switch (eShape) { case VertexShape.Circle: case VertexShape.Square: case VertexShape.Diamond: case VertexShape.Triangle: // The fill color is the color of the background. Adjust the // fill color for the opacity of the vertex. oFillColor = WpfGraphicsUtil.SetWpfColorAlpha( oGraphDrawingContext.BackColor, oVertexColor.A); break; default: oFillColor = oVertexColor; break; } Color oContrastingColor = WpfGraphicsUtil.GetContrastingColor(oFillColor); // The font size used below was chosen so that it is large enough to be // easily readable, but small enough to fit within the smallest // collapsed group vertex created by the NodeXLControl. oVertexLabelDrawer.DrawLabel( oDrawingContext, oGraphDrawingContext, oVertexDrawingHistory, oVertexBounds, VertexLabelPosition.MiddleCenter, CreateFormattedText("+", oContrastingColor, 15.0) ); }