using System; using System.Drawing; using System.Drawing.Drawing2D; namespace DevComponents.DotNetBar { /// /// Represents class that provides shadows to elements. /// public class ShadowPainter { /// /// Creates new instance of shadow painter. /// public ShadowPainter() { } private static System.Drawing.Drawing2D.GraphicsPath GetPath(Rectangle r) { System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); path.AddLine(r.Left + 1, r.Y, r.Right - 1, r.Y); path.AddLine(r.Right - 1, r.Y, r.Right - 1, r.Y + 1); path.AddLine(r.Right - 1, r.Y + 1, r.Right, r.Y + 1); path.AddLine(r.Right, r.Y + 1, r.Right, r.Bottom - 1); path.AddLine(r.Right, r.Bottom - 1, r.Right - 1, r.Bottom - 1); path.AddLine(r.Right - 1, r.Bottom - 1, r.Right - 1, r.Bottom); path.AddLine(r.Right - 1, r.Bottom, r.Left + 1, r.Bottom); path.AddLine(r.Left + 1, r.Bottom, r.Left + 1, r.Bottom - 1); path.AddLine(r.Left + 1, r.Bottom - 1, r.Left, r.Bottom - 1); path.AddLine(r.Left, r.Bottom - 1, r.Left, r.Top + 1); return path; } public static void Paint(ShadowPaintInfo info) { Paint(info, 0); } public static void Paint(ShadowPaintInfo info, int alphaOffset) { Graphics g = info.Graphics; Region oldClip = g.Clip; if (info.ClipRectangle.IsEmpty) g.SetClip(info.Rectangle, CombineMode.Exclude); else g.SetClip(info.ClipRectangle, CombineMode.Exclude); Color[] clr = new Color[]{ Color.FromArgb(Math.Max(0, 14-alphaOffset),Color.Black), Color.FromArgb(Math.Max(0,43-alphaOffset),Color.Black), Color.FromArgb(Math.Max(0,84-alphaOffset),Color.Black), Color.FromArgb(Math.Max(0,113-alphaOffset),Color.Black), Color.FromArgb(Math.Max(0,128-alphaOffset),Color.Black)}; Rectangle r = info.Rectangle; if (info.IsSquare) { r.Inflate(info.Size, info.Size); r.Width += info.Size; } else { r.Width--; r.Height--; int offset = info.Size / 2; r.Offset(offset + 1, offset); r.Width += (info.Size - offset); r.Height += (info.Size - offset); } //r.Width--; //r.Height--; //int offset = info.Size / 2; //r.Offset(offset,offset); //r.Width+=(info.Size-offset); //r.Height+=(info.Size-offset); for (int i = 0; i < info.Size; i++) { using (Pen pen = new Pen(clr[i], 1)) { using (GraphicsPath path = GetPath(r)) g.DrawPath(pen, path); r.Inflate(-1, -1); } } g.Clip = oldClip; } public static void Paint2(ShadowPaintInfo info) { if (info.Size <= 2) return; Graphics g = info.Graphics; Color c = Color.FromArgb(128, Color.Black); Rectangle r = info.Rectangle; r.Offset(info.Size - 1, info.Size - 1); using (Bitmap bmp = new Bitmap(info.Size, info.Size)) { using (Graphics bg = Graphics.FromImage(bmp)) { using (GraphicsPath path = new GraphicsPath()) { path.AddEllipse(0, 0, info.Size * 2, info.Size * 2); using (PathGradientBrush brush = new PathGradientBrush(path)) { brush.CenterColor = c; brush.SurroundColors = new Color[] { Color.Transparent }; bg.FillRectangle(brush, new Rectangle(0, 0, info.Size, info.Size)); } } } g.DrawImage(bmp, r.X, r.Y); bmp.RotateFlip(RotateFlipType.Rotate90FlipNone); g.DrawImage(bmp, r.Right - info.Size, r.Y); bmp.RotateFlip(RotateFlipType.Rotate90FlipNone); g.DrawImage(bmp, r.Right - info.Size, r.Bottom - info.Size); bmp.RotateFlip(RotateFlipType.Rotate90FlipNone); g.DrawImage(bmp, r.X, r.Bottom - info.Size); } SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; Rectangle rb = new Rectangle(r.X + info.Size, r.Y + 1, r.Width - info.Size * 2, info.Size - 1); using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, Color.Transparent, c, 90)) g.FillRectangle(brush, rb); rb.Offset(0, r.Height - info.Size - 1); using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, c, Color.Transparent, 90)) g.FillRectangle(brush, rb); rb = new Rectangle(r.X, r.Y + info.Size, info.Size, r.Height - info.Size * 2); using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, Color.Transparent, c, 0)) g.FillRectangle(brush, rb); rb.Offset(r.Width - info.Size - 1, 0); using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, c, Color.Transparent, 0)) g.FillRectangle(brush, rb); g.SmoothingMode = sm; } private static Bitmap _ShadowTemplate = null; private static Bitmap[] _ShadowParts = null; private static int LastUsedShadowVersion = 1; public static void Paint3(ShadowPaintInfo p) { Paint3(p, 1); } public static void Paint3(ShadowPaintInfo p, int shadowVersion) { if (LastUsedShadowVersion != shadowVersion && _ShadowTemplate != null) { _ShadowTemplate.Dispose(); _ShadowTemplate = null; for (int i = 0; i < _ShadowParts.Length; i++) { _ShadowParts[i].Dispose(); } _ShadowParts = null; } if (_ShadowTemplate == null) { if(shadowVersion == 1) _ShadowTemplate = BarFunctions.LoadBitmap("SystemImages.Shadow3px.png"); else _ShadowTemplate = BarFunctions.LoadBitmap("SystemImages.Shadow3px-2.png"); _ShadowParts = new Bitmap[4]; // Left part Bitmap bmp = new Bitmap(_ShadowTemplate, 1, 1); using (Graphics gb = Graphics.FromImage(bmp)) { gb.DrawImage(_ShadowTemplate, new Rectangle(0, 0, 1, 1), new Rectangle(0, 3, 1, 1), GraphicsUnit.Pixel); _ShadowParts[0] = bmp; } // Top part bmp = new Bitmap(_ShadowTemplate, 1, 1); using (Graphics gb = Graphics.FromImage(bmp)) { gb.DrawImage(_ShadowTemplate, new Rectangle(0, 0, 1, 1), new Rectangle(3, 0, 1, 1), GraphicsUnit.Pixel); _ShadowParts[1] = bmp; } // Right part bmp = new Bitmap(_ShadowTemplate, 3, 1); using (Graphics gb = Graphics.FromImage(bmp)) { gb.DrawImage(_ShadowTemplate, new Rectangle(0, 0, 3, 1), new Rectangle(_ShadowTemplate.Width - 3, 6, 3, 1), GraphicsUnit.Pixel); _ShadowParts[2] = bmp; //bmp.Save(@"d:\rightpart.png", System.Drawing.Imaging.ImageFormat.Png); } // Bottom part bmp = new Bitmap(_ShadowTemplate, 1, 3); using (Graphics gb = Graphics.FromImage(bmp)) { gb.DrawImage(_ShadowTemplate, new Rectangle(0, 0, 1, 3), new Rectangle(5, _ShadowTemplate.Height - 3, 1, 3), GraphicsUnit.Pixel); _ShadowParts[3] = bmp; } } Graphics g = p.Graphics; SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; Rectangle r = p.Rectangle; g.DrawImage(_ShadowTemplate, new Rectangle(r.X, r.Y, 1, 1), new Rectangle(0, 0, 1, 1), GraphicsUnit.Pixel); // Left side using (TextureBrush brush = new TextureBrush(_ShadowParts[0], System.Drawing.Drawing2D.WrapMode.Tile)) { g.FillRectangle(brush, new Rectangle(r.X, r.Y + 1, _ShadowParts[0].Width, r.Height - 4)); } // Top side using (TextureBrush brush = new TextureBrush(_ShadowParts[1], System.Drawing.Drawing2D.WrapMode.Tile)) { g.FillRectangle(brush, new Rectangle(r.X + 1, r.Y, r.Width - 4, _ShadowParts[1].Height)); } // Top-Right corner g.DrawImage(_ShadowTemplate, new Rectangle(r.Right - 3, r.Y, 3, 4), new Rectangle(_ShadowTemplate.Width - 3, 0, 3, 4), GraphicsUnit.Pixel); // Right side using (TextureBrush brush = new TextureBrush(_ShadowParts[2], System.Drawing.Drawing2D.WrapMode.Tile)) { Rectangle rightSide = new Rectangle(r.Right - _ShadowParts[2].Width, r.Y + 4, _ShadowParts[2].Width, r.Height - 7); brush.TranslateTransform(rightSide.X, rightSide.Y); g.FillRectangle(brush, rightSide); } // Bottom-right corner g.DrawImage(_ShadowTemplate, new Rectangle(r.Right - 4, r.Bottom - 3, 4, 3), new Rectangle(_ShadowTemplate.Width - 4, _ShadowTemplate.Height - 3, 4, 3), GraphicsUnit.Pixel); // Bottom side using (TextureBrush brush = new TextureBrush(_ShadowParts[3], System.Drawing.Drawing2D.WrapMode.Tile)) { Rectangle bottomSide = new Rectangle(r.X + 4, r.Bottom - 3, r.Width - 8, _ShadowParts[3].Height); brush.TranslateTransform(bottomSide.X, bottomSide.Y); g.FillRectangle(brush, bottomSide); } // Bottom-left corner g.DrawImage(_ShadowTemplate, new Rectangle(r.X, r.Bottom - 3, 4, 3), new Rectangle(0, _ShadowTemplate.Height - 3, 4, 3), GraphicsUnit.Pixel); g.SmoothingMode = sm; LastUsedShadowVersion = shadowVersion; } } #region ShadowPaintInfo class /// /// Represents class that provides display context for shadow painter. /// public class ShadowPaintInfo { public System.Drawing.Graphics Graphics = null; public System.Drawing.Rectangle Rectangle = Rectangle.Empty; public int Size = 3; public System.Drawing.Rectangle ClipRectangle = Rectangle.Empty; public bool IsSquare = false; } #endregion }