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