Click here to Skip to main content
15,898,134 members
Articles / Desktop Programming / Windows Forms

Storm - the world's best IDE framework for .NET

Rate me:
Please Sign up or sign in to vote.
4.96/5 (82 votes)
4 Feb 2010LGPL311 min read 278.6K   6.5K   340  
Create fast, flexible, and extensible IDE applications easily with Storm - it takes nearly no code at all!
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;

using Storm.TextEditor.Core;
using Storm.TextEditor.Win32;
using Storm.TextEditor.Win32.Enums;

namespace Storm.TextEditor.Drawing
{
	/// <summary>
	/// Represents a sealed class holding several methods for drawing.
	/// </summary>
	public sealed class DrawingTools
	{
		#region Methods

		#region Public

		/// <summary>
		/// Resets the given Graphics variable.
		/// </summary>
		/// <param name="g">Graphics to reset.</param>
		public static void ResetGraphics(Graphics g)
		{
			g.ReleaseHdc(g.GetHdc());
		}

		/// <summary>
		/// Mixes the given colors and returns the new color.
		/// </summary>
		/// <param name="c1">First color to mix.</param>
		/// <param name="c2">Second color to mix.</param>
		/// <param name="mix">Factor of the mixing.</param>
		/// <returns>The mixed color.</returns>
		public static Color MixColors(Color c1, Color c2, double mix)
		{
			return Color.FromArgb((int)(c1.R * (1 - mix) + c2.R * mix), (int)(c1.G * 
				(1 - mix) + c2.G * mix), (int)(c1.B * (1 - mix) + c2.B * mix));
		}

		/// <summary>
		/// Draws a border depending on the given ControlBorderStyle with specific color at the given Rectangle.
		/// </summary>
		/// <param name="style">ControlBorderStyle that holds how the method should draw the border.</param>
		/// <param name="borderColor">Color of the drawn border.</param>
		/// <param name="g">Graphics to use when drawing.</param>
		/// <param name="r">Rectangle to draw the border at.</param>
		public static void DrawBorder(ControlBorderStyle style, Color borderColor, Graphics g, Rectangle r)
		{
			switch (style)
			{
				case ControlBorderStyle.Dotted:
					{
						r.Width--;
						r.Height--;

						g.DrawRectangle(new Pen(SystemColors.Control), r);
						Pen p = new Pen(borderColor);
						p.DashStyle = DashStyle.Dot;
						g.DrawRectangle(p, r);

						break;
					}
				case ControlBorderStyle.Dashed:
					{
						r.Width--;
						r.Height--;

						g.DrawRectangle(new Pen(SystemColors.Control), r);
						Pen p = new Pen(borderColor);
						p.DashStyle = DashStyle.Dash;
						g.DrawRectangle(p, r);

						break;
					}
				case ControlBorderStyle.Sunken:
					{
						if (borderColor == Color.Black)
							borderColor = SystemColors.Control;

						DrawingTools.DrawBorder(Border3DStyle.Sunken, borderColor, g, r);

						break;
					}
				case ControlBorderStyle.FixedSingle:
					{
						r.Width--;
						r.Height--;

						g.DrawRectangle(new Pen(borderColor), r);
						break;
					}
				case ControlBorderStyle.FixedDouble:
					{
						g.DrawRectangle(new Pen(borderColor), r.Left, r.Top, r.Width - 1, r.Height - 1);
						g.DrawRectangle(new Pen(borderColor), r.Left + 1, r.Top + 1, r.Width - 3, r.Height - 3);

						break;
					}
				case ControlBorderStyle.Raised:
					{
						if (borderColor == Color.Black)
							borderColor = SystemColors.Control;

						DrawingTools.DrawBorder(Border3DStyle.Raised, borderColor, g, r);
						break;
					}
				case ControlBorderStyle.RaisedThin:
					{
						if (borderColor == Color.Black)
						{
							borderColor = Color.FromArgb(SystemColors.Control.R,
								SystemColors.Control.G, SystemColors.Control.B);
						}

						DrawingTools.DrawBorder(Border3DStyle.RaisedInner,
							borderColor, g, r);

						break;
					}
				case ControlBorderStyle.SunkenThin:
					{
						if (borderColor == Color.Black)
						{
							borderColor = Color.FromArgb(SystemColors.Control.R,
								SystemColors.Control.G, SystemColors.Control.B);
						}

						DrawingTools.DrawBorder(Border3DStyle.SunkenOuter,
							borderColor, g, r);
						break;
					}
				case ControlBorderStyle.Etched:
					{
						if (borderColor == Color.Black)
							borderColor = SystemColors.Control;

						ControlPaint.DrawBorder3D(g, r,
							Border3DStyle.Etched);

						break;
					}
				case ControlBorderStyle.Bump:
					{
						if (borderColor == Color.Black)
							borderColor = SystemColors.Control;

						SolidBrush b = new SolidBrush(borderColor);
						g.FillRectangle(b, r.Left, r.Top, r.Width, 4);
						g.FillRectangle(b, r.Left, r.Bottom - 4, r.Width, 4);

						g.FillRectangle(b, r.Left, r.Top, 4, r.Height);
						g.FillRectangle(b, r.Right - 4, r.Top, 4, r.Height);
						b.Dispose();

						DrawingTools.DrawBorder(Border3DStyle.Raised, borderColor, g, r);
						DrawingTools.DrawBorder(Border3DStyle.Sunken, borderColor, g,
							new Rectangle(r.Left + 4, r.Top + 4, r.Width - 8,
							r.Height - 8));

						break;
					}
				case ControlBorderStyle.Column:
					{
						SolidBrush normal = new SolidBrush(borderColor);
						SolidBrush light = new SolidBrush(MixColors(borderColor,
							Color.White, 1));

						SolidBrush dark = new SolidBrush(MixColors(borderColor,
							Color.Black, 0.4));

						SolidBrush darkdark = new SolidBrush(Color.FromArgb
							(borderColor.A, System.Windows.Forms.ControlPaint.
							DarkDark(borderColor)));

						g.FillRectangle(light, r.Left, r.Top, r.Width, 1);
						g.FillRectangle(light, r.Left, r.Top + 3, 1, r.Height - 1 - 6);
						g.FillRectangle(dark, r.Right - 1, r.Top + 3, 1, r.Height - 6);
						g.FillRectangle(dark, r.Left, r.Bottom - 1, r.Width, 1);

						break;
					}
				case ControlBorderStyle.Row:
					{
						SolidBrush normal = new SolidBrush(borderColor);
						SolidBrush light = new SolidBrush(MixColors(borderColor,
							Color.White, 1));

						SolidBrush dark = new SolidBrush(MixColors(borderColor,
							Color.Black, 0.4));

						SolidBrush darkdark = new SolidBrush(Color.FromArgb
							(borderColor.A, System.Windows.Forms.ControlPaint.DarkDark
							(borderColor)));

						g.FillRectangle(light, r.Left + 3, r.Top, r.Width - 6, 1);
						g.FillRectangle(light, r.Left, r.Top, 1, r.Height - 1);
						g.FillRectangle(dark, r.Right - 1, r.Top, 1, r.Height);
						g.FillRectangle(dark, r.Left + 3, r.Bottom - 1, r.Width - 6, 1);

						break;
					}
			}
		}

		/// <summary>
		/// Draws a line at the given coordinates.
		/// </summary>
		/// <param name="g">Graphics to use when drawing.</param>
		/// <param name="x1">Start x coordinate.</param>
		/// <param name="y1">Start y coordinate.</param>
		/// <param name="x2">End x coordinate.</param>
		/// <param name="y2">End y coordinate.</param>
		public static void DrawDesignTimeLine(Graphics g, int x1, int y1, int x2, int y2)
		{
			Pen p = new Pen(SystemColors.ControlDarkDark);

			p.DashOffset = 10;
			p.DashStyle = DashStyle.Dash;

			g.DrawLine(p, x1, y1, x2, y2);
			p.Dispose();
		}

		/// <summary>
		/// Draws the given image as a gray version.
		/// </summary>
		/// <param name="g">Graphics to use when drawing.</param>
		/// <param name="image">Image to draw.</param>
		/// <param name="x">X coordinate to draw the image at.</param>
		/// <param name="y">Y coordinate to draw the image at.</param>
		/// <param name="transparencyFactor">Factor of the transparency.</param>
		public static void DrawGrayImage(Graphics g, Image image, int x, int y, float transparencyFactor)
		{
			ColorMatrix cm = new ColorMatrix();
			ImageAttributes ia = new ImageAttributes();

			cm.Matrix33 = transparencyFactor;
			cm.Matrix00 = 0.33333334F;
			cm.Matrix01 = 0.33333334F;
			cm.Matrix02 = 0.33333334F;
			cm.Matrix10 = 0.33333334F;
			cm.Matrix11 = 0.33333334F;
			cm.Matrix12 = 0.33333334F;
			cm.Matrix20 = 0.33333334F;
			cm.Matrix21 = 0.33333334F;
			cm.Matrix22 = 0.33333334F;

			ia.SetColorMatrix(cm);
			g.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0,
				image.Width, image.Height, GraphicsUnit.Pixel, ia);
		}

		/// <summary>
		/// Draws the given image as a transparent version.
		/// </summary>
		/// <param name="g">Graphics to use when drawing.</param>
		/// <param name="image">Image to draw.</param>
		/// <param name="x">X coordinate to draw the image at.</param>
		/// <param name="y">Y coordinate to draw the image at.</param>
		/// <param name="transparencyFactor">Factor of the transparency.</param>
		public static void DrawTransparentImage(Graphics g, Image image, int x, int y, float transparencyFactor)
		{
			ImageAttributes ia = new ImageAttributes();
			ColorMatrix cm = new ColorMatrix();

			cm.Matrix33 = transparencyFactor;
			cm.Matrix00 = 1.0F;
			cm.Matrix11 = 1.0F;
			cm.Matrix22 = 1.0F;

			ia.SetColorMatrix(cm);
			g.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0,
				image.Width, image.Height, GraphicsUnit.Pixel, ia);
		}

		/// <summary>
		/// Draws a border using DashStyle.Dash at the given Rectangle.
		/// </summary>
		/// <param name="g">Graphics to use when drawing.</param>
		/// <param name="rect">Rectangle to draw the border at.</param>
		public static void DrawDesignTimeBorder(Graphics g, Rectangle rect)
		{
			rect.Width--;
			rect.Height--;

			Pen p = new Pen(SystemColors.ControlDarkDark);
			p.DashStyle = DashStyle.Dash;

			g.DrawRectangle(p, rect);
			p.Dispose();
		}

		public static void DrawInsertIndicatorH(int x, int y, int width, Graphics g, Color c)
		{
			y -= 3;
			x -= 2;

			ControlPaint.FillReversibleRectangle(new Rectangle(x, y, 2, 7), c);
			ControlPaint.FillReversibleRectangle(new Rectangle(x + 2, y + 1, width, 5), c);
			ControlPaint.FillReversibleRectangle(new Rectangle(width + 2 + x, y, 2, 7), c);
		}

		public static void DrawInsertIndicatorV(int x, int y, int height, Graphics g, Color c)
		{
			x -= 3;
			y -= 2;

			ControlPaint.FillReversibleRectangle(new Rectangle(x, y, 7, 2), c);
			ControlPaint.FillReversibleRectangle(new Rectangle(x + 1, y + 2, 5, height), c);
			ControlPaint.FillReversibleRectangle(new Rectangle(x, height + 2 + y, 7, 2), c);
		}

		/// <summary>
		/// Draws the given Control.
		/// </summary>
		/// <param name="control">Control to draw.</param>
		/// <returns>Bitmap created from the given Control.</returns>
		public static Bitmap DrawControl(Control control)
		{
			Bitmap b = new Bitmap(control.Width, control.Height);

			Graphics g = Graphics.FromImage(b);
			IntPtr hdc = g.GetHdc();

			int i = NativeUser32Api.SendMessage(control.Handle,
				(int)WindowMessage.WM_PRINT, (int)hdc,
				(int)(WMPrintFlags.PRF_CLIENT |
				WMPrintFlags.PRF_ERASEBKGND));

			g.ReleaseHdc(hdc);
			g.Dispose();

			return b;
		}

		/// <summary>
		/// Draws the given Control.
		/// </summary>
		/// <param name="control">Control to draw.</param>
		/// <param name="b">Bitmap to create graphics from.</param>
		/// <returns>Whether the drawing was succesful.</returns>
		public static bool DrawControl(Control control, Bitmap b)
		{
			Graphics g = Graphics.FromImage(b);
			IntPtr hdc = g.GetHdc();

			int result = NativeUser32Api.SendMessage(control.Handle, (int)WindowMessage.WM_PRINT, (int)hdc, 
				(int)(WMPrintFlags.PRF_CLIENT | WMPrintFlags.PRF_ERASEBKGND));
			
			g.ReleaseHdc(hdc);
			g.Dispose();
			
			return result != 0;
		}

		public static void DrawSortArrow(int x, int y, Graphics g, bool ascending)
		{
			Color c1 = Color.FromArgb(220, 255, 255, 255);
			Color c2 = Color.FromArgb(140, 0, 0, 0);

			Pen p1 = new Pen(c1);
			Pen p2 = new Pen(c2);

			if (ascending == true)
			{
				g.DrawLine(p1, x, y + 6, x + 7, y + 6);
				g.DrawLine(p2, x + 3, y, x, y + 6);
				g.DrawLine(p1, x + 4, y, x + 7, y + 6);
			}
			else
			{
				g.DrawLine(p2, x, y, x + 7, y);
				g.DrawLine(p2, x, y, x + 3, y + 6);
				g.DrawLine(p1, x + 7, y, x + 4, y + 6);
			}
		}

		#endregion

		#region Private

		private static void DrawBorder(Border3DStyle Style, Color BorderColor, Graphics g, Rectangle r)
		{
			SolidBrush normal = new SolidBrush(BorderColor);
			SolidBrush light;

			if (BorderColor.GetBrightness() > 0.6)
				light = new SolidBrush(MixColors(BorderColor, Color.White, 1));
			else
				light = new SolidBrush(MixColors(BorderColor, Color.White, 0.5));

			SolidBrush dark;
			SolidBrush darkdark;

			if (BorderColor.GetBrightness() < 0.5)
			{
				dark = new SolidBrush(MixColors(BorderColor, Color.Black, 0.7));
				darkdark = new SolidBrush(MixColors(BorderColor, Color.Black, 1));
			}
			else
			{
				dark = new SolidBrush(MixColors(BorderColor, Color.Black, 0.4));
				darkdark = new SolidBrush(MixColors(BorderColor, Color.Black, 0.6));
			}

			switch (Style)
			{
				case Border3DStyle.Sunken:
					{
						g.FillRectangle(dark, r.Left, r.Top, r.Width, 1);
						g.FillRectangle(dark, r.Left, r.Top, 1, r.Height);
						g.FillRectangle(darkdark, r.Left + 1, r.Top + 1, r.Width - 2, 1);
						g.FillRectangle(darkdark, r.Left + 1, r.Top + 1, 1, r.Height - 2);

						g.FillRectangle(light, r.Right - 1, r.Top + 1, 1, r.Height - 1);
						g.FillRectangle(light, r.Left + 1, r.Bottom - 1, r.Width - 1, 1);
						g.FillRectangle(normal, r.Right - 2, r.Top + 2, 1, r.Height - 3);
						g.FillRectangle(normal, r.Left + 2, r.Bottom - 2, r.Width - 3, 1);
						break;
					}
				case Border3DStyle.Raised:
					{
						g.FillRectangle(normal, r.Left, r.Top, r.Width - 1, 1);
						g.FillRectangle(normal, r.Left, r.Top, 1, r.Height - 1);
						g.FillRectangle(light, r.Left + 1, r.Top + 1, r.Width - 2, 1);
						g.FillRectangle(light, r.Left + 1, r.Top + 1, 1, r.Height - 2);

						g.FillRectangle(darkdark, r.Right - 1, r.Top, 1, r.Height);
						g.FillRectangle(darkdark, r.Left, r.Bottom - 1, r.Width, 1);
						g.FillRectangle(dark, r.Right - 2, r.Top + 1, 1, r.Height - 2);
						g.FillRectangle(dark, r.Left + 1, r.Bottom - 2, r.Width - 2, 1);

						break;
					}
				case Border3DStyle.RaisedInner:
					{
						g.FillRectangle(light, r.Left, r.Top, r.Width - 1, 1);
						g.FillRectangle(light, r.Left, r.Top, 1, r.Height - 1);

						g.FillRectangle(dark, r.Right - 1, r.Top, 1, r.Height);
						g.FillRectangle(dark, r.Left, r.Bottom - 1, r.Width, 1);

						break;
					}
				case Border3DStyle.SunkenOuter:
					{
						g.FillRectangle(dark, r.Left, r.Top, r.Width, 1);
						g.FillRectangle(dark, r.Left, r.Top, 1, r.Height);

						g.FillRectangle(light, r.Right - 1, r.Top + 1, 1, r.Height - 1);
						g.FillRectangle(light, r.Left + 1, r.Bottom - 1, r.Width - 1, 1);

						break;
					}
				case Border3DStyle.Etched:
					break;
				default:
					break;
			}

			normal.Dispose();
			light.Dispose();
			dark.Dispose();
			darkdark.Dispose();
		}

		#endregion

		#endregion

		/// <summary>
		/// Initializes a new instance of DrawingTools.
		/// </summary>
		private DrawingTools()
		{
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)



Comments and Discussions