External/Aga.Controls/Tree/TreeViewAdv.Draw.cs
author moel.mich
Sun, 27 May 2012 15:16:19 +0000
changeset 345 0c551e8818e0
child 346 f652ab1e06e2
permissions -rw-r--r--
Added the source code of Aga.Controls (TreeViewAdv for .Net) version 1.7.0.0.
     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 (FullRowSelect)
   139 			{
   140 				context.DrawFocus = false;
   141 				if (context.DrawSelection == DrawSelectionMode.Active || context.DrawSelection == DrawSelectionMode.Inactive)
   142 				{
   143 					Rectangle focusRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
   144 					if (context.DrawSelection == DrawSelectionMode.Active)
   145 					{
   146 						e.Graphics.FillRectangle(SystemBrushes.Highlight, focusRect);
   147 						context.DrawSelection = DrawSelectionMode.FullRowSelect;
   148 					}
   149 					else
   150 					{
   151 						e.Graphics.FillRectangle(SystemBrushes.InactiveBorder, focusRect);
   152 						context.DrawSelection = DrawSelectionMode.None;
   153 					}
   154 				}
   155 			}
   156 
   157             if ((GridLineStyle & GridLineStyle.Horizontal) == GridLineStyle.Horizontal)
   158 				e.Graphics.DrawLine(SystemPens.InactiveBorder, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);
   159 
   160 			if (ShowLines)
   161 				DrawLines(e.Graphics, node, rowRect);
   162 
   163 			DrawNode(node, context);
   164 		}
   165 
   166 		private void DrawVerticalGridLines(Graphics gr, int y)
   167 		{
   168 			int x = 0;
   169 			foreach (TreeColumn c in Columns)
   170 			{
   171 				if (c.IsVisible)
   172 				{
   173 					x += c.Width;
   174 					gr.DrawLine(SystemPens.InactiveBorder, x - 1, y, x - 1, gr.ClipBounds.Bottom);
   175 				}
   176 			}
   177 		}
   178 
   179 		private void DrawColumnHeaders(Graphics gr)
   180 		{
   181 			PerformanceAnalyzer.Start("DrawColumnHeaders");
   182 			ReorderColumnState reorder = Input as ReorderColumnState;
   183 			int x = 0;
   184 			TreeColumn.DrawBackground(gr, new Rectangle(0, 0, ClientRectangle.Width + 2, ColumnHeaderHeight - 1), false, false);
   185 			gr.TranslateTransform(-OffsetX, 0);
   186 			foreach (TreeColumn c in Columns)
   187 			{
   188 				if (c.IsVisible)
   189 				{
   190 					if (x >= OffsetX && x - OffsetX < this.Bounds.Width)// skip invisible columns
   191 					{
   192 						Rectangle rect = new Rectangle(x, 0, c.Width, ColumnHeaderHeight - 1);
   193 						gr.SetClip(rect);
   194 						bool pressed = ((Input is ClickColumnState || reorder != null) && ((Input as ColumnState).Column == c));
   195 						c.Draw(gr, rect, Font, pressed, _hotColumn == c);
   196 						gr.ResetClip();
   197 
   198 						if (reorder != null && reorder.DropColumn == c)
   199 							TreeColumn.DrawDropMark(gr, rect);
   200 					}
   201 					x += c.Width;
   202 				}
   203 			}
   204 
   205 			if (reorder != null)
   206 			{
   207 				if (reorder.DropColumn == null)
   208 					TreeColumn.DrawDropMark(gr, new Rectangle(x, 0, 0, ColumnHeaderHeight));
   209 				gr.DrawImage(reorder.GhostImage, new Point(reorder.Location.X +  + reorder.DragOffset, reorder.Location.Y));
   210 			}
   211 			PerformanceAnalyzer.Finish("DrawColumnHeaders");
   212 		}
   213 
   214 		public void DrawNode(TreeNodeAdv node, DrawContext context)
   215 		{
   216 			foreach (NodeControlInfo item in GetNodeControls(node))
   217 			{
   218 				if (item.Bounds.Right >= OffsetX && item.Bounds.X - OffsetX < this.Bounds.Width)// skip invisible nodes
   219 				{
   220 					context.Bounds = item.Bounds;
   221 					context.Graphics.SetClip(context.Bounds);
   222 					item.Control.Draw(node, context);
   223 					context.Graphics.ResetClip();
   224 				}
   225 			}
   226 		}
   227 
   228 		private void DrawScrollBarsBox(Graphics gr)
   229 		{
   230 			Rectangle r1 = DisplayRectangle;
   231 			Rectangle r2 = ClientRectangle;
   232 			gr.FillRectangle(SystemBrushes.Control,
   233 				new Rectangle(r1.Right, r1.Bottom, r2.Width - r1.Width, r2.Height - r1.Height));
   234 		}
   235 
   236 		private void DrawDropMark(Graphics gr)
   237 		{
   238 			if (_dropPosition.Position == NodePosition.Inside)
   239 				return;
   240 
   241 			Rectangle rect = GetNodeBounds(_dropPosition.Node);
   242 			int right = DisplayRectangle.Right - LeftMargin + OffsetX;
   243 			int y = rect.Y;
   244 			if (_dropPosition.Position == NodePosition.After)
   245 				y = rect.Bottom;
   246 			gr.DrawLine(_markPen, rect.X, y, right, y);
   247 		}
   248 
   249 		private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect)
   250 		{
   251 			if (UseColumns && Columns.Count > 0)
   252 				gr.SetClip(new Rectangle(0, rowRect.Y, Columns[0].Width, rowRect.Bottom));
   253 
   254 			TreeNodeAdv curNode = node;
   255 			while (curNode != _root && curNode != null)
   256 			{
   257 				int level = curNode.Level;
   258 				int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin;
   259 				int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2;
   260 				int y = rowRect.Y;
   261 				int y2 = y + rowRect.Height;
   262 
   263 				if (curNode == node)
   264 				{
   265 					int midy = y + rowRect.Height / 2;
   266 					gr.DrawLine(_linePen, x, midy, x + width, midy);
   267 					if (curNode.NextNode == null)
   268 						y2 = y + rowRect.Height / 2;
   269 				}
   270 
   271 				if (node.Row == 0)
   272 					y = rowRect.Height / 2;
   273 				if (curNode.NextNode != null || curNode == node)
   274 					gr.DrawLine(_linePen, x, y, x, y2);
   275 
   276 				curNode = curNode.Parent;
   277 			}
   278 
   279 			gr.ResetClip();
   280 		}
   281 
   282 		#region Performance
   283 
   284 		private double _totalTime;
   285 		private int _paintCount;
   286 
   287 		[Conditional("PERF_TEST")]
   288 		private void BeginPerformanceCount()
   289 		{
   290 			_paintCount++;
   291 			TimeCounter.Start();
   292 		}
   293 
   294 		[Conditional("PERF_TEST")]
   295 		private void EndPerformanceCount(PaintEventArgs e)
   296 		{
   297 			double time = TimeCounter.Finish();
   298 			_totalTime += time;
   299 			string debugText = string.Format("FPS {0:0.0}; Avg. FPS {1:0.0}",
   300 				1 / time, 1 / (_totalTime / _paintCount));
   301 			e.Graphics.FillRectangle(Brushes.White, new Rectangle(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20, 150, 20));
   302 			e.Graphics.DrawString(debugText, Control.DefaultFont, Brushes.Gray,
   303 				new PointF(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20));
   304 		}
   305 		#endregion
   306 
   307 	}
   308 }