Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace WindowsFormsApplication4
- {
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Linq;
- using System.Windows.Forms;
- public class DropShadowPanel : Panel
- {
- protected override void OnControlAdded(ControlEventArgs e)
- {
- e.Control.Paint += Control_Paint;
- base.OnControlAdded(e);
- }
- void Control_Paint(object sender, PaintEventArgs e)
- {
- CheckDrawInnerShadow(sender as Control, e.Graphics);
- }
- private void CheckDrawInnerShadow(Control sender, Graphics g)
- {
- var dropShadowStruct = GetDropShadowStruct(sender);
- if (dropShadowStruct == null || !dropShadowStruct.Inset)
- {
- return;
- }
- DrawInsetShadow(sender, g);
- }
- protected override void OnControlRemoved(ControlEventArgs e)
- {
- e.Control.Paint -= Control_Paint;
- }
- protected override void OnPaint(PaintEventArgs e)
- {
- base.OnPaint(e);
- DrawShadow(Controls.OfType<Control>().Where(c => c.Tag != null && c.Tag.ToString().StartsWith("DropShadow")), e.Graphics);
- }
- void DrawInsetShadow(Control control, Graphics g)
- {
- var dropShadowStruct = GetDropShadowStruct(control);
- var rInner = new Rectangle(Point.Empty, control.Size);
- var img = new Bitmap(rInner.Width, rInner.Height, g);
- var g2 = Graphics.FromImage(img);
- g2.CompositingMode = CompositingMode.SourceCopy;
- g2.FillRectangle(new SolidBrush(dropShadowStruct.Color), 0, 0, control.Width, control.Height);
- rInner.Offset(dropShadowStruct.HShadow, dropShadowStruct.VShadow);
- rInner.Inflate(dropShadowStruct.Blur, dropShadowStruct.Blur);
- rInner.Inflate(-dropShadowStruct.Spread, -dropShadowStruct.Spread);
- double blurSize = dropShadowStruct.Blur;
- double blurStartSize = blurSize;
- do
- {
- var transparency = blurSize / blurStartSize;
- var color = Color.FromArgb(((int)(255 * (transparency * transparency))), dropShadowStruct.Color);
- rInner.Inflate(-1, -1);
- DrawRoundedRectangle(g2, rInner, (int)blurSize, Pens.Transparent, color);
- blurSize--;
- } while (blurSize > 0);
- g.DrawImage(img, 0, 0);
- g.Flush();
- g2.Dispose();
- img.Dispose();
- }
- void DrawShadow(IEnumerable<Control> controls, Graphics g)
- {
- foreach (var control in controls)
- {
- var dropShadowStruct = GetDropShadowStruct(control);
- if (dropShadowStruct.Inset)
- {
- continue; // must be handled by the control itself
- }
- DrawOutsetShadow(g, dropShadowStruct, control);
- }
- }
- // drawing the loop on an image because of speed
- private void DrawOutsetShadow(Graphics g, dynamic dropShadowStruct, Control control)
- {
- var rOuter = control.Bounds;
- var rInner = control.Bounds;
- rInner.Offset(dropShadowStruct.HShadow, dropShadowStruct.VShadow);
- rInner.Inflate(-dropShadowStruct.Blur, -dropShadowStruct.Blur);
- rOuter.Inflate(dropShadowStruct.Spread, dropShadowStruct.Spread);
- rOuter.Offset(dropShadowStruct.HShadow, dropShadowStruct.VShadow);
- var originalOuter = rOuter;
- var img = new Bitmap(originalOuter.Width, originalOuter.Height, g);
- var g2 = Graphics.FromImage(img);
- var currentBlur = 0;
- do
- {
- var transparency = (rOuter.Height - rInner.Height) / (double)(dropShadowStruct.Blur * 2 + dropShadowStruct.Spread * 2);
- var color = Color.FromArgb(((int)(255 * (transparency * transparency))), dropShadowStruct.Color);
- var rOutput = rInner;
- rOutput.Offset(-originalOuter.Left, -originalOuter.Top);
- DrawRoundedRectangle(g2, rOutput, currentBlur, Pens.Transparent, color);
- rInner.Inflate(1, 1);
- currentBlur = (int)((double)dropShadowStruct.Blur * (1 - (transparency * transparency)));
- } while (rOuter.Contains(rInner));
- g2.Flush();
- g2.Dispose();
- g.DrawImage(img, originalOuter);
- img.Dispose();
- }
- private static dynamic GetDropShadowStruct(Control control)
- {
- if (control.Tag == null || !(control.Tag is string) || !control.Tag.ToString().StartsWith("DropShadow"))
- return null;
- string[] dropShadowParams = control.Tag.ToString().Split(':')[1].Split(',');
- var dropShadowStruct = new
- {
- HShadow = Convert.ToInt32(dropShadowParams[0]),
- VShadow = Convert.ToInt32(dropShadowParams[1]),
- Blur = Convert.ToInt32(dropShadowParams[2]),
- Spread = Convert.ToInt32(dropShadowParams[3]),
- Color = ColorTranslator.FromHtml(dropShadowParams[4]),
- Inset = dropShadowParams[5].ToLowerInvariant() == "inset"
- };
- return dropShadowStruct;
- }
- private void DrawRoundedRectangle(Graphics gfx, Rectangle bounds, int cornerRadius, Pen drawPen, Color fillColor)
- {
- int strokeOffset = Convert.ToInt32(Math.Ceiling(drawPen.Width));
- bounds = Rectangle.Inflate(bounds, -strokeOffset, -strokeOffset);
- var gfxPath = new GraphicsPath();
- if (cornerRadius > 0)
- {
- gfxPath.AddArc(bounds.X, bounds.Y, cornerRadius, cornerRadius, 180, 90);
- gfxPath.AddArc(bounds.X + bounds.Width - cornerRadius, bounds.Y, cornerRadius, cornerRadius, 270, 90);
- gfxPath.AddArc(bounds.X + bounds.Width - cornerRadius, bounds.Y + bounds.Height - cornerRadius, cornerRadius,
- cornerRadius, 0, 90);
- gfxPath.AddArc(bounds.X, bounds.Y + bounds.Height - cornerRadius, cornerRadius, cornerRadius, 90, 90);
- }
- else
- {
- gfxPath.AddRectangle(bounds);
- }
- gfxPath.CloseAllFigures();
- gfx.FillPath(new SolidBrush(fillColor), gfxPath);
- if (drawPen != Pens.Transparent)
- {
- var pen = new Pen(drawPen.Color);
- pen.EndCap = pen.StartCap = LineCap.Round;
- gfx.DrawPath(pen, gfxPath);
- }
- }
- }
- }
Add Comment
Please, Sign In to add comment