External/Aga.Controls/Tree/TreeColumn.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using System.ComponentModel;
     5 using System.Windows.Forms;
     6 using System.Drawing;
     7 using System.Windows.Forms.VisualStyles;
     8 using System.Drawing.Imaging;
     9 
    10 namespace Aga.Controls.Tree
    11 {
    12 	[TypeConverter(typeof(TreeColumn.TreeColumnConverter)), DesignTimeVisible(false), ToolboxItem(false)]
    13 	public class TreeColumn : Component
    14 	{
    15 		private class TreeColumnConverter : ComponentConverter
    16 		{
    17 			public TreeColumnConverter()
    18 				: base(typeof(TreeColumn))
    19 			{
    20 			}
    21 
    22 			public override bool GetPropertiesSupported(ITypeDescriptorContext context)
    23 			{
    24 				return false;
    25 			}
    26 		}
    27 
    28 		private const int HeaderLeftMargin = 5;
    29         private const int HeaderRightMargin = 5;   
    30 		private const int SortOrderMarkMargin = 8;
    31 
    32         private TextFormatFlags _headerFlags;
    33         private TextFormatFlags _baseHeaderFlags = TextFormatFlags.NoPadding | 
    34                                                    TextFormatFlags.EndEllipsis |
    35                                                    TextFormatFlags.VerticalCenter |
    36 												TextFormatFlags.PreserveGraphicsTranslateTransform;
    37 
    38 		#region Properties
    39 
    40         private TreeColumnCollection _owner;
    41 		internal TreeColumnCollection Owner
    42 		{
    43 			get { return _owner; }
    44 			set { _owner = value; }
    45 		}
    46 
    47 		[Browsable(false)]
    48 		public int Index
    49 		{
    50 			get 
    51 			{
    52 				if (Owner != null)
    53 					return Owner.IndexOf(this);
    54 				else
    55 					return -1;
    56 			}
    57 		}
    58 
    59 		private string _header;
    60 		[Localizable(true)]
    61 		public string Header
    62 		{
    63 			get { return _header; }
    64 			set 
    65 			{ 
    66 				_header = value;
    67 				OnHeaderChanged();
    68 			}
    69 		}
    70 
    71 		private string _tooltipText;
    72 		[Localizable(true)]
    73 		public string TooltipText
    74 		{
    75 			get { return _tooltipText; }
    76 			set { _tooltipText = value; }
    77 		}
    78 
    79 		private int _width;
    80 		[DefaultValue(50), Localizable(true)]
    81 		public int Width
    82 		{
    83 			get
    84             {
    85                 return _width;
    86             }
    87 			set 
    88 			{
    89 				if (_width != value)
    90 				{
    91                     _width = Math.Max(MinColumnWidth, value);
    92                     if (_maxColumnWidth > 0)
    93                     {
    94                         _width = Math.Min(_width, MaxColumnWidth);
    95                     }
    96 					OnWidthChanged();
    97 				}
    98 			}
    99 		}
   100 
   101         private int _minColumnWidth;
   102         [DefaultValue(0)]
   103         public int MinColumnWidth
   104         {
   105             get { return _minColumnWidth; }
   106             set
   107             {
   108 				if (value < 0)
   109 					throw new ArgumentOutOfRangeException("value");
   110 
   111 				_minColumnWidth = value;
   112                 Width = Math.Max(value, Width);
   113             }
   114         }
   115 
   116         private int _maxColumnWidth;
   117         [DefaultValue(0)]
   118         public int MaxColumnWidth
   119         {
   120             get { return _maxColumnWidth; }
   121             set
   122             {
   123 				if (value < 0)
   124 					throw new ArgumentOutOfRangeException("value");
   125 
   126 				_maxColumnWidth = value;
   127 				if (value > 0)
   128 					Width = Math.Min(value, _width);
   129             }
   130         }
   131 
   132 		private bool _visible = true;
   133 		[DefaultValue(true)]
   134 		public bool IsVisible
   135 		{
   136 			get { return _visible; }
   137 			set 
   138 			{ 
   139 				_visible = value;
   140 				OnIsVisibleChanged();
   141 			}
   142 		}
   143 
   144 		private HorizontalAlignment _textAlign = HorizontalAlignment.Left;
   145 		[DefaultValue(HorizontalAlignment.Left)]
   146 		public HorizontalAlignment TextAlign
   147 		{
   148 			get { return _textAlign; }
   149 			set 
   150 			{
   151 				if (value != _textAlign)
   152 				{
   153 					_textAlign = value;
   154                     _headerFlags = _baseHeaderFlags | TextHelper.TranslateAligmentToFlag(value);
   155 					OnHeaderChanged();
   156 				}
   157 			}
   158 		}
   159 
   160         private bool _sortable = false;
   161         [DefaultValue(false)]
   162         public bool Sortable
   163         {
   164             get { return _sortable; }
   165             set { _sortable = value; }
   166         }
   167 
   168 		private SortOrder _sort_order = SortOrder.None;
   169 		public SortOrder SortOrder
   170 		{
   171 			get { return _sort_order; }
   172 			set
   173 			{
   174 				if (value == _sort_order)
   175 					return;
   176 				_sort_order = value;
   177 				OnSortOrderChanged();
   178 			}
   179 		}
   180 
   181 		public Size SortMarkSize
   182 		{
   183 			get
   184 			{
   185 				if (Application.RenderWithVisualStyles)
   186 					return new Size(9, 5);
   187 				else
   188 					return new Size(7, 4);
   189 			}
   190 		}
   191 		#endregion
   192 
   193 		public TreeColumn(): 
   194 			this(string.Empty, 50)
   195 		{
   196 		}
   197 
   198         public TreeColumn(string header, int width)
   199 		{
   200 			_header = header;
   201 			_width = width;
   202             _headerFlags = _baseHeaderFlags | TextFormatFlags.Left;
   203 		}
   204 
   205 		public override string ToString()
   206 		{
   207 			if (string.IsNullOrEmpty(Header))
   208 				return GetType().Name;
   209 			else
   210 				return Header;
   211 		}
   212 
   213 		protected override void Dispose(bool disposing)
   214 		{
   215 			base.Dispose(disposing);
   216 		}
   217 
   218 		#region Draw
   219 
   220 		private static VisualStyleRenderer _normalRenderer;
   221 		private static VisualStyleRenderer _pressedRenderer;
   222 		private static VisualStyleRenderer _hotRenderer;
   223 
   224 		private static void CreateRenderers()
   225 		{
   226 			if (Application.RenderWithVisualStyles && _normalRenderer == null)
   227 			{
   228 				_normalRenderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Normal);
   229 				_pressedRenderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Pressed);
   230 				_hotRenderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Hot);
   231 			}
   232 		}
   233 
   234 		internal Bitmap CreateGhostImage(Rectangle bounds, Font font)
   235 		{
   236 			Bitmap b = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
   237 			Graphics gr = Graphics.FromImage(b);
   238 			gr.FillRectangle(SystemBrushes.ControlDark, bounds);
   239 			DrawContent(gr, bounds, font);
   240 			BitmapHelper.SetAlphaChanelValue(b, 150);
   241 			return b;
   242 		}
   243 
   244 		internal void Draw(Graphics gr, Rectangle bounds, Font font, bool pressed, bool hot)
   245 		{
   246 			DrawBackground(gr, bounds, pressed, hot);
   247 			DrawContent(gr, bounds, font);
   248 		}
   249 
   250         private void DrawContent(Graphics gr, Rectangle bounds, Font font)
   251         {
   252             Rectangle innerBounds = new Rectangle(bounds.X + HeaderLeftMargin, bounds.Y,
   253                                    bounds.Width - HeaderLeftMargin - HeaderRightMargin,
   254                                    bounds.Height);
   255 
   256             if (SortOrder != SortOrder.None)
   257 				innerBounds.Width -= (SortMarkSize.Width + SortOrderMarkMargin);
   258 
   259             Size maxTextSize = TextRenderer.MeasureText(gr, Header, font, innerBounds.Size, TextFormatFlags.NoPadding);
   260 			Size textSize = TextRenderer.MeasureText(gr, Header, font, innerBounds.Size, _baseHeaderFlags);
   261 
   262             if (SortOrder != SortOrder.None)
   263             {
   264 				int tw = Math.Min(textSize.Width, innerBounds.Size.Width);
   265 
   266                 int x = 0;
   267                 if (TextAlign == HorizontalAlignment.Left)
   268 					x = innerBounds.X + tw + SortOrderMarkMargin;
   269                 else if (TextAlign == HorizontalAlignment.Right)
   270 					x = innerBounds.Right + SortOrderMarkMargin;
   271                 else
   272 					x = innerBounds.X + tw + (innerBounds.Width - tw) / 2 + SortOrderMarkMargin;
   273                 DrawSortMark(gr, bounds, x);
   274 			}
   275 
   276 			if (textSize.Width < maxTextSize.Width)
   277 				TextRenderer.DrawText(gr, Header, font, innerBounds, SystemColors.ControlText, _baseHeaderFlags | TextFormatFlags.Left);
   278             else
   279 				TextRenderer.DrawText(gr, Header, font, innerBounds, SystemColors.ControlText, _headerFlags);
   280         }
   281 
   282 		private void DrawSortMark(Graphics gr, Rectangle bounds, int x)
   283 		{
   284 			int y = bounds.Y + bounds.Height / 2 - 2;
   285 			x = Math.Max(x, bounds.X + SortOrderMarkMargin);
   286 
   287             int w2 = SortMarkSize.Width / 2;
   288             if (SortOrder == SortOrder.Ascending)
   289             {
   290                 Point[] points = new Point[] { new Point(x, y), new Point(x + SortMarkSize.Width, y), new Point(x + w2, y + SortMarkSize.Height) };
   291                 gr.FillPolygon(SystemBrushes.ControlDark, points);
   292             }
   293             else if (SortOrder == SortOrder.Descending)
   294             {
   295                 Point[] points = new Point[] { new Point(x - 1, y + SortMarkSize.Height), new Point(x + SortMarkSize.Width, y + SortMarkSize.Height), new Point(x + w2, y - 1) };
   296                 gr.FillPolygon(SystemBrushes.ControlDark, points);
   297             }
   298 		}
   299 
   300 		internal static void DrawDropMark(Graphics gr, Rectangle rect)
   301 		{
   302 			gr.FillRectangle(SystemBrushes.HotTrack, rect.X-1, rect.Y, 2, rect.Height);
   303 		}
   304 
   305 		internal static void DrawBackground(Graphics gr, Rectangle bounds, bool pressed, bool hot)
   306 		{
   307 			if (Application.RenderWithVisualStyles)
   308 			{
   309 				CreateRenderers();
   310 				if (pressed)
   311 					_pressedRenderer.DrawBackground(gr, bounds);
   312 				else if (hot)
   313 					_hotRenderer.DrawBackground(gr, bounds);
   314 				else
   315 					_normalRenderer.DrawBackground(gr, bounds);
   316 			}
   317 			else
   318 			{
   319 				gr.FillRectangle(SystemBrushes.Control, bounds);
   320 				Pen p1 = SystemPens.ControlLightLight;
   321 				Pen p2 = SystemPens.ControlDark;
   322 				Pen p3 = SystemPens.ControlDarkDark;
   323 				if (pressed)
   324 					gr.DrawRectangle(p2, bounds.X, bounds.Y, bounds.Width, bounds.Height);
   325 				else
   326 				{
   327 					gr.DrawLine(p1, bounds.X, bounds.Y, bounds.Right, bounds.Y);
   328 					gr.DrawLine(p3, bounds.X, bounds.Bottom, bounds.Right, bounds.Bottom);
   329 					gr.DrawLine(p3, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1);
   330 					gr.DrawLine(p1, bounds.Left, bounds.Y + 1, bounds.Left, bounds.Bottom - 2);
   331 					gr.DrawLine(p2, bounds.Right - 2, bounds.Y + 1, bounds.Right - 2, bounds.Bottom - 2);
   332 					gr.DrawLine(p2, bounds.X, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom - 1);
   333 				}
   334 			}
   335 		}
   336 
   337 		#endregion
   338 
   339 		#region Events
   340 
   341 		public event EventHandler HeaderChanged;
   342 		private void OnHeaderChanged()
   343 		{
   344 			if (HeaderChanged != null)
   345 				HeaderChanged(this, EventArgs.Empty);
   346 		}
   347 
   348 		public event EventHandler SortOrderChanged;
   349 		private void OnSortOrderChanged()
   350 		{
   351 			if (SortOrderChanged != null)
   352 				SortOrderChanged(this, EventArgs.Empty);
   353 		}
   354 
   355 		public event EventHandler IsVisibleChanged;
   356 		private void OnIsVisibleChanged()
   357 		{
   358 			if (IsVisibleChanged != null)
   359 				IsVisibleChanged(this, EventArgs.Empty);
   360 		}
   361 
   362 		public event EventHandler WidthChanged;
   363 		private void OnWidthChanged()
   364 		{
   365 			if (WidthChanged != null)
   366 				WidthChanged(this, EventArgs.Empty);
   367 		}
   368 
   369 		#endregion
   370 	}
   371 }