using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; #if TREEGX namespace DevComponents.Tree #elif DOTNETBAR namespace DevComponents.DotNetBar #endif { /// /// Paints the ElementStyle /// public class ElementStyleDisplay { /// Creates new instance of the object. public ElementStyleDisplay() { } /// /// Paints text for given style. /// /// Display information. /// Text to paint. /// Default font if no font by style is specified. public static void PaintText(ElementStyleDisplayInfo e, string text, Font defaultFont) { PaintText(e, text, defaultFont, false); } /// /// Paints text for given style. /// /// Display information. /// /// Default font if no font by style is specified. /// Specifies whether to use default font for painting regardless of style settings. public static void PaintText(ElementStyleDisplayInfo e, string text, Font defaultFont, bool useDefaultFont) { PaintText(e, text, defaultFont, useDefaultFont, e.Style.TextFormat); } /// /// Paints text for given style. /// /// Display information. /// /// Default font if no font by style is specified. /// Specifies whether to use default font for painting regardless of style settings. public static void PaintText(ElementStyleDisplayInfo e, string text, Font defaultFont, bool useDefaultFont, eTextFormat textFormat) { Rectangle textBounds = e.Bounds; ElementStyle style = GetElementStyle(e.Style); if (text == "" || textBounds.IsEmpty || style.TextColor.IsEmpty) return; Font font = style.Font; if (font == null || useDefaultFont) font = defaultFont; textBounds.X += style.MarginLeft; textBounds.Width -= (style.MarginLeft + style.MarginRight); textBounds.Y += style.MarginTop; textBounds.Height -= (style.MarginTop + style.MarginBottom); if (!style.TextShadowColor.IsEmpty && Math.Abs(style.TextShadowColor.GetBrightness() - style.TextColor.GetBrightness()) > .2) { using (SolidBrush brush = new SolidBrush(style.TextShadowColor)) { Rectangle r = textBounds; r.Offset(style.TextShadowOffset); TextDrawing.DrawString(e.Graphics, text, font, style.TextShadowColor, r, textFormat); //e.Graphics.DrawString(text,font,brush,r,style.StringFormat); } } if (!style.TextColor.IsEmpty) TextDrawing.DrawString(e.Graphics, text, font, style.TextColor, textBounds, textFormat); } /// Returns new Region object for given ElementStyle. /// New instance of Region object. /// Information to describe ElementStyle. public static Region GetStyleRegion(ElementStyleDisplayInfo e) { Rectangle rectPath = e.Bounds; if (e.Style.PaintBorder && e.Style.CornerType!=eCornerType.Square) { rectPath.Width--; rectPath.Height--; } GraphicsPath path = ElementStyleDisplay.GetBackgroundPath(e.Style, rectPath); Region r = new Region(); r.MakeEmpty(); r.Union(path); // Widen path for the border... if (e.Style.PaintBorder && (e.Style.CornerType == eCornerType.Rounded || e.Style.CornerType == eCornerType.Diagonal || e.Style.CornerTypeTopLeft == eCornerType.Rounded || e.Style.CornerTypeTopLeft == eCornerType.Diagonal || e.Style.CornerTypeTopRight==eCornerType.Rounded || e.Style.CornerTypeTopRight==eCornerType.Diagonal || e.Style.CornerTypeBottomLeft==eCornerType.Rounded || e.Style.CornerTypeBottomLeft==eCornerType.Diagonal || e.Style.CornerTypeBottomRight==eCornerType.Rounded || e.Style.CornerTypeBottomRight==eCornerType.Diagonal)) { using (Pen pen = new Pen(Color.Black, (e.Style.BorderTopWidth>0?e.Style.BorderTopWidth:1))) { path.Widen(pen); } //Region r2 = new Region(path); r.Union(path); } return r; //GraphicsPath path=ElementStyleDisplay.GetBackgroundPath(e.Style,e.Bounds,false); //return new Region(path); } /// /// Returns the clipping for the content of the element style. /// /// /// public static GraphicsPath GetInsideClip(ElementStyleDisplayInfo e) { Rectangle rectPath = e.Bounds; // GDI bug if (e.Style.PaintBorder) { if (e.Style.PaintTopBorder) { rectPath.Y += e.Style.BorderTopWidth; rectPath.Height -= e.Style.BorderTopWidth; if (e.Style.BorderTop == eStyleBorderType.Etched || e.Style.BorderTop == eStyleBorderType.Double) { rectPath.Y += e.Style.BorderTopWidth; rectPath.Height -= e.Style.BorderTopWidth; } } if (e.Style.PaintBottomBorder) { rectPath.Height -= e.Style.BorderBottomWidth; if (e.Style.BorderBottom == eStyleBorderType.Etched || e.Style.BorderBottom == eStyleBorderType.Double) rectPath.Height -= e.Style.BorderBottomWidth; } if (e.Style.PaintLeftBorder) { rectPath.X += e.Style.BorderLeftWidth; rectPath.Width -= e.Style.BorderLeftWidth; if (e.Style.BorderLeft == eStyleBorderType.Etched || e.Style.BorderLeft == eStyleBorderType.Double) { rectPath.X += e.Style.BorderLeftWidth; rectPath.Width -= e.Style.BorderLeftWidth; } } if (e.Style.PaintRightBorder) { rectPath.Width -= e.Style.BorderRightWidth; if (e.Style.BorderRight == eStyleBorderType.Etched || e.Style.BorderRight == eStyleBorderType.Double) rectPath.Width -= e.Style.BorderRightWidth; } } GraphicsPath path = ElementStyleDisplay.GetBackgroundPath(e.Style, rectPath); return path; } /// /// Paints the element style on the canvas. /// /// Holds information neccessary to paint style on canvas. public static void Paint(ElementStyleDisplayInfo e) { ElementStyleDisplay.PaintBackground(e); ElementStyleDisplay.PaintBackgroundImage(e); ElementStyleDisplay.PaintBorder(e); } private static eCornerType GetCornerType(eCornerType baseType, eCornerType specificType) { if(specificType!=eCornerType.Inherit) return specificType; return baseType; } /// /// Paint style border. /// /// Style display information. public static void PaintBorder(ElementStyleDisplayInfo e) { ElementStyle style = GetElementStyle(e.Style); Rectangle bounds=ElementStyleDisplay.GetBorderRectangle(style,e.Bounds); if (bounds.Width < 2 || bounds.Height < 2) return; eCornerType cornerTopLeft = GetCornerType(style.CornerType, style.CornerTypeTopLeft); eCornerType cornerTopRight = GetCornerType(style.CornerType, style.CornerTypeTopRight); eCornerType cornerBottomLeft = GetCornerType(style.CornerType, style.CornerTypeBottomLeft); eCornerType cornerBottomRight = GetCornerType(style.CornerType, style.CornerTypeBottomRight); if (!style.BorderColor2.IsEmpty || !style.BorderColorLight.IsEmpty) { if (style.Border == eStyleBorderType.Solid) { using (GraphicsPath path = DisplayHelp.GetRoundedRectanglePath(bounds, style.CornerDiameter, eStyleBackgroundPathPart.Complete, cornerTopLeft, cornerTopRight, cornerBottomLeft, cornerBottomRight)) { DisplayHelp.DrawGradientPathBorder(e.Graphics, path, style.BorderColor, style.BorderColor2, style.BorderGradientAngle, style.BorderWidth); } return; } else if (style.Border == eStyleBorderType.Etched) { Rectangle r = bounds; r.Width -= style.BorderWidth; r.Height -= style.BorderWidth; r.Offset(style.BorderWidth, style.BorderWidth); if (r.Width > 2 && r.Height > 2) { using (GraphicsPath path = DisplayHelp.GetRoundedRectanglePath(r, style.CornerDiameter, eStyleBackgroundPathPart.Complete, cornerTopLeft, cornerTopRight, cornerBottomLeft, cornerBottomRight)) { DisplayHelp.DrawGradientPathBorder(e.Graphics, path, style.BorderColorLight, style.BorderColorLight2, style.BorderLightGradientAngle, style.BorderWidth); } r.Offset(-style.BorderWidth, -style.BorderWidth); using (GraphicsPath path = DisplayHelp.GetRoundedRectanglePath(r, style.CornerDiameter, eStyleBackgroundPathPart.Complete, cornerTopLeft, cornerTopRight, cornerBottomLeft, cornerBottomRight)) { DisplayHelp.DrawGradientPathBorder(e.Graphics, path, style.BorderColor, style.BorderColor2, style.BorderGradientAngle, style.BorderWidth); } } return; } else if ((style.BorderTop == eStyleBorderType.Double && style.BorderLeft == eStyleBorderType.Double && style.BorderRight == eStyleBorderType.Double && style.BorderBottom == eStyleBorderType.Double) || (style.BorderTop == eStyleBorderType.None && style.BorderLeft == eStyleBorderType.Double && style.BorderRight == eStyleBorderType.Double && style.BorderBottom == eStyleBorderType.Double)) { Rectangle r = bounds; Region oldClip = null; bool clipSet = false; if (style.BorderTop == eStyleBorderType.None) { Rectangle clipRect = r; clipRect.Width++; clipRect.Height++; e.Graphics.SetClip(clipRect); r.Y -= 3; r.Height += 3; } using(GraphicsPath path = DisplayHelp.GetBorderPath(r, style.CornerDiameter, eStyleBackgroundPathPart.Complete, cornerTopLeft, cornerTopRight, cornerBottomLeft, cornerBottomRight, style.PaintLeftBorder, style.PaintRightBorder, style.PaintTopBorder, style.PaintBottomBorder)) { using (Pen pen = new Pen(style.BorderColor, style.BorderWidth)) path.Widen(pen); DisplayHelp.FillPath(e.Graphics, path, style.BorderColor, style.BorderColor2); } r.Inflate(-style.BorderWidth, -style.BorderWidth); using (GraphicsPath path = DisplayHelp.GetBorderPath(r, style.CornerDiameter, eStyleBackgroundPathPart.Complete, cornerTopLeft, cornerTopRight, cornerBottomLeft, cornerBottomRight, style.PaintLeftBorder, style.PaintRightBorder, style.PaintTopBorder, style.PaintBottomBorder)) { using (Pen pen = new Pen(style.BorderColor, style.BorderWidth)) path.Widen(pen); DisplayHelp.FillPath(e.Graphics, path, style.BorderColorLight, style.BorderColorLight2); } if (clipSet) e.Graphics.Clip = oldClip; return; } } Color colorStart = style.BorderColor; Color colorEnd = style.BorderColor2; Color colorLightStart = style.BorderColorLight; Color colorLightEnd = style.BorderColorLight2; if(style.PaintLeftBorder) { Color color=style.BorderColor; if(!style.BorderLeftColor.IsEmpty) color=style.BorderLeftColor; Point[] p=new Point[2]; // Corner type square is default setting p[0]=bounds.Location; p[1].X=bounds.X; p[1].Y=bounds.Bottom; if(cornerTopLeft!=eCornerType.Square) { p[0].Y+=style.CornerDiameter; } if(cornerBottomLeft!=eCornerType.Square) { p[1].Y-=style.CornerDiameter; } ElementStyleDisplay.DrawBorderLine(e.Graphics, p, style.BorderLeft, style.BorderLeftWidth, color, colorEnd, colorLightStart, colorLightEnd, eBorderSide.Left); if(style.PaintTopBorder && cornerTopLeft!=eCornerType.Square) { if(cornerTopLeft==eCornerType.Diagonal) { p[0].X=bounds.X; p[0].Y=bounds.Y+style.CornerDiameter; p[1].X=bounds.X+style.CornerDiameter; p[1].Y=bounds.Y; ElementStyleDisplay.DrawBorderLine(e.Graphics, p, style.BorderLeft, style.BorderLeftWidth, color, colorEnd, colorLightStart, colorLightEnd, eBorderSide.TopLeft); } else if(cornerTopLeft==eCornerType.Rounded) { ArcData a=GetCornerArc(bounds,style.CornerDiameter,eCornerArc.TopLeft);// new ArcData(bounds.X,bounds.Y,style.CornerDiameter*2,style.CornerDiameter*2,180,90); ElementStyleDisplay.DrawCornerArc(e.Graphics,a,style.BorderLeft,style.BorderLeftWidth,color); } } if(style.PaintBottomBorder && cornerBottomLeft!=eCornerType.Square) { if(cornerBottomLeft==eCornerType.Diagonal) { p[0].X=bounds.X; p[0].Y=bounds.Bottom-style.CornerDiameter; p[1].X=bounds.X+style.CornerDiameter; p[1].Y=bounds.Bottom; ElementStyleDisplay.DrawBorderLine(e.Graphics, p, style.BorderLeft, style.BorderLeftWidth, color, colorEnd, colorLightStart, colorLightEnd, eBorderSide.BottomLeft); } else if(cornerBottomLeft==eCornerType.Rounded) { ArcData a=GetCornerArc(bounds,style.CornerDiameter,eCornerArc.BottomLeft);// new ArcData(bounds.X,bounds.Y,style.CornerDiameter*2,style.CornerDiameter*2,180,90); ElementStyleDisplay.DrawCornerArc(e.Graphics,a,style.BorderLeft,style.BorderLeftWidth,color); } } } if(style.PaintTopBorder) { Color color=style.BorderColor; if(!style.BorderTopColor.IsEmpty) color=style.BorderTopColor; Point[] p=new Point[2]; // Default setting for Square corner type on both sides p[0]=bounds.Location; p[1].X=bounds.Right; p[1].Y=bounds.Y; if(cornerTopLeft!=eCornerType.Square) { p[0].X+=style.CornerDiameter; } if(cornerTopRight!=eCornerType.Square) { p[1].X-=style.CornerDiameter; } ElementStyleDisplay.DrawBorderLine(e.Graphics, p, style.BorderTop, style.BorderTopWidth, color, colorEnd, colorLightStart, colorLightEnd, eBorderSide.Top); } if(style.PaintBottomBorder) { Color color=style.BorderColor; if(!style.BorderBottomColor.IsEmpty) color=style.BorderBottomColor; Point[] p=new Point[2]; // Default for Square corner type on both sides p[0].X=bounds.X; p[0].Y=bounds.Bottom; p[1].X=bounds.Right; p[1].Y=bounds.Bottom; if(cornerBottomLeft!=eCornerType.Square) { p[0].X+=style.CornerDiameter; } if(cornerBottomRight!=eCornerType.Square) { p[1].X-=style.CornerDiameter; } ElementStyleDisplay.DrawBorderLine(e.Graphics, p, style.BorderBottom, style.BorderBottomWidth, color, colorEnd, colorLightStart, colorLightEnd, eBorderSide.Bottom); } if(style.PaintRightBorder) { Color color=style.BorderColor; if(!style.BorderRightColor.IsEmpty) color=style.BorderRightColor; Point[] p=new Point[2]; // Default for Square corner type on both sides p[0].X=bounds.Right; p[0].Y=bounds.Y; p[1].X=bounds.Right; p[1].Y=bounds.Bottom; if(cornerTopRight!=eCornerType.Square) { p[0].Y+=style.CornerDiameter; } if(cornerBottomRight!=eCornerType.Square) { p[1].Y-=style.CornerDiameter; } ElementStyleDisplay.DrawBorderLine(e.Graphics, p, style.BorderRight, style.BorderRightWidth, color, colorEnd, colorLightStart, colorLightEnd, eBorderSide.Right); if(style.PaintTopBorder && cornerTopRight!=eCornerType.Square) { if(cornerTopRight==eCornerType.Diagonal) { p[0].X=bounds.Right-style.CornerDiameter; p[0].Y=bounds.Y; p[1].X=bounds.Right; p[1].Y=bounds.Y+style.CornerDiameter; ElementStyleDisplay.DrawBorderLine(e.Graphics, p, style.BorderLeft, style.BorderRightWidth, color, colorEnd, colorLightStart, colorLightEnd, eBorderSide.TopRight); } else if(cornerTopRight==eCornerType.Rounded) { ArcData a=GetCornerArc(bounds,style.CornerDiameter,eCornerArc.TopRight);// new ArcData(bounds.X,bounds.Y,style.CornerDiameter*2,style.CornerDiameter*2,180,90); ElementStyleDisplay.DrawCornerArc(e.Graphics,a,style.BorderLeft,style.BorderLeftWidth,color); } } if(style.PaintBottomBorder && cornerBottomRight!=eCornerType.Square) { if(cornerBottomRight==eCornerType.Diagonal) { p[0].X=bounds.Right; p[0].Y=bounds.Bottom-style.CornerDiameter; p[1].X=bounds.Right-style.CornerDiameter; p[1].Y=bounds.Bottom; ElementStyleDisplay.DrawBorderLine(e.Graphics,p,style.BorderLeft,style.BorderRightWidth,color, colorEnd, colorLightStart, colorLightEnd,eBorderSide.BottomRight); } else if(cornerBottomRight==eCornerType.Rounded) { ArcData a=GetCornerArc(bounds,style.CornerDiameter,eCornerArc.BottomRight);// new ArcData(bounds.X,bounds.Y,style.CornerDiameter*2,style.CornerDiameter*2,180,90); ElementStyleDisplay.DrawCornerArc(e.Graphics,a,style.BorderLeft,style.BorderLeftWidth,color); } } } } private static Pen CreatePen(eStyleBorderType border,int lineWidth, Color color) { Pen pen=new Pen(color,lineWidth); pen.Alignment=PenAlignment.Inset; pen.DashStyle=ElementStyleDisplay.GetDashStyle(border); return pen; } private static void DrawBorderLine(Graphics g,Point[] p,eStyleBorderType border,int lineWidth, Color colorStart, Color colorEnd, Color colorLightStart, Color colorLightEnd, eBorderSide side) { if (border == eStyleBorderType.Etched || border == eStyleBorderType.Double) { if (colorLightStart.IsEmpty) { colorLightStart = System.Windows.Forms.ControlPaint.Light(colorStart); colorStart = System.Windows.Forms.ControlPaint.Dark(colorStart); } if (side == eBorderSide.Bottom || side == eBorderSide.Right) { Color ct1 = colorStart; Color ct2 = colorEnd; colorStart = colorLightStart; colorEnd = colorLightEnd; colorLightStart = ct1; colorLightEnd = ct2; } DisplayHelp.DrawGradientLine(g, p[0], p[1], colorStart, colorEnd, 90, lineWidth); if (side == eBorderSide.Top) { p[0].Y+=lineWidth; p[1].Y += lineWidth; } else if (side == eBorderSide.Bottom) { p[0].Y -= lineWidth; p[1].Y -= lineWidth; } else if (side == eBorderSide.Left || side == eBorderSide.BottomLeft || side == eBorderSide.TopLeft) { p[0].X += lineWidth; p[1].X += lineWidth; } else if (side == eBorderSide.Right || side == eBorderSide.BottomRight || side == eBorderSide.TopRight) { p[0].X -= lineWidth; p[1].X -= lineWidth; } DisplayHelp.DrawGradientLine(g, p[0], p[1], colorLightStart, colorLightEnd, 90, lineWidth); } else { if (colorEnd.IsEmpty) { SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; using (Pen pen = CreatePen(border, lineWidth, colorStart)) g.DrawLine(pen, p[0], p[1]); g.SmoothingMode = sm; } else DisplayHelp.DrawGradientLine(g, p[0], p[1], colorStart, colorEnd, 90, lineWidth); } } private static void DrawCornerArc(Graphics g,ArcData arc,eStyleBorderType border,int lineWidth, Color color) { using(Pen pen=CreatePen(border,lineWidth,color)) { g.DrawArc(pen,arc.X,arc.Y,arc.Width,arc.Height,arc.StartAngle,arc.SweepAngle); } } private static DashStyle GetDashStyle(eStyleBorderType border) { DashStyle style=DashStyle.Solid; switch(border) { case eStyleBorderType.Dash: style=DashStyle.Dash; break; case eStyleBorderType.DashDot: style=DashStyle.DashDot; break; case eStyleBorderType.DashDotDot: style=DashStyle.DashDotDot; break; case eStyleBorderType.Dot: style=DashStyle.Dot; break; } return style; } internal static ElementStyle GetElementStyle(ElementStyle style) { if (style.Class == "") return style; IElementStyleClassProvider provider = GetIElementStyleClassProvider(); if (provider != null) { ElementStyle baseStyle = provider.GetClass(style.Class); if (baseStyle != null) { return baseStyle; } } return style; } private static IElementStyleClassProvider GetIElementStyleClassProvider() { #if DOTNETBAR if (Rendering.GlobalManager.Renderer is Rendering.Office2007Renderer) { return ((Rendering.Office2007Renderer)Rendering.GlobalManager.Renderer).ColorTable as IElementStyleClassProvider; } #endif return null; } /// /// Paints style background. /// /// Style display information. public static void PaintBackground(ElementStyleDisplayInfo e) { Region oldClip = e.Graphics.Clip; if (oldClip != null) e.Graphics.SetClip(e.Bounds, CombineMode.Intersect); else e.Graphics.SetClip(e.Bounds, CombineMode.Replace); ElementStyle style = GetElementStyle(e.Style); SmoothingMode sm = e.Graphics.SmoothingMode; e.Graphics.SmoothingMode = SmoothingMode.Default; // Paint Background Rectangle bounds=DisplayHelp.GetDrawRectangle(ElementStyleDisplay.GetBackgroundRectangle(style,e.Bounds)); GraphicsPath path; path = ElementStyleDisplay.GetBackgroundPath(style, e.Bounds); eBackgroundColorBlendType blendType = style.BackColorBlend.GetBlendType(); if (blendType!=eBackgroundColorBlendType.Invalid) { if (blendType == eBackgroundColorBlendType.Relative) { try { if (style.BackColorGradientType == eGradientType.Linear) { Rectangle rb = bounds; rb.Inflate(1, 1); using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, style.BackColor, style.BackColor2, style.BackColorGradientAngle)) { brush.InterpolationColors = style.BackColorBlend.GetColorBlend(); e.Graphics.FillPath(brush, path); } } else if (style.BackColorGradientType == eGradientType.Radial) { int d = (int)Math.Sqrt(bounds.Width * bounds.Width + bounds.Height * bounds.Height) + 4; GraphicsPath fillPath = new GraphicsPath(); fillPath.AddEllipse(bounds.X - (d - bounds.Width) / 2, bounds.Y - (d - bounds.Height) / 2, d, d); using (PathGradientBrush brush = new PathGradientBrush(fillPath)) { brush.CenterColor = style.BackColor; brush.SurroundColors = new Color[] { style.BackColor2 }; brush.InterpolationColors = style.BackColorBlend.GetColorBlend(); e.Graphics.FillPath(brush, path); } fillPath.Dispose(); } } catch { blendType = eBackgroundColorBlendType.Invalid; } } else { Graphics g = e.Graphics; bounds = e.Bounds; if (oldClip != null) { e.Graphics.SetClip(oldClip, CombineMode.Replace); e.Graphics.SetClip(path, CombineMode.Intersect); } else e.Graphics.SetClip(path, CombineMode.Replace); BackgroundColorBlendCollection bc = style.BackColorBlend; for (int i = 0; i < bc.Count; i+=2) { BackgroundColorBlend b1 = bc[i]; BackgroundColorBlend b2 = null; if (i < bc.Count) b2 = bc[i + 1]; if (b1 != null && b2 != null) { Rectangle rb = new Rectangle(bounds.X, bounds.Y + (int)b1.Position, bounds.Width, (b2.Position == 1f ? bounds.Height : (int)b2.Position) - (int)b1.Position); using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, b1.Color, b2.Color, style.BackColorGradientAngle)) g.FillRectangle(brush, rb); } } } } if(blendType==eBackgroundColorBlendType.Invalid) { if (style.BackColor2.IsEmpty) { if (!style.BackColor.IsEmpty) { using (SolidBrush brush = new SolidBrush(style.BackColor)) e.Graphics.FillPath(brush, path); //if(e.Style.BackColor.A==255) //{ // // Correct problems with FillPath where path was not filled properly... // using(Pen pen=new Pen(e.Style.BackColor,1)) // e.Graphics.DrawPath(pen,path); //} } } else if (!style.BackColor.IsEmpty) { if (style.BackColorGradientType == eGradientType.Linear) { Rectangle rb = bounds; rb.X--; rb.Height++; rb.Width += 2; using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, style.BackColor, style.BackColor2, style.BackColorGradientAngle)) { e.Graphics.FillPath(brush, path); } } else if (style.BackColorGradientType == eGradientType.Radial) { int d = (int)Math.Sqrt(bounds.Width * bounds.Width + bounds.Height * bounds.Height) + 4; GraphicsPath fillPath = new GraphicsPath(); fillPath.AddEllipse(bounds.X - (d - bounds.Width) / 2, bounds.Y - (d - bounds.Height) / 2, d, d); using (PathGradientBrush brush = new PathGradientBrush(fillPath)) { brush.CenterColor = style.BackColor; brush.SurroundColors = new Color[] { style.BackColor2 }; e.Graphics.FillPath(brush, path); } fillPath.Dispose(); } } } e.Graphics.SmoothingMode = sm; if (oldClip != null) e.Graphics.Clip = oldClip; else e.Graphics.ResetClip(); } /// /// Paints style background image. /// /// Style display information. public static void PaintBackgroundImage(ElementStyleDisplayInfo e) { ElementStyle style = GetElementStyle(e.Style); if(style.BackgroundImage==null) return; Rectangle bounds = DisplayHelp.GetDrawRectangle(ElementStyleDisplay.GetBackgroundRectangle(style, e.Bounds)); GraphicsPath path; if (e.Graphics.SmoothingMode == SmoothingMode.AntiAlias) { Rectangle r = e.Bounds; r.Width--; //r.Height--; path = ElementStyleDisplay.GetBackgroundPath(style, r); } else path = ElementStyleDisplay.GetBackgroundPath(style, e.Bounds); ImageAttributes imageAtt=null; if (style.BackgroundImageAlpha != 255) { ColorMatrix colorMatrix=new ColorMatrix(); colorMatrix.Matrix33 = 255 - style.BackgroundImageAlpha; imageAtt=new ImageAttributes(); imageAtt.SetColorMatrix(colorMatrix,ColorMatrixFlag.Default,ColorAdjustType.Bitmap); } Region clip=e.Graphics.Clip; e.Graphics.SetClip(path); eStyleBackgroundImage imagePosition = style.BackgroundImagePosition; bool transform = false; Image backgroundImage = style.BackgroundImage; if (e.RightToLeft) { if (imagePosition == eStyleBackgroundImage.TopLeft) { imagePosition = eStyleBackgroundImage.TopRight; transform = true; } else if (imagePosition == eStyleBackgroundImage.TopRight) imagePosition = eStyleBackgroundImage.TopLeft; else if (imagePosition == eStyleBackgroundImage.BottomLeft) imagePosition = eStyleBackgroundImage.BottomRight; else if (imagePosition == eStyleBackgroundImage.BottomRight) imagePosition = eStyleBackgroundImage.BottomLeft; } if (transform) { backgroundImage = backgroundImage.Clone() as Image; backgroundImage.RotateFlip(RotateFlipType.RotateNoneFlipX); } switch (imagePosition) { case eStyleBackgroundImage.Stretch: { if(imageAtt!=null) e.Graphics.DrawImage(backgroundImage, bounds, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); else e.Graphics.DrawImage(backgroundImage, bounds, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel); break; } case eStyleBackgroundImage.Center: { Rectangle destRect = new Rectangle(bounds.X, bounds.Y, backgroundImage.Width, backgroundImage.Height); if (bounds.Width > backgroundImage.Width) destRect.X += (bounds.Width - backgroundImage.Width) / 2; if (bounds.Height > backgroundImage.Height) destRect.Y += (bounds.Height - backgroundImage.Height) / 2; if(imageAtt!=null) e.Graphics.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); else e.Graphics.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel); break; } case eStyleBackgroundImage.TopLeft: case eStyleBackgroundImage.TopRight: case eStyleBackgroundImage.BottomLeft: case eStyleBackgroundImage.BottomRight: { Rectangle destRect = new Rectangle(bounds.X, bounds.Y, backgroundImage.Width, backgroundImage.Height); if (imagePosition == eStyleBackgroundImage.TopRight) destRect.X = bounds.Right - backgroundImage.Width; else if (imagePosition == eStyleBackgroundImage.BottomLeft) destRect.Y = bounds.Bottom - backgroundImage.Height; else if (imagePosition == eStyleBackgroundImage.BottomRight) { destRect.Y = bounds.Bottom - backgroundImage.Height; destRect.X = bounds.Right - backgroundImage.Width; } if(imageAtt!=null) e.Graphics.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); else e.Graphics.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel); break; } case eStyleBackgroundImage.Tile: { if(imageAtt!=null) { if (bounds.Width > backgroundImage.Width || bounds.Height > backgroundImage.Height) { int x=bounds.X,y=bounds.Y; while(ybounds.Right) destRect.Width=destRect.Width-(destRect.Right-bounds.Right); if(destRect.Bottom>bounds.Bottom) destRect.Height=destRect.Height-(destRect.Bottom-bounds.Bottom); e.Graphics.DrawImage(backgroundImage, destRect, 0, 0, destRect.Width, destRect.Height, GraphicsUnit.Pixel, imageAtt); x += backgroundImage.Width; } x=bounds.X; y += backgroundImage.Height; } } else { e.Graphics.DrawImage(backgroundImage, new Rectangle(0, 0, backgroundImage.Width, backgroundImage.Height), 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); } } else { TextureBrush brush = new TextureBrush(backgroundImage); brush.WrapMode=WrapMode.Tile; e.Graphics.FillPath(brush,path); brush.Dispose(); } break; } } if (transform) { backgroundImage.Dispose(); } if (clip != null) e.Graphics.Clip = clip; else e.Graphics.ResetClip(); } /// /// Returns background rectangle for given style by taking in account margins. /// /// Reference to style object. /// Style bounds /// Background rectangle. public static Rectangle GetBackgroundRectangle(ElementStyle style, Rectangle bounds) { // Reduce the bounds rectangle size by the margin size bounds.X+=style.MarginLeft; bounds.Width-=(style.MarginLeft+style.MarginRight); bounds.Y+=style.MarginTop; bounds.Height-=(style.MarginTop+style.MarginBottom); return bounds; } private static Rectangle GetBorderRectangle(ElementStyle style, Rectangle bounds) { bounds=GetBackgroundRectangle(style,bounds); if(style.PaintRightBorder) { if(style.BorderRightWidth<=1) bounds.Width-=style.BorderRightWidth; else bounds.Width-=style.BorderRightWidth/2; } if(style.PaintBottomBorder) { if(style.BorderBottomWidth<=1) bounds.Height-=style.BorderBottomWidth; else bounds.Height-=style.BorderBottomWidth/2; } if(style.PaintLeftBorder && style.BorderLeftWidth>1) { bounds.X+=style.BorderLeftWidth/2; bounds.Width-=style.BorderLeftWidth/2; } if(style.PaintTopBorder && style.BorderTopWidth>1) { bounds.X+=style.BorderTopWidth/2; bounds.Width-=style.BorderTopWidth/2; } return bounds; } private static Rectangle GetTextRectangle(ElementStyle style, Rectangle bounds) { bounds=ElementStyleDisplay.GetBackgroundRectangle(style,bounds); // Reduce the bounds rectangle size by the padding size bounds.X+=style.PaddingLeft; bounds.Width-=(style.PaddingLeft+style.PaddingRight); bounds.Y+=style.PaddingTop; bounds.Height-=(style.PaddingTop+style.PaddingBottom); return bounds; } /// /// Returns GraphicsPath for given style. /// /// Reference to style. /// Style bounds. /// New instance of GraphicsPath public static GraphicsPath GetBackgroundPath(ElementStyle style, Rectangle bounds) { return GetBackgroundPath(style, bounds, eStyleBackgroundPathPart.Complete); } /// /// Returns GraphicsPath for given style. /// /// Reference to style. /// Style bounds. /// New instance of GraphicsPath public static GraphicsPath GetBackgroundPath(ElementStyle style, Rectangle bounds, eStyleBackgroundPathPart pathPart) { GraphicsPath path=new GraphicsPath(); Rectangle clientRectangle; //if(drawPath) clientRectangle=/*DisplayHelp.GetDrawRectangle*/(ElementStyleDisplay.GetBackgroundRectangle(style,bounds)); //else // clientRectangle =/*DisplayHelp.GetDrawRectangle*/(ElementStyleDisplay.GetBackgroundRectangle(style, bounds)); if (pathPart==eStyleBackgroundPathPart.Complete && style.CornerTypeBottomLeft == eCornerType.Inherit && style.CornerTypeBottomRight == eCornerType.Inherit && style.CornerTypeTopLeft == eCornerType.Inherit && style.CornerTypeTopRight == eCornerType.Inherit) { switch (style.CornerType) { case eCornerType.Square: { path.AddRectangle(clientRectangle); break; } case eCornerType.Rounded: { ArcData ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.TopLeft); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.TopRight); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.BottomRight); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.BottomLeft); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); path.CloseAllFigures(); break; } case eCornerType.Diagonal: { path.AddLine(clientRectangle.X, clientRectangle.Bottom - style.CornerDiameter - 1, clientRectangle.X, clientRectangle.Y + style.CornerDiameter); path.AddLine(clientRectangle.X + style.CornerDiameter, clientRectangle.Y, clientRectangle.Right - style.CornerDiameter, clientRectangle.Y); path.AddLine(clientRectangle.Right, clientRectangle.Y + style.CornerDiameter, clientRectangle.Right, clientRectangle.Bottom - style.CornerDiameter - 1); path.AddLine(clientRectangle.Right - style.CornerDiameter - 1, clientRectangle.Bottom, clientRectangle.X + style.CornerDiameter, clientRectangle.Bottom); path.CloseAllFigures(); break; } } } else { if(pathPart==eStyleBackgroundPathPart.TopHalf) clientRectangle.Height = clientRectangle.Height/2; else if(pathPart==eStyleBackgroundPathPart.BottomHalf) { int h=clientRectangle.Height; clientRectangle.Height = clientRectangle.Height/2; clientRectangle.Y += (h - clientRectangle.Height-1); } eCornerType corner = style.CornerTypeTopLeft; if (corner == eCornerType.Inherit) corner = style.CornerType; if(pathPart==eStyleBackgroundPathPart.BottomHalf) corner=eCornerType.Square; if (corner == eCornerType.Rounded) { ArcData ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.TopLeft); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); } else if (corner == eCornerType.Diagonal) { path.AddLine(clientRectangle.X, clientRectangle.Y + style.CornerDiameter, clientRectangle.X + style.CornerDiameter, clientRectangle.Y); } else { path.AddLine(clientRectangle.X, clientRectangle.Y + 2, clientRectangle.X, clientRectangle.Y); path.AddLine(clientRectangle.X, clientRectangle.Y ,clientRectangle.X+2, clientRectangle.Y); } corner = style.CornerTypeTopRight; if (corner == eCornerType.Inherit) corner = style.CornerType; if(pathPart==eStyleBackgroundPathPart.BottomHalf) corner=eCornerType.Square; if (corner == eCornerType.Rounded) { ArcData ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.TopRight); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); } else if (corner == eCornerType.Diagonal) { path.AddLine(clientRectangle.Right-style.CornerDiameter-1, clientRectangle.Y , clientRectangle.Right, clientRectangle.Y+style.CornerDiameter); } else { path.AddLine(clientRectangle.Right-2, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y); path.AddLine(clientRectangle.Right, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y+2); } corner = style.CornerTypeBottomRight; if (corner == eCornerType.Inherit) corner = style.CornerType; if(pathPart==eStyleBackgroundPathPart.TopHalf) corner=eCornerType.Square; if (corner == eCornerType.Rounded) { ArcData ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.BottomRight); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); } else if (corner == eCornerType.Diagonal) { path.AddLine(clientRectangle.Right, clientRectangle.Bottom - style.CornerDiameter - 1, clientRectangle.Right - style.CornerDiameter - 1, clientRectangle.Bottom); } else { path.AddLine(clientRectangle.Right, clientRectangle.Bottom-2, clientRectangle.Right, clientRectangle.Bottom); path.AddLine(clientRectangle.Right, clientRectangle.Bottom, clientRectangle.Right-2, clientRectangle.Bottom); } corner = style.CornerTypeBottomLeft; if (corner == eCornerType.Inherit) corner = style.CornerType; if(pathPart==eStyleBackgroundPathPart.TopHalf) corner=eCornerType.Square; if (corner == eCornerType.Rounded) { ArcData ad = GetCornerArc(clientRectangle, style.CornerDiameter, eCornerArc.BottomLeft); path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); } else if (corner == eCornerType.Diagonal) { path.AddLine(clientRectangle.X + 2, clientRectangle.Bottom, clientRectangle.X, clientRectangle.Bottom - style.CornerDiameter - 1); } else { path.AddLine(clientRectangle.X+2, clientRectangle.Bottom, clientRectangle.X, clientRectangle.Bottom); path.AddLine(clientRectangle.X, clientRectangle.Bottom, clientRectangle.X, clientRectangle.Bottom-2); } } return path; } internal static void AddCornerArc(GraphicsPath path, Rectangle bounds, int cornerDiameter, eCornerArc corner) { ArcData a = GetCornerArc(bounds, cornerDiameter, corner); path.AddArc(a.X, a.Y, a.Width, a.Height, a.StartAngle, a.SweepAngle); } internal static ArcData GetCornerArc(Rectangle bounds, int cornerDiameter, eCornerArc corner) { ArcData a; int diameter=cornerDiameter*2; switch(corner) { case eCornerArc.TopLeft: a=new ArcData(bounds.X,bounds.Y,diameter,diameter,180,90); break; case eCornerArc.TopRight: a=new ArcData(bounds.Right-diameter,bounds.Y,diameter,diameter,270,90); break; case eCornerArc.BottomLeft: a=new ArcData(bounds.X,bounds.Bottom-diameter,diameter,diameter,90,90); break; default: // eCornerArc.BottomRight: a=new ArcData(bounds.Right-diameter,bounds.Bottom-diameter,diameter,diameter,0,90); break; } return a; } enum eBorderSide { Top, Bottom, Left, Right, TopLeft, TopRight, BottomLeft, BottomRight } } internal enum eCornerArc { TopLeft, TopRight, BottomLeft, BottomRight } /// /// Represents information neccessary to paint the style on canvas. /// public class ElementStyleDisplayInfo { /// Reference to ElementStyle object. public ElementStyle Style=null; /// Reference to Graphics object. public Graphics Graphics=null; /// ElementStyle bounds. public Rectangle Bounds=Rectangle.Empty; /// Get or sets whether layout is right-to-left. public bool RightToLeft = false; /// Creates new instance of the object. public ElementStyleDisplayInfo() { } /// Creates new instance of the object and initializes it with default values. /// Style to initialize object with. /// Graphics object to initialize object with. /// Bounds to initialize object with. public ElementStyleDisplayInfo(ElementStyle style, Graphics g, Rectangle bounds) { this.Style=style; this.Graphics=g; this.Bounds=bounds; } // public ElementStyleDisplayInfo(ElementStyle style, System.Drawing.Graphics g, Rectangle bounds, string text, Rectangle textBounds) // { // this.Style=style; // this.Graphics=g; // this.Bounds=bounds; // this.Text=text; // this.TextBounds=textBounds; // } } #region eStyleBackgroundPathPart /// /// Specifies part of the background path. /// public enum eStyleBackgroundPathPart { /// /// Indicates complete background path /// Complete, /// /// Indicates Top half of background path /// TopHalf, /// /// Indicates Bottom half of background path /// BottomHalf } #endregion #region ArcData internal struct ArcData { public int X; public int Y; public int Width; public int Height; public float StartAngle; public float SweepAngle; public ArcData(int x, int y, int width, int height, float startAngle, float sweepAngle) { this.X=x; this.Y=y; this.Width=width; this.Height=height; this.StartAngle=startAngle; this.SweepAngle=sweepAngle; } } #endregion }