External/Aga.Controls/Tree/NodeControls/BaseTextControl.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 345 0c551e8818e0
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.Drawing;
     5 using System.Windows.Forms;
     6 using System.Reflection;
     7 using System.ComponentModel;
     8 
     9 namespace Aga.Controls.Tree.NodeControls
    10 {
    11 	public abstract class BaseTextControl : EditableControl
    12 	{
    13 		private TextFormatFlags _baseFormatFlags;
    14         private TextFormatFlags _formatFlags;
    15         private Pen _focusPen;
    16 		private StringFormat _format;
    17 
    18 		#region Properties
    19 
    20 		private Font _font = null;
    21 		public Font Font
    22 		{
    23 			get
    24 			{
    25 				if (_font == null)
    26 					return Control.DefaultFont;
    27 				else
    28 					return _font;
    29 			}
    30 			set
    31 			{
    32 				if (value == Control.DefaultFont)
    33 					_font = null;
    34 				else
    35 					_font = value;
    36 			}
    37 		}
    38 
    39 		protected bool ShouldSerializeFont()
    40 		{
    41 			return (_font != null);
    42 		}
    43 
    44 		private HorizontalAlignment _textAlign = HorizontalAlignment.Left;
    45 		[DefaultValue(HorizontalAlignment.Left)]
    46 		public HorizontalAlignment TextAlign
    47 		{
    48 			get { return _textAlign; }
    49 			set 
    50 			{ 
    51 				_textAlign = value;
    52 				SetFormatFlags();
    53 			}
    54 		}
    55 
    56 		private StringTrimming _trimming = StringTrimming.None;
    57 		[DefaultValue(StringTrimming.None)]
    58 		public StringTrimming Trimming
    59 		{
    60 			get { return _trimming; }
    61 			set 
    62 			{ 
    63 				_trimming = value;
    64 				SetFormatFlags();
    65 			}
    66 		}
    67 
    68 		private bool _displayHiddenContentInToolTip = true;
    69 		[DefaultValue(true)]
    70 		public bool DisplayHiddenContentInToolTip
    71 		{
    72 			get { return _displayHiddenContentInToolTip; }
    73 			set { _displayHiddenContentInToolTip = value; }
    74 		}
    75 
    76 		private bool _useCompatibleTextRendering = false;
    77 		[DefaultValue(false)]
    78 		public bool UseCompatibleTextRendering
    79 		{
    80 			get { return _useCompatibleTextRendering; }
    81 			set { _useCompatibleTextRendering = value; }
    82 		}
    83 
    84 		[DefaultValue(false)]
    85 		public bool TrimMultiLine
    86 		{
    87 			get;
    88 			set;
    89 		}
    90 
    91 		#endregion
    92 
    93 		protected BaseTextControl()
    94 		{
    95 			IncrementalSearchEnabled = true;
    96 			_focusPen = new Pen(Color.Black);
    97 			_focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
    98 
    99 			_format = new StringFormat(StringFormatFlags.LineLimit | StringFormatFlags.NoClip | StringFormatFlags.FitBlackBox | StringFormatFlags.MeasureTrailingSpaces);
   100 			_baseFormatFlags = TextFormatFlags.PreserveGraphicsClipping |
   101 						   TextFormatFlags.PreserveGraphicsTranslateTransform;
   102 			SetFormatFlags();
   103 			LeftMargin = 3;
   104 		}
   105 
   106 		private void SetFormatFlags()
   107 		{
   108 			_format.Alignment = TextHelper.TranslateAligment(TextAlign);
   109 			_format.Trimming = Trimming;
   110 
   111 			_formatFlags = _baseFormatFlags | TextHelper.TranslateAligmentToFlag(TextAlign)
   112 				| TextHelper.TranslateTrimmingToFlag(Trimming);
   113 		}
   114 
   115 		public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
   116 		{
   117 			return GetLabelSize(node, context);
   118 		}
   119 
   120 		protected Size GetLabelSize(TreeNodeAdv node, DrawContext context)
   121 		{
   122 			return GetLabelSize(node, context, GetLabel(node));
   123 		}
   124 
   125 		protected Size GetLabelSize(TreeNodeAdv node, DrawContext context, string label)
   126 		{
   127 			PerformanceAnalyzer.Start("GetLabelSize");
   128 			CheckThread();
   129 			Font font = GetDrawingFont(node, context, label);
   130 			Size s = Size.Empty;
   131 			if (UseCompatibleTextRendering)
   132 				s = TextRenderer.MeasureText(label, font);
   133 			else
   134 			{
   135 				SizeF sf = context.Graphics.MeasureString(label, font);
   136 				s = new Size((int)Math.Ceiling(sf.Width), (int)Math.Ceiling(sf.Height));
   137 			}
   138 			PerformanceAnalyzer.Finish("GetLabelSize");
   139 
   140 			if (!s.IsEmpty)
   141 				return s;
   142 			else
   143 				return new Size(10, Font.Height);
   144 		}
   145 
   146 		protected Font GetDrawingFont(TreeNodeAdv node, DrawContext context, string label)
   147 		{
   148 			Font font = context.Font;
   149 			if (DrawTextMustBeFired(node))
   150 			{
   151 				DrawEventArgs args = new DrawEventArgs(node, this, context, label);
   152 				args.Font = context.Font;
   153 				OnDrawText(args);
   154 				font = args.Font;
   155 			}
   156 			return font;
   157 		}
   158 
   159 		protected void SetEditControlProperties(Control control, TreeNodeAdv node)
   160 		{
   161 			string label = GetLabel(node);
   162 			DrawContext context = new DrawContext();
   163 			context.Font = control.Font;
   164 			control.Font = GetDrawingFont(node, context, label);
   165 		}
   166 
   167 		public override void Draw(TreeNodeAdv node, DrawContext context)
   168 		{
   169 			if (context.CurrentEditorOwner == this && node == Parent.CurrentNode)
   170 				return;
   171 
   172 			PerformanceAnalyzer.Start("BaseTextControl.Draw");
   173 			string label = GetLabel(node);
   174 			Rectangle bounds = GetBounds(node, context);
   175 			Rectangle focusRect = new Rectangle(bounds.X, context.Bounds.Y,	
   176 				bounds.Width, context.Bounds.Height);
   177 
   178 			Brush backgroundBrush;
   179 			Color textColor;
   180 			Font font;
   181 			CreateBrushes(node, context, label, out backgroundBrush, out textColor, out font, ref label);
   182 
   183 			if (backgroundBrush != null)
   184 				context.Graphics.FillRectangle(backgroundBrush, focusRect);
   185 			if (context.DrawFocus)
   186 			{
   187 				focusRect.Width--;
   188 				focusRect.Height--;
   189 				if (context.DrawSelection == DrawSelectionMode.None)
   190 					_focusPen.Color = SystemColors.ControlText;
   191 				else
   192 					_focusPen.Color = SystemColors.InactiveCaption;
   193 				context.Graphics.DrawRectangle(_focusPen, focusRect);
   194 			}
   195 			
   196 			PerformanceAnalyzer.Start("BaseTextControl.DrawText");
   197 			if (UseCompatibleTextRendering)
   198 				TextRenderer.DrawText(context.Graphics, label, font, bounds, textColor, _formatFlags);
   199 			else
   200 				context.Graphics.DrawString(label, font, GetFrush(textColor), bounds, _format);
   201 			PerformanceAnalyzer.Finish("BaseTextControl.DrawText");
   202 
   203 			PerformanceAnalyzer.Finish("BaseTextControl.Draw");
   204 		}
   205 
   206 		private static Dictionary<Color, Brush> _brushes = new Dictionary<Color,Brush>();
   207 		private static Brush GetFrush(Color color)
   208 		{
   209 			Brush br;
   210 			if (_brushes.ContainsKey(color))
   211 				br = _brushes[color];
   212 			else
   213 			{
   214 				br = new SolidBrush(color);
   215 				_brushes.Add(color, br);
   216 			}
   217 			return br;
   218 		}
   219 
   220 		private void CreateBrushes(TreeNodeAdv node, DrawContext context, string text, out Brush backgroundBrush, out Color textColor, out Font font, ref string label)
   221 		{
   222 			textColor = SystemColors.ControlText;
   223 			backgroundBrush = null;
   224 			font = context.Font;
   225 			if (context.DrawSelection == DrawSelectionMode.Active)
   226 			{
   227 				textColor = SystemColors.HighlightText;
   228                 backgroundBrush = SystemBrushes.Highlight;
   229 			}
   230 			else if (context.DrawSelection == DrawSelectionMode.Inactive)
   231 			{
   232 				textColor = SystemColors.ControlText;
   233                 backgroundBrush = SystemBrushes.InactiveBorder;
   234 			}
   235 			else if (context.DrawSelection == DrawSelectionMode.FullRowSelect)
   236 				textColor = SystemColors.ControlText;
   237 
   238 			if (!context.Enabled)
   239 				textColor = SystemColors.GrayText;
   240 
   241 			if (DrawTextMustBeFired(node))
   242 			{
   243 				DrawEventArgs args = new DrawEventArgs(node, this, context, text);
   244 				args.Text = label;
   245 				args.TextColor = textColor;
   246 				args.BackgroundBrush = backgroundBrush;
   247 				args.Font = font;
   248 
   249 				OnDrawText(args);
   250 
   251 				textColor = args.TextColor;
   252 				backgroundBrush = args.BackgroundBrush;
   253 				font = args.Font;
   254 				label = args.Text;
   255 			}
   256 		}
   257 
   258 		public string GetLabel(TreeNodeAdv node)
   259 		{
   260 			if (node != null && node.Tag != null)
   261 			{
   262 				object obj = GetValue(node);
   263 				if (obj != null)
   264 					return FormatLabel(obj);
   265 			}
   266 			return string.Empty;
   267 		}
   268 
   269 		protected virtual string FormatLabel(object obj)
   270 		{
   271 			var res = obj.ToString();
   272 			if (TrimMultiLine && res != null)
   273 			{
   274 				string[] parts = res.Split('\n');
   275 				if (parts.Length > 1)
   276 					return parts[0] + "...";
   277 			}
   278 			return res;
   279 		}
   280 
   281 		public void SetLabel(TreeNodeAdv node, string value)
   282 		{
   283 			SetValue(node, value);
   284 		}
   285 
   286 		protected override void Dispose(bool disposing)
   287 		{
   288 			base.Dispose(disposing);
   289 			if (disposing)
   290 			{
   291 				_focusPen.Dispose();
   292 				_format.Dispose();
   293 			}
   294 		}
   295 
   296 		/// <summary>
   297 		/// Fires when control is going to draw a text. Can be used to change text or back color
   298 		/// </summary>
   299 		public event EventHandler<DrawEventArgs> DrawText;
   300 		protected virtual void OnDrawText(DrawEventArgs args)
   301 		{
   302 			TreeViewAdv tree = args.Node.Tree;
   303 			if (tree != null)
   304 				tree.FireDrawControl(args);
   305 			if (DrawText != null)
   306 				DrawText(this, args);
   307 		}
   308 
   309 		protected virtual bool DrawTextMustBeFired(TreeNodeAdv node)
   310 		{
   311 			return DrawText != null || (node.Tree != null && node.Tree.DrawControlMustBeFired());
   312 		}
   313 	}
   314 }