External/Aga.Controls/Tree/TreeViewAdv.Draw.cs
author StephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433 090259cfd699
parent 345 0c551e8818e0
permissions -rw-r--r--
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
     1 using System;
     2 using System.Drawing;
     3 using System.Diagnostics;
     4 using System.Drawing.Drawing2D;
     5 using System.Windows.Forms;
     6 using Aga.Controls.Tree.NodeControls;
     7 
     8 namespace Aga.Controls.Tree
     9 {
    10 	public partial class TreeViewAdv
    11 	{
    12 		public void AutoSizeColumn(TreeColumn column)
    13 		{
    14 			if (!Columns.Contains(column))
    15 				throw new ArgumentException("column");
    16 
    17 			DrawContext context = new DrawContext();
    18 			context.Graphics = Graphics.FromImage(new Bitmap(1, 1));
    19 			context.Font = this.Font;
    20 			int res = 0;
    21 			for (int row = 0; row < RowCount; row++)
    22 			{
    23 				if (row < RowMap.Count)
    24 				{
    25 					int w = 0;
    26 					TreeNodeAdv node = RowMap[row];
    27 					foreach (NodeControl nc in NodeControls)
    28 					{
    29 						if (nc.ParentColumn == column)
    30 							w += nc.GetActualSize(node, _measureContext).Width;
    31 					}
    32 					res = Math.Max(res, w);
    33 				}
    34 			}
    35 
    36 			if (res > 0)
    37 				column.Width = res;
    38 		}
    39 
    40 		private void CreatePens()
    41 		{
    42 			CreateLinePen();
    43 			CreateMarkPen();
    44 		}
    45 
    46 		private void CreateMarkPen()
    47 		{
    48 			GraphicsPath path = new GraphicsPath();
    49 			path.AddLines(new Point[] { new Point(0, 0), new Point(1, 1), new Point(-1, 1), new Point(0, 0) });
    50 			CustomLineCap cap = new CustomLineCap(null, path);
    51 			cap.WidthScale = 1.0f;
    52 
    53 			_markPen = new Pen(_dragDropMarkColor, _dragDropMarkWidth);
    54 			_markPen.CustomStartCap = cap;
    55 			_markPen.CustomEndCap = cap;
    56 		}
    57 
    58 		private void CreateLinePen()
    59 		{
    60 			_linePen = new Pen(_lineColor);
    61 			_linePen.DashStyle = DashStyle.Dot;
    62 		}
    63 
    64         protected override void OnPaint(PaintEventArgs e)
    65         {
    66             BeginPerformanceCount();
    67 			PerformanceAnalyzer.Start("OnPaint");
    68 
    69             DrawContext context = new DrawContext();
    70             context.Graphics = e.Graphics;
    71             context.Font = this.Font;
    72             context.Enabled = Enabled;
    73 
    74             int y = 0;
    75             int gridHeight = 0;
    76 
    77             if (UseColumns)
    78             {
    79 				DrawColumnHeaders(e.Graphics);
    80 				y += ColumnHeaderHeight;
    81                 if (Columns.Count == 0 || e.ClipRectangle.Height <= y)
    82                     return;
    83             }
    84 
    85 			int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y;
    86             y -= firstRowY;
    87 
    88             e.Graphics.ResetTransform();
    89             e.Graphics.TranslateTransform(-OffsetX, y);
    90             Rectangle displayRect = DisplayRectangle;
    91             for (int row = FirstVisibleRow; row < RowCount; row++)
    92             {
    93                 Rectangle rowRect = _rowLayout.GetRowBounds(row);
    94                 gridHeight += rowRect.Height;
    95                 if (rowRect.Y + y > displayRect.Bottom)
    96                     break;
    97                 else
    98                     DrawRow(e, ref context, row, rowRect);
    99             }
   100 
   101 			if ((GridLineStyle & GridLineStyle.Vertical) == GridLineStyle.Vertical && UseColumns)
   102 				DrawVerticalGridLines(e.Graphics, firstRowY);
   103 
   104 			if (_dropPosition.Node != null && DragMode && HighlightDropPosition)
   105                 DrawDropMark(e.Graphics);
   106 
   107             e.Graphics.ResetTransform();
   108             DrawScrollBarsBox(e.Graphics);
   109 
   110             if (DragMode && _dragBitmap != null)
   111                 e.Graphics.DrawImage(_dragBitmap, PointToClient(MousePosition));
   112 
   113 			PerformanceAnalyzer.Finish("OnPaint");
   114 			EndPerformanceCount(e);
   115         }
   116 
   117 		private void DrawRow(PaintEventArgs e, ref DrawContext context, int row, Rectangle rowRect)
   118 		{
   119 			TreeNodeAdv node = RowMap[row];
   120 			context.DrawSelection = DrawSelectionMode.None;
   121 			context.CurrentEditorOwner = CurrentEditorOwner;
   122 			if (DragMode)
   123 			{
   124 				if ((_dropPosition.Node == node) && _dropPosition.Position == NodePosition.Inside && HighlightDropPosition)
   125 					context.DrawSelection = DrawSelectionMode.Active;
   126 			}
   127 			else
   128 			{
   129 				if (node.IsSelected && Focused)
   130 					context.DrawSelection = DrawSelectionMode.Active;
   131 				else if (node.IsSelected && !Focused && !HideSelection)
   132 					context.DrawSelection = DrawSelectionMode.Inactive;
   133 			}
   134 			context.DrawFocus = Focused && CurrentNode == node;
   135 			
   136 			OnRowDraw(e, node, context, row, rowRect);
   137 
   138 			if ((GridLineStyle & GridLineStyle.Horizontal) == GridLineStyle.Horizontal) {
   139 				e.Graphics.DrawLine(LightGrayPen, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);
   140       }
   141 
   142 			if (FullRowSelect)
   143 			{
   144 				context.DrawFocus = false;
   145 				if (context.DrawSelection == DrawSelectionMode.Active || context.DrawSelection == DrawSelectionMode.Inactive)
   146 				{
   147 					Rectangle focusRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
   148 					if (context.DrawSelection == DrawSelectionMode.Active)
   149 					{
   150 						e.Graphics.FillRectangle(GrayBrush, focusRect);
   151 						context.DrawSelection = DrawSelectionMode.FullRowSelect;
   152 					}
   153 					else
   154 					{
   155 						e.Graphics.FillRectangle(GrayBrush, focusRect);
   156 						context.DrawSelection = DrawSelectionMode.None;
   157 					}
   158 				}
   159 			}
   160 
   161 			if (ShowLines)
   162 				DrawLines(e.Graphics, node, rowRect);
   163 
   164 			DrawNode(node, context);
   165 		}
   166 
   167 		private Brush GrayBrush = new SolidBrush(Color.FromArgb(240, 240, 240));
   168 		private Pen LightGrayPen = new Pen(Color.FromArgb(247, 247, 247));
   169 
   170 		private void DrawVerticalGridLines(Graphics gr, int y)
   171 		{
   172 			int x = 0;
   173 			foreach (TreeColumn c in Columns)
   174 			{
   175 				if (c.IsVisible)
   176 				{
   177 					x += c.Width;
   178 					gr.DrawLine(SystemPens.InactiveBorder, x - 1, y, x - 1, gr.ClipBounds.Bottom);
   179 				}
   180 			}
   181 		}
   182 
   183 		private void DrawColumnHeaders(Graphics gr)
   184 		{
   185 			PerformanceAnalyzer.Start("DrawColumnHeaders");
   186 			ReorderColumnState reorder = Input as ReorderColumnState;
   187 			int x = 0;
   188 			TreeColumn.DrawBackground(gr, new Rectangle(0, 0, ClientRectangle.Width + 2, ColumnHeaderHeight - 1), false, false);
   189 			gr.TranslateTransform(-OffsetX, 0);
   190 			foreach (TreeColumn c in Columns)
   191 			{
   192 				if (c.IsVisible)
   193 				{
   194 					if (x >= OffsetX && x - OffsetX < this.Bounds.Width)// skip invisible columns
   195 					{
   196 						Rectangle rect = new Rectangle(x, 0, c.Width, ColumnHeaderHeight - 1);
   197 						gr.SetClip(rect);
   198 						bool pressed = ((Input is ClickColumnState || reorder != null) && ((Input as ColumnState).Column == c));
   199 						c.Draw(gr, rect, Font, pressed, _hotColumn == c);
   200 						gr.ResetClip();
   201 
   202 						if (reorder != null && reorder.DropColumn == c)
   203 							TreeColumn.DrawDropMark(gr, rect);
   204 					}
   205 					x += c.Width;
   206 				}
   207 			}
   208 
   209 			if (reorder != null)
   210 			{
   211 				if (reorder.DropColumn == null)
   212 					TreeColumn.DrawDropMark(gr, new Rectangle(x, 0, 0, ColumnHeaderHeight));
   213 				gr.DrawImage(reorder.GhostImage, new Point(reorder.Location.X +  + reorder.DragOffset, reorder.Location.Y));
   214 			}
   215 			PerformanceAnalyzer.Finish("DrawColumnHeaders");
   216 		}
   217 
   218 		public void DrawNode(TreeNodeAdv node, DrawContext context)
   219 		{
   220 			foreach (NodeControlInfo item in GetNodeControls(node))
   221 			{
   222 				if (item.Bounds.Right >= OffsetX && item.Bounds.X - OffsetX < this.Bounds.Width)// skip invisible nodes
   223 				{
   224 					context.Bounds = item.Bounds;
   225 					context.Graphics.SetClip(context.Bounds);
   226 					item.Control.Draw(node, context);
   227 					context.Graphics.ResetClip();
   228 				}
   229 			}
   230 		}
   231 
   232 		private void DrawScrollBarsBox(Graphics gr)
   233 		{
   234 			Rectangle r1 = DisplayRectangle;
   235 			Rectangle r2 = ClientRectangle;
   236 			gr.FillRectangle(SystemBrushes.Control,
   237 				new Rectangle(r1.Right, r1.Bottom, r2.Width - r1.Width, r2.Height - r1.Height));
   238 		}
   239 
   240 		private void DrawDropMark(Graphics gr)
   241 		{
   242 			if (_dropPosition.Position == NodePosition.Inside)
   243 				return;
   244 
   245 			Rectangle rect = GetNodeBounds(_dropPosition.Node);
   246 			int right = DisplayRectangle.Right - LeftMargin + OffsetX;
   247 			int y = rect.Y;
   248 			if (_dropPosition.Position == NodePosition.After)
   249 				y = rect.Bottom;
   250 			gr.DrawLine(_markPen, rect.X, y, right, y);
   251 		}
   252 
   253 		private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect)
   254 		{
   255 			if (UseColumns && Columns.Count > 0)
   256 				gr.SetClip(new Rectangle(0, rowRect.Y, Columns[0].Width, rowRect.Bottom));
   257 
   258 			TreeNodeAdv curNode = node;
   259 			while (curNode != _root && curNode != null)
   260 			{
   261 				int level = curNode.Level;
   262 				int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin;
   263 				int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2;
   264 				int y = rowRect.Y;
   265 				int y2 = y + rowRect.Height;
   266 
   267 				if (curNode == node)
   268 				{
   269 					int midy = y + rowRect.Height / 2;
   270 					gr.DrawLine(_linePen, x, midy, x + width, midy);
   271 					if (curNode.NextNode == null)
   272 						y2 = y + rowRect.Height / 2;
   273 				}
   274 
   275 				if (node.Row == 0)
   276 					y = rowRect.Height / 2;
   277 				if (curNode.NextNode != null || curNode == node)
   278 					gr.DrawLine(_linePen, x, y, x, y2);
   279 
   280 				curNode = curNode.Parent;
   281 			}
   282 
   283 			gr.ResetClip();
   284 		}
   285 
   286 		#region Performance
   287 
   288 		private double _totalTime;
   289 		private int _paintCount;
   290 
   291 		[Conditional("PERF_TEST")]
   292 		private void BeginPerformanceCount()
   293 		{
   294 			_paintCount++;
   295 			TimeCounter.Start();
   296 		}
   297 
   298 		[Conditional("PERF_TEST")]
   299 		private void EndPerformanceCount(PaintEventArgs e)
   300 		{
   301 			double time = TimeCounter.Finish();
   302 			_totalTime += time;
   303 			string debugText = string.Format("FPS {0:0.0}; Avg. FPS {1:0.0}",
   304 				1 / time, 1 / (_totalTime / _paintCount));
   305 			e.Graphics.FillRectangle(Brushes.White, new Rectangle(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20, 150, 20));
   306 			e.Graphics.DrawString(debugText, Control.DefaultFont, Brushes.Gray,
   307 				new PointF(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20));
   308 		}
   309 		#endregion
   310 
   311 	}
   312 }