Click here to Skip to main content
15,886,422 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.6K   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
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Drawing.Design;
    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.Web;
    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;

    [ToolboxItem(false)]
	public class FormatLabelControl : Widget
	{
		#region Members
		private string _text = "format <b>label</b>";

		private ArrayList   _rows = null;
		private Hashtable  _fonts = new Hashtable();
		private Hashtable _images = new Hashtable();

		private VScrollBar    _vScroll = null;
		private HScrollBar    _hScroll = null;
		private ScrollBars _scrollBars = 0;

		private FormatLabelElement[]    _elements = null;
		private FormatLabelElement _activeElement = null;

		private ImageList _imageList = null;
		private PictureBox   _filler = null;

		private Color      _linkColor = Color.Blue;
		private Color _linkColorHover = Color.Blue;

		private GDISurface _bufferSurface = null;

		private bool      _linkUnderLine = false;
		private bool _linkUnderLineHover = true;
		private bool      _hasImageError = false;

		private bool           _wordWrap = true;
		private bool _autoSizeHorizontal = false;
		private bool   _autoSizeVertical = false;

		private int _margin = 0;

		// Form Designer generated.
		private Container components = null;

		#region Events
		public event ClickLinkEventHandler ClickLink = null;
		#endregion
		#endregion

		#region Properties
		public int LabelMargin
		{
			get { return _margin; }
			set
			{
				_margin = value;
				CreateRows();
				Invalidate();
			}
		}

		public ImageList ImageList
		{
			get { return _imageList; }
			set
			{
				_imageList = value;
				Invalidate();
			}
		}

		public Color LinkColor
		{
			get { return _linkColor; }
			set
			{
				_linkColor = value;
				Invalidate();
			}
		}

		public Color LinkColorHover
		{
			get { return _linkColorHover; }
			set
			{
				_linkColorHover = value;
				Invalidate();
			}
		}

		public bool LinkUnderLine
		{
			get { return _linkUnderLine; }
			set
			{
				_linkUnderLine = value;
				Invalidate();
			}
		}

		public bool LinkUnderLineHover
		{
			get { return _linkUnderLineHover; }
			set
			{
				_linkUnderLineHover = value;
				Invalidate();
			}
		}

		public bool AutoSizeHorizontal
		{
			get { return _autoSizeHorizontal; }
			set { _autoSizeHorizontal = value; }
		}

		public bool AutoSizeVertical
		{
			get { return _autoSizeVertical; }
			set { _autoSizeVertical = value; }
		}

		public bool WordWrap
		{
			get { return _wordWrap; }
			set
			{
				_wordWrap = value;
				CreateRows();
				Invalidate();
			}
		}

		public ScrollBars ScrollBars
		{
			get { return _scrollBars; }
			set
			{
				_scrollBars = value;
				InitScrollbars();
			}
		}

		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public override string Text
		{
			get { return _text; }
			set
			{
				try
				{
					_text = value;

					CreateAll();
					Invalidate();
				}
				catch (Exception x)
				{
					Console.WriteLine(x.Message);
					System.Diagnostics.Debugger.Break();
				}

				RedrawBuffer();
			}
		}
		#endregion

		#region Methods
		#region Protected
		protected void OnClickLink(string Link)
		{
			if (ClickLink != null)
				ClickLink(this, new ClickLinkEventArgs(Link));
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			SetAutoSize();

			if (_hasImageError)
				CreateAll();

			if (_bufferSurface != null)
				_bufferSurface.RenderToControl(0, 0);
		}

		protected override void OnResize(EventArgs e)
		{
			try
			{
				InitScrollbars();
				SetAutoSize();
			}
			catch
			{
			}

			CreateRows();
			base.OnResize(e);
		}

		protected override void OnSizeChanged(EventArgs e)
		{
			base.OnSizeChanged(e);
			if (IsHandleCreated)
				RedrawBuffer();
		}
		protected override void OnMouseUp(MouseEventArgs e)
		{
			int y = e.Y;
			int x = e.X;

			int index = 0;
			bool Link = false;
			_activeElement = null;
			if (_rows != null)
			{
				foreach (FormatLabelRow r in _rows)
				{
					if (y >= r.Top && y <= r.Top + r.Height)
					{
						foreach (FormatLabelWord w in r.Words)
						{
							if (y >= w.ScreenArea.Top && y <= w.ScreenArea.Bottom)
							{
								if (x >= w.ScreenArea.Left && x <= w.ScreenArea.Right)
								{
									if (w.Element.Link != null)
									{
										Link = true;
										_activeElement = w.Element.Link;
										break;
									}
								}
							}
						}

						break;
					}

					index++;
				}
			}
			if (Link)
			{
				Cursor = Cursors.Hand;
				Invalidate();
				OnClickLink(GetAttrib("href", _activeElement.Tag));
			}
			else
			{
				Cursor = Cursors.Arrow;
				Invalidate();
			}

			base.OnMouseUp(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			int y = e.Y;
			int x = e.X;

			int index = 0;
			bool Link = false;
			_activeElement = null;
			if (_rows != null)
			{
				foreach (FormatLabelRow r in _rows)
				{
					if (y >= r.Top && y <= r.Top + r.Height)
					{
						foreach (FormatLabelWord w in r.Words)
						{
							if (y >= w.ScreenArea.Top && y <= w.ScreenArea.Bottom)
							{
								if (x >= w.ScreenArea.Left && x <= w.ScreenArea.Right)
								{
									if (w.Element.Link != null)
									{
										Link = true;
										_activeElement = w.Element.Link;
										break;
									}
								}
							}
						}

						break;
					}

					index++;
				}
			}
			if (Link)
			{
				Cursor = Cursors.Hand;
				Invalidate();
			}
			else
			{
				Cursor = Cursors.Arrow;
				Invalidate();
			}

			base.OnMouseMove(e);
		}

		protected override void OnInvalidated(InvalidateEventArgs e)
		{
			if (IsHandleCreated)
				RedrawBuffer();

			base.OnInvalidated(e);
		}
		#endregion

		#region Private
		private void CreateAll()
		{
			_elements = CreateElements();
			ClearFonts();

			ApplyFormat(_elements);
			CreateWords(_elements);

			CreateRows();
			SetAutoSize();
		}

		private void ClearFonts()
		{
			foreach (GDIFont gf in _fonts.Values)
				gf.Dispose();

			_fonts.Clear();
		}

		private void SetAutoSize()
		{
			if (AutoSizeHorizontal)
				Width = GetWidth();

			if (AutoSizeVertical)
				Height = GetHeight();
		}

		private void RedrawBuffer()
        {
            if (_bufferSurface != null)
                _bufferSurface.Dispose();

            _bufferSurface = new GDISurface(Width, Height, this, true);
            using (Graphics gfx = Graphics.FromHdc(_bufferSurface.hDC))
            {
                _bufferSurface.FontTransparent = true;
                _bufferSurface.Clear(BackColor);

                int x = LabelMargin;
                int y = LabelMargin;

                for (int i = _vScroll.Value; i < _rows.Count; i++)
                {
                    FormatLabelRow r = (FormatLabelRow)_rows[i];
                    x = LabelMargin;
                    r.Visible = true;
                    r.Top = y;

                    if (r.RenderSeparator)
                    {
                        Color c1 = Color.FromArgb(120, 0, 0, 0);
                        Brush b1 = new SolidBrush(c1);
                        gfx.FillRectangle(b1, 0, y, Width, 1);

                        Color c2 = Color.FromArgb(120, 255, 255, 255);
                        Brush b2 = new SolidBrush(c2);
                        gfx.FillRectangle(b2, 0, y + 1, Width, 1);

                        b1.Dispose();
                        b2.Dispose();
                    }

                    foreach (FormatLabelWord w in r.Words)
                    {
                        int ypos = r.Height - w.Height + y;

                        if (w.Image != null)
                            gfx.DrawImage(w.Image, x, y);
                        else
                        {
                            GDIFont gf = null;
                            if (w.Element.Link != null)
                            {
                                Font f = null;

                                FontStyle fs = w.Element.Font.Style;
                                if (w.Element.Link == _activeElement)
                                {
                                    if (_linkUnderLineHover)
                                        fs |= FontStyle.Underline;

                                    f = new Font(w.Element.Font, fs);
                                }
                                else
                                {
                                    if (_linkUnderLine)
                                        fs |= FontStyle.Underline;

                                    f = new Font(w.Element.Font, fs);
                                }

                                gf = GetFont(f);
                            }
                            else
                            {
                                gf = GetFont(w.Element.Font);
                            }

                            _bufferSurface.Font = gf;
                            if (w.Element.Effect != TextEffect.None)
                            {
                                _bufferSurface.TextForeColor = w.Element.EffectColor;

                                if (w.Element.Effect == TextEffect.Outline)
                                {
                                    for (int xx = -1; xx <= 1; xx++)
                                        for (int yy = -1; yy <= 1; yy++)
                                            _bufferSurface.DrawTabbedString(w.Text, x + xx, ypos + yy, 0, 0);


                                }
                                else if (w.Element.Effect != TextEffect.None)
                                    _bufferSurface.DrawTabbedString(w.Text, x + 1, ypos + 1, 0, 0);
                            }


                            if (w.Element.Link != null)
                            {
                                if (w.Element.Link == _activeElement)
                                    _bufferSurface.TextForeColor = LinkColorHover;
                                else
                                    _bufferSurface.TextForeColor = LinkColor;
                            }
                            else
                                _bufferSurface.TextForeColor = w.Element.ForeColor;

                            _bufferSurface.TextBackColor = w.Element.BackColor;
                            _bufferSurface.DrawTabbedString(w.Text, x, ypos, 0, 0);
                        }

                        w.ScreenArea =new Rectangle(new Point(x, ypos), w.ScreenArea.Size);
                        x += w.Width;
                    }

                    y += r.Height + r.BottomPadd;
                    if (y > Height)
                        break;
                }
            }
		}

		private FormatLabelElement[] CreateElements()
		{
			string text = Text.Replace("\n", "");
			text = text.Replace("\r", "");

			string[] parts = text.Split('<');
			ArrayList Elements = new ArrayList();

			int i = 0;
			foreach (string part in parts)
			{
				FormatLabelElement cmd = new FormatLabelElement();

				if (i == 0)
					cmd.Text = part;
				else
				{
					string[] TagTextPair = part.Split('>');
					cmd.Tag = TagTextPair[0].ToLower();
					if (cmd.Tag.IndexOfAny(" \t".ToCharArray()) >= 0)
					{
						int ws = cmd.Tag.IndexOfAny(" \t".ToCharArray());
						string s1 = TagTextPair[0].Substring(0, ws).ToLower();
						string s2 = TagTextPair[0].Substring(ws + 1);
						cmd.Tag = s1 + " " + s2;
					}

					cmd.Text = TagTextPair[1];
					if (cmd.TagName == "img")
					{
						FormatLabelElement img = new FormatLabelElement();
						img.Tag = cmd.Tag;
						Elements.Add(img);
						cmd.Tag = "";			
					}

					cmd.Text = cmd.Text.Replace("\t", "     ");
					cmd.Text = cmd.Text.Replace("&#145;", "'");
					cmd.Text = cmd.Text.Replace("&#146;", "'");

					cmd.Text = cmd.Text.Replace(" ", ((char) 1).ToString());
					cmd.Text = HttpUtility.HtmlDecode(cmd.Text);
					cmd.Text = cmd.Text.Replace(((char) 1).ToString(), " ");
				}

				Elements.Add(cmd);
				i++;
			}

			FormatLabelElement[] res = new FormatLabelElement[Elements.Count];
			Elements.CopyTo(res);
			return res;
		}

		private string GetAttrib(string attrib, string tag)
		{
			try
			{
				if (tag.IndexOf(attrib) < 0)
					return "";

				tag = tag.Replace("\t", " ");

				int start = tag.IndexOf(attrib);
				int end = start + attrib.Length;
				int valuestart = tag.IndexOf("=", end);
				if (valuestart < 0)
					return "";

				valuestart++;

				string value = tag.Substring(valuestart);
				while (value.StartsWith(" "))
					value = value.Substring(1);

				if (value.StartsWith("\""))
				{
					value = value.Substring(1);

					int valueend = value.IndexOf("\"");
					value = value.Substring(0, valueend);
					return value;
				}
				else
				{
					int valueend = value.IndexOf(" ");
					if (valueend < 0)
						valueend = value.Length;

					value = value.Substring(0, valueend);
					return value;
				}
			}
			catch
			{
				return "";
			}
		}

		private void ApplyFormat(FormatLabelElement[] Elements)
		{
			Stack bold = new Stack();
			Stack italic = new Stack();
			Stack underline = new Stack();
			Stack forecolor = new Stack();
			Stack backcolor = new Stack();
			Stack fontsize = new Stack();
			Stack fontname = new Stack();
			Stack link = new Stack();
			Stack effectcolor = new Stack();
			Stack effect = new Stack();

			bold.Push(Font.Bold);
			italic.Push(Font.Italic);
			underline.Push(Font.Underline);
			forecolor.Push(ForeColor);
			backcolor.Push(Color.Transparent);
			fontsize.Push((int) (Font.Size*1.3));
			fontname.Push(Font.Name);
			effect.Push(TextEffect.None);
			effectcolor.Push(Color.Black);
			link.Push(null);

			foreach (FormatLabelElement Element in Elements)
			{
				switch (Element.TagName)
				{
					case "b":
						{
							bold.Push(true);
							break;
						}
					case "a":
						{
							link.Push(Element);
							break;
						}
					case "i":
					case "em":
						{
							italic.Push(true);
							break;
						}
					case "u":
						{
							underline.Push(true);
							break;
						}
					case "font":
						{
							string _fontname = GetAttrib("face", Element.Tag);
							string _size = GetAttrib("size", Element.Tag);
							string _color = GetAttrib("color", Element.Tag);
							string _effectcolor = GetAttrib("effectcolor", Element.Tag);
							string _effect = GetAttrib("effect", Element.Tag);

							if (_size == "")
								fontsize.Push(fontsize.Peek());
							else
								fontsize.Push(int.Parse(_size));

							if (_fontname == "")
								fontname.Push(fontname.Peek());
							else
								fontname.Push(_fontname);

							if (_color == "")
								forecolor.Push(forecolor.Peek());
							else
								forecolor.Push(Color.FromName(_color));

							if (_effectcolor == "")
								effectcolor.Push(effectcolor.Peek());
							else
								effectcolor.Push(Color.FromName(_effectcolor));

							if (_effect == "")
								effect.Push(effect.Peek());
							else
								effect.Push(Enum.Parse(typeof (TextEffect), _effect, true));

							break;

						}
					case "br":
						{
							Element.NewLine = true;
							break;
						}
					case "hr":
						{
							Element.NewLine = true;
							break;
						}
					case "h3":
						{
							fontsize.Push((int) (Font.Size*1.4));
							bold.Push(true);
							Element.NewLine = true;
							break;
						}
					case "h4":
						{
							fontsize.Push((int) (Font.Size*1.2));
							bold.Push(true);
							Element.NewLine = true;
							break;
						}
					case "/b":
						{
							bold.Pop();
							break;
						}
					case "/a":
						{
							link.Pop();
							break;
						}
					case "/i":
					case "/em":
						{
							italic.Pop();
							break;
						}
					case "/u":
						{
							underline.Pop();
							break;
						}
					case "/font":
						{
							fontname.Pop();
							fontsize.Pop();
							forecolor.Pop();
							effect.Pop();
							effectcolor.Pop();
							break;
						}
					case "/h3":
						{
							fontsize.Pop();
							bold.Pop();
							Element.NewLine = true;
							break;
						}
					case "/h4":
						{
							fontsize.Pop();
							bold.Pop();
							Element.NewLine = true;
							break;
						}

					default:
						{
							break;
						}
				}

				bool Bold = (bool) bold.Peek();
				bool Italic = (bool) italic.Peek();
				bool Underline = (bool) underline.Peek();

				FormatLabelElement Link = (FormatLabelElement) link.Peek();
				string FontName = (string) fontname.Peek();
				int FontSize = (int) fontsize.Peek();

				Color backColor = (Color) backcolor.Peek();
				Color foreColor = (Color) forecolor.Peek();
				TextEffect Effect = (TextEffect) effect.Peek();
				Color EffectColor = (Color) effectcolor.Peek();

				FontStyle fs = 0;
				if (Bold) fs |= FontStyle.Bold;
				if (Italic) fs |= FontStyle.Italic;
				if (Underline) fs |= FontStyle.Underline;

				Font font = new Font(FontName, FontSize, fs);
				Element.Font = font;
				Element.BackColor = backColor;
				Element.ForeColor = foreColor;
				Element.Link = Link;
				Element.Effect = Effect;
				Element.EffectColor = EffectColor;
			}
		}

		private bool IsIndex(string SRC)
		{
			try
			{
				int i = int.Parse(SRC);
				return true;
			}
			catch
			{
				return false;
			}
		}

		private void CreateWords(FormatLabelElement[] Elements)
		{
			GDISurface bbuff = new GDISurface(1, 1, this, false);

			_hasImageError = false;
			foreach (FormatLabelElement Element in Elements)
			{
				if (Element.TagName == "img")
				{
					Element.words = new FormatLabelWord[1];

					Element.words[0] = new FormatLabelWord();

					Image img = null;

					try
					{
						string SRC = GetAttrib("img", Element.Tag).ToLower();
						if (IsIndex(SRC))
						{
							int index = int.Parse(SRC);
							img = ImageList.Images[index];
						}
						else if (SRC.StartsWith("file://"))
							img = Image.FromFile(SRC.Substring(7));
						else
							img = Image.FromFile(SRC);
					}
					catch
					{
						img = new Bitmap(20, 20);
						_hasImageError = true;
					}

					Element.words[0].Image = img;


					Element.words[0].Element = Element;


					if (img != null)
					{
						Element.words[0].Height = img.Height;
						Element.words[0].Width = img.Width;
                        Element.words[0].ScreenArea = new Rectangle(Element.words[0].ScreenArea.Location,
                            new Size(img.Width, img.Height));
					}
				}
				else
				{
					string[] words = Element.Text.Split(' ');
					Element.words = new FormatLabelWord[words.Length];
					int i = 0;
					foreach (string word in words)
					{
						string tmp = "";

						Element.words[i] = new FormatLabelWord();
						Element.words[i].Element = Element;

						if (i == words.Length - 1)
						{
							Element.words[i].Text = word;
							tmp = word;
						}
						else
						{
							Element.words[i].Text = word + " ";
							tmp = word + " ";
						}

						bbuff.Font = GetFont(Element.Font);
						Size s = bbuff.MeasureTabbedString(tmp, 0);

						Element.words[i].Height = s.Height;
						Element.words[i].Width = s.Width - 0;
                        Element.words[i].ScreenArea = new Rectangle(Element.words[i].ScreenArea.Location, 
                            new Size(Element.words[i].Width, Element.words[i].Height));

						i++;
					}
				}
			}

			bbuff.Dispose();
		}

		private GDIFont GetFont(Font font)
		{
			GDIFont gf = (GDIFont) _fonts[GetFontKey(font)];
			if (gf == null)
			{
				gf = new GDIFont(font.Name, font.Size, font.Bold, font.Italic, font.Underline, false);
				_fonts[GetFontKey(font)] = gf;
			}

			return gf;
		}

		private string GetFontKey(Font font)
		{
			return font.Name + font.Bold.ToString() + 
							   font.Italic.ToString() + 
							   font.Underline.ToString() + 
							   font.Size.ToString();
		}


		private void CreateRows()
		{
			if (_elements != null)
			{
				int x = 0;
				_rows = new ArrayList();

				FormatLabelRow row = new FormatLabelRow();
				_rows.Add(row);
				bool WhiteSpace = false;
				foreach (FormatLabelElement Element in _elements)
				{
					if (Element.words == null)
						return;

					if (Element.NewLine)
					{
						x = 0;
						row = new FormatLabelRow();
						_rows.Add(row);
						WhiteSpace = true;
					}
					if (Element.TagName == "hr")
						row.RenderSeparator = true;

					foreach (FormatLabelWord word in Element.words)
					{
						if (WordWrap)
						{
							int scrollwdh = 0;
							if (ScrollBars == ScrollBars.Both || ScrollBars == ScrollBars.Vertical)
								scrollwdh = _vScroll.Width;

							if ((word.Width + x) > ClientWidth - LabelMargin - scrollwdh)
							{
								x = 0;
								row = new FormatLabelRow();
								_rows.Add(row);
								WhiteSpace = true;
							}
						}

						if (word.Text.Replace(" ", "") != "" || word.Image != null)
							WhiteSpace = false;

						if (!WhiteSpace)
						{
							row.Words.Add(word);

							x += word.Width;
						}
					}
				}

				int index = 0;
				foreach (FormatLabelRow r in _rows)
				{
					int width = 0;
					int height = 0;
					int padd = 0;

					if (index > 0)
					{
						int previndex = index - 1;
						FormatLabelRow prev = (FormatLabelRow) _rows[previndex];
						while (previndex >= 0 && prev.Words.Count == 0)
						{
							prev = (FormatLabelRow) _rows[previndex];
							previndex--;
						}

						if (previndex >= 0)
						{
							prev = (FormatLabelRow) _rows[previndex];
							if (prev.Words.Count > 0)
							{
								FormatLabelWord w = (FormatLabelWord) prev.Words[prev.Words.Count - 1];
								height = w.Height;
							}
						}

					}


					foreach (FormatLabelWord w in r.Words)
					{
						if (w.Height > height && (w.Text != ""))
							height = w.Height;

						width += w.Width;

					}
					r.Height = height;

					int MaxImageH = 0;
					foreach (FormatLabelWord w in r.Words)
					{
						if (w.Image != null)
						{
							if (w.Height > height)
								MaxImageH = w.Height;
						}
					}

					foreach (FormatLabelWord w in r.Words)
					{
						int imgH = 0;
						int imgPadd = 0;
						if (w.Image != null)
						{
							string valign = GetAttrib("valign", w.Element.Tag);
							switch (valign)
							{
								case "top":
									{
										imgH = r.Height;
										imgPadd = w.Height - imgH;
										break;
									}
								case "middle":
								case "center":
									{
										int tmp = 0;
										imgH = r.Height;
										tmp = (w.Height - imgH)/2;
										imgH += tmp;
										imgPadd = tmp;

										break;
									}
								case "bottom":
									{
										imgH = w.Height;
										imgPadd = 0;
										break;
									}
								default:
									{
										imgH = w.Height;
										imgPadd = 0;
										break;
									}

							}

							if (imgH > height)
								height = imgH;

							if (imgPadd > padd)
								padd = imgPadd;


							width += w.Width;
						}
					}
					r.Width = width;
					r.Height = height;
					r.BottomPadd = padd;
					index++;
				}

				_vScroll.Maximum = _rows.Count;
			}
		}

		private void InitScrollbars()
		{
			if (_vScroll == null || _hScroll == null)
				return;

			if (ScrollBars == ScrollBars.Both)
			{
				_vScroll.Left = ClientWidth - _vScroll.Width;
				_vScroll.Top = 0;
				_vScroll.Height = ClientHeight - _hScroll.Height;

				_hScroll.Left = 0;
				_hScroll.Top = ClientHeight - _hScroll.Height;
				_hScroll.Width = ClientWidth - _vScroll.Width;

				_filler.Left = _vScroll.Left;
				_filler.Top = _hScroll.Top;

				_filler.Visible = true;
				_vScroll.Visible = true;
				_hScroll.Visible = true;
			}
			else if (ScrollBars == ScrollBars.Vertical)
			{
				_vScroll.Left = ClientWidth - _vScroll.Width;
				_vScroll.Top = 0;
				_vScroll.Height = ClientHeight;

				_hScroll.Left = 0;
				_hScroll.Top = ClientHeight - _hScroll.Height;
				_hScroll.Width = ClientWidth - _vScroll.Width;

				_filler.Left = _vScroll.Left;
				_filler.Top = _hScroll.Top;

				_filler.Visible = false;
				_vScroll.Visible = true;
				_hScroll.Visible = false;

			}
			else if (ScrollBars == ScrollBars.Horizontal)
			{
				_vScroll.Left = ClientWidth - _vScroll.Width;
				_vScroll.Top = 0;
				_vScroll.Height = ClientHeight;

				_hScroll.Left = 0;
				_hScroll.Top = ClientHeight - _hScroll.Height;
				_hScroll.Width = ClientWidth;

				_filler.Left = _vScroll.Left;
				_filler.Top = _hScroll.Top;

				_filler.Visible = false;
				_vScroll.Visible = false;
				_hScroll.Visible = true;

			}
			else if (ScrollBars == ScrollBars.None)
			{
				_vScroll.Left = ClientWidth - _vScroll.Width;
				_vScroll.Top = 0;
				_vScroll.Height = ClientHeight;

				_hScroll.Left = 0;
				_hScroll.Top = ClientHeight - _hScroll.Height;
				_hScroll.Width = ClientWidth;

				_filler.Left = _vScroll.Left;
				_filler.Top = _hScroll.Top;

				_filler.Visible = false;
				_vScroll.Visible = false;
				_hScroll.Visible = false;
			}
		}

		private void vScroll_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e)
		{ Invalidate(); }
		#endregion

		#region Public
		public int GetWidth()
		{
			int max = 0;
			foreach (FormatLabelRow r in _rows)
				if (r.Width > max)
					max = r.Width;

			return max + LabelMargin * 2 + BorderWidth * 2;
		}

		public int GetHeight()
		{
			int max = 0;
			foreach (FormatLabelRow r in _rows)
				max += r.Height;

			return max + LabelMargin * 2 + BorderWidth * 2;
		}
		#endregion
		#endregion

		/// <summary>
		/// Initializes the FormatLabelControl.
		/// </summary>
		public FormatLabelControl()
		{
			_rows = new ArrayList();
			InitializeComponent();

			SetStyle(ControlStyles.ResizeRedraw, true);
			SetStyle(ControlStyles.Opaque, true);

			Text = Text;
			InitScrollbars();
		}

		/// <summary>
		/// Disposes the FormatLabelControl along with any resources being used.
		/// </summary>
		/// <param name="disposing">Whether the FormatLabelControl should dispose.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				foreach (GDIObject o in _fonts.Values)
					o.Dispose();

				if (components != null)
					components.Dispose();

				if (_bufferSurface != null)
					_bufferSurface.Dispose();
			}

			base.Dispose(disposing);
		}

		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			_filler = new System.Windows.Forms.PictureBox();
			_vScroll = new System.Windows.Forms.VScrollBar();
			_hScroll = new System.Windows.Forms.HScrollBar();
			SuspendLayout();
			// 
			// _filler
			// 
			_filler.BackColor = System.Drawing.SystemColors.Control;
			_filler.Cursor = System.Windows.Forms.Cursors.Default;
			_filler.Location = new System.Drawing.Point(136, 112);
			_filler.Name = "Filler";
			_filler.Size = new System.Drawing.Size(16, 16);
			_filler.TabIndex = 5;
			_filler.TabStop = false;
			// 
			// _vScroll
			// 
			_vScroll.Cursor = System.Windows.Forms.Cursors.Default;
			_vScroll.LargeChange = 2;
			_vScroll.Location = new System.Drawing.Point(136, -8);
			_vScroll.Name = "vScroll";
			_vScroll.Size = new System.Drawing.Size(16, 112);
			_vScroll.TabIndex = 4;
			_vScroll.Scroll += new System.Windows.Forms.ScrollEventHandler(vScroll_Scroll);
			// 
			// _hScroll
			// 
			_hScroll.Cursor = System.Windows.Forms.Cursors.Default;
			_hScroll.LargeChange = 1;
			_hScroll.Location = new System.Drawing.Point(0, 112);
			_hScroll.Maximum = 600;
			_hScroll.Name = "hScroll";
			_hScroll.Size = new System.Drawing.Size(128, 16);
			_hScroll.TabIndex = 3;
			// 
			// FormatLabelControl
			// 
			BackColor = System.Drawing.SystemColors.Window;
			Controls.AddRange(new System.Windows.Forms.Control[]
				{
					_filler,
					_vScroll,
					_hScroll
				});
			Name = "FormatLabelControl";
			Size = new System.Drawing.Size(160, 136);
			ResumeLayout(false);
		}
		#endregion
	}
}

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