External/Aga.Controls/Tree/AutoRowHeightLayout.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.Drawing;
     5 using Aga.Controls.Tree.NodeControls;
     6 
     7 namespace Aga.Controls.Tree
     8 {
     9 	public class AutoRowHeightLayout: IRowLayout
    10 	{
    11 		private DrawContext _measureContext;
    12 		private TreeViewAdv _treeView;
    13 		private List<Rectangle> _rowCache;
    14 
    15 		public AutoRowHeightLayout(TreeViewAdv treeView, int rowHeight)
    16 		{
    17 			_rowCache = new List<Rectangle>();
    18 			_treeView = treeView;
    19 			PreferredRowHeight = rowHeight;
    20 			_measureContext = new DrawContext();
    21 			_measureContext.Graphics = Graphics.FromImage(new Bitmap(1, 1));
    22 		}
    23 
    24 		private int _rowHeight;
    25 		public int PreferredRowHeight
    26 		{
    27 			get { return _rowHeight; }
    28 			set { _rowHeight = value; }
    29 		}
    30 
    31 
    32 		public int PageRowCount
    33 		{
    34 			get 
    35 			{
    36 				if (_treeView.RowCount == 0)
    37 					return 0;
    38 				else
    39 				{
    40 					int pageHeight = _treeView.DisplayRectangle.Height - _treeView.ColumnHeaderHeight;
    41 					int y = 0;
    42 					for (int i = _treeView.RowCount - 1; i >= 0; i--)
    43 					{
    44 						y += GetRowHeight(i);
    45 						if (y > pageHeight)
    46 							return Math.Max(0, _treeView.RowCount - 1 - i);
    47 					}
    48 					return _treeView.RowCount;
    49 				}
    50 			}
    51 		}
    52 
    53 		public int CurrentPageSize
    54 		{
    55 			get
    56 			{
    57 				if (_treeView.RowCount == 0)
    58 					return 0;
    59 				else
    60 				{
    61 					int pageHeight = _treeView.DisplayRectangle.Height - _treeView.ColumnHeaderHeight;
    62 					int y = 0;
    63 					for (int i = _treeView.FirstVisibleRow; i < _treeView.RowCount; i++)
    64 					{
    65 						y += GetRowHeight(i);
    66 						if (y > pageHeight)
    67 							return Math.Max(0, i - _treeView.FirstVisibleRow);
    68 					}
    69 					return Math.Max(0, _treeView.RowCount - _treeView.FirstVisibleRow);
    70 				}
    71 			}
    72 		}
    73 
    74 		public Rectangle GetRowBounds(int rowNo)
    75 		{
    76 			if (rowNo >= _rowCache.Count)
    77 			{
    78 				int count = _rowCache.Count;
    79 				int y = count > 0 ? _rowCache[count - 1].Bottom : 0;
    80 				for (int i = count; i <= rowNo; i++)
    81 				{
    82 					int height = GetRowHeight(i);
    83 					_rowCache.Add(new Rectangle(0, y, 0, height));
    84 					y += height;
    85 				}
    86 				if (rowNo < _rowCache.Count - 1)
    87 					return Rectangle.Empty;
    88 			}
    89 			if (rowNo >= 0 && rowNo < _rowCache.Count)
    90 				return _rowCache[rowNo];
    91 			else
    92 				return Rectangle.Empty;
    93 		}
    94 
    95 		private int GetRowHeight(int rowNo)
    96 		{
    97 			if (rowNo < _treeView.RowMap.Count)
    98 			{
    99 				TreeNodeAdv node = _treeView.RowMap[rowNo];
   100 				if (node.Height == null)
   101 				{
   102 					int res = 0;
   103 					_measureContext.Font = _treeView.Font;
   104 					foreach (NodeControl nc in _treeView.NodeControls)
   105 					{
   106 						int h = nc.GetActualSize(node, _measureContext).Height;
   107 						if (h > res)
   108 							res = h;
   109 					}
   110 					node.Height = res;
   111 				}
   112 				return node.Height.Value;
   113 			}
   114 			else
   115 				return 0;
   116 		}
   117 
   118 		public int GetRowAt(Point point)
   119 		{
   120 			int py = point.Y - _treeView.ColumnHeaderHeight;
   121 			int y = 0;
   122 			for (int i = _treeView.FirstVisibleRow; i < _treeView.RowCount; i++)
   123 			{
   124 				int h = GetRowHeight(i);
   125 				if (py >= y && py < y + h)
   126 					return i;
   127 				else
   128 					y += h;
   129 			}
   130 			return -1;
   131 		}
   132 
   133 		public int GetFirstRow(int lastPageRow)
   134 		{
   135 			int pageHeight = _treeView.DisplayRectangle.Height - _treeView.ColumnHeaderHeight;
   136 			int y = 0;
   137 			for (int i = lastPageRow; i >= 0; i--)
   138 			{
   139 				y += GetRowHeight(i);
   140 				if (y > pageHeight)
   141 					return Math.Max(0, i + 1);
   142 			}
   143 			return 0;
   144 		}
   145 
   146 		public void ClearCache()
   147 		{
   148 			_rowCache.Clear();
   149 		}
   150 	}
   151 }