257 lines
11 KiB
C#
257 lines
11 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
|
|
namespace DevComponents.DotNetBar
|
|
{
|
|
/// <summary>
|
|
/// Represents class that provides shadows to elements.
|
|
/// </summary>
|
|
public class ShadowPainter
|
|
{
|
|
/// <summary>
|
|
/// Creates new instance of shadow painter.
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Represents class that provides display context for shadow painter.
|
|
/// </summary>
|
|
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
|
|
}
|