Click here to Skip to main content
15,884,986 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 274.4K   6.5K   340  
Create fast, flexible, and extensible IDE applications easily with Storm - it takes nearly no code at all!
//
//    ___ _____ ___  ___ __  __ 
//   / __|_   _/ _ \| _ \  \/  |
//   \__ \ | || (_) |   / |\/| |
//   |___/ |_| \___/|_|_\_|  |_|
// 
//   Storm.TextEditor.dll
//   ��������������������
//     Storm.TabControl.dll was created under the LGPL 
//     license. Some of the code was created from scratch, 
//     some was not. Code not created from scratch was 
//     based on the DotNetFireball framework and evolved 
//     from that. 
//     
//     What I mostly did in this library was that I 
//     cleaned up the code, structured it, documentated 
//     it and added new features. 
//     
//     Although it might not sound like it, it was very
//     hard and took a long (pretty much a shitload)
//     time. Why? Well, this was* some of the crappiest,
//     most unstructured, undocumentated, ugly code I've
//     ever seen. It would actually have taken me less 
//     time to create it from scratch, but I figured that
//     out too late. Figuring out what the code actually
//     did and then documentating it was (mostly) a 
//     day-long process. Well, I hope you enjoy some of
//     my hard work. /rant
//     
//     Of course some/most of it is made from scratch by me.
//     *Yes, was. It isn't now. :) Some of the naming 
//     conventions might still seem a little bit off though.
//
//   What is Storm?
//   ��������������
//     Storm is a set of dynamic link libraries used in 
//     Theodor "Vestras" Storm Kristensen's application 
//     "Moonlite".
//     
//
//   Thanks:
//   �������
//     - The DotNetFireball team for creating and publishing 
//       DotNetFireball which I based some of my code on.
//
//
//   Copyright (c) Theodor "Vestras" Storm Kristensen 2009
//   �����������������������������������������������������
//


namespace Storm.TextEditor.Controls.Core
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Drawing.Design;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Diagnostics.Design;
    using System.Diagnostics.SymbolStore;
    using System.IO;
    using System.Reflection;
    using System.Resources;
    using System.Text;
    using System.Windows.Forms;

    using Storm.TextEditor;
    using Storm.TextEditor.Controls;
    using Storm.TextEditor.Controls.Core;
    using Storm.TextEditor.Controls.Core.Globalization;
    using Storm.TextEditor.Controls.Core.Timers;
    using Storm.TextEditor.Controls.IntelliMouse;
    using Storm.TextEditor.Document;
    using Storm.TextEditor.Document.Exporters;
    using Storm.TextEditor.Forms;
    using Storm.TextEditor.Interacting;
    using Storm.TextEditor.Painting;
    using Storm.TextEditor.Parsing;
    using Storm.TextEditor.Parsing.Base;
    using Storm.TextEditor.Parsing.Classes;
    using Storm.TextEditor.Parsing.Language;
    using Storm.TextEditor.Preset;
    using Storm.TextEditor.Preset.Painting;
    using Storm.TextEditor.Preset.TextDraw;
    using Storm.TextEditor.Printing;
    using Storm.TextEditor.Utilities;
    using Storm.TextEditor.Win32;

	public sealed class DrawingTools
	{
		public static void ResetGraphics(Graphics g)
		{
			g.ReleaseHdc(g.GetHdc());
		}

		public static Color MixColors(Color c1, Color c2, double mix)
		{
			double d = mix;
			return Color.FromArgb((int) (c1.R*(1 - d) + c2.R*d), (int) (c1.G*(1 - d) + c2.G*d), (int) (c1.B*(1 - d) + c2.B*d));
		}

		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();
		}

		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;

						System.Windows.Forms.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;
					}
			}
		}

		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();
		}

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

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

		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;

			System.Windows.Forms.ControlPaint.FillReversibleRectangle
                (new Rectangle(x, y, 2, 7), c);

			System.Windows.Forms.ControlPaint.FillReversibleRectangle
                (new Rectangle(x + 2, y + 1, width, 5), c);

			System.Windows.Forms.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;

			System.Windows.Forms.ControlPaint.FillReversibleRectangle
                (new Rectangle(x, y, 7, 2), c);

			System.Windows.Forms.ControlPaint.FillReversibleRectangle
                (new Rectangle(x + 1, y + 2, 5, height), c);

			System.Windows.Forms.ControlPaint.FillReversibleRectangle
                (new Rectangle(x, height + 2 + y, 7, 2), c);

		}


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

		public static bool DrawControl(Control control, Bitmap b)
		{
			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 i != 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)
			{
				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);
			}
		}

        /// <summary>
        /// Initializes the 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