External/Aga.Controls/Tree/AutoRowHeightLayout.cs
author sl
Thu, 01 Jan 2015 23:35:49 +0100
changeset 405 5715aefd2bcc
permissions -rw-r--r--
SharpDisplay: Migrating to new robust client scheme.
     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 }