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
 | 
						|
}
 |