SharpDisplay: Migrating to new robust client scheme.
3 using System.Diagnostics;
4 using System.Drawing.Drawing2D;
5 using System.Windows.Forms;
6 using Aga.Controls.Tree.NodeControls;
8 namespace Aga.Controls.Tree
10 public partial class TreeViewAdv
12 public void AutoSizeColumn(TreeColumn column)
14 if (!Columns.Contains(column))
15 throw new ArgumentException("column");
17 DrawContext context = new DrawContext();
18 context.Graphics = Graphics.FromImage(new Bitmap(1, 1));
19 context.Font = this.Font;
21 for (int row = 0; row < RowCount; row++)
23 if (row < RowMap.Count)
26 TreeNodeAdv node = RowMap[row];
27 foreach (NodeControl nc in NodeControls)
29 if (nc.ParentColumn == column)
30 w += nc.GetActualSize(node, _measureContext).Width;
32 res = Math.Max(res, w);
40 private void CreatePens()
46 private void CreateMarkPen()
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;
53 _markPen = new Pen(_dragDropMarkColor, _dragDropMarkWidth);
54 _markPen.CustomStartCap = cap;
55 _markPen.CustomEndCap = cap;
58 private void CreateLinePen()
60 _linePen = new Pen(_lineColor);
61 _linePen.DashStyle = DashStyle.Dot;
64 protected override void OnPaint(PaintEventArgs e)
66 BeginPerformanceCount();
67 PerformanceAnalyzer.Start("OnPaint");
69 DrawContext context = new DrawContext();
70 context.Graphics = e.Graphics;
71 context.Font = this.Font;
72 context.Enabled = Enabled;
79 DrawColumnHeaders(e.Graphics);
80 y += ColumnHeaderHeight;
81 if (Columns.Count == 0 || e.ClipRectangle.Height <= y)
85 int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y;
88 e.Graphics.ResetTransform();
89 e.Graphics.TranslateTransform(-OffsetX, y);
90 Rectangle displayRect = DisplayRectangle;
91 for (int row = FirstVisibleRow; row < RowCount; row++)
93 Rectangle rowRect = _rowLayout.GetRowBounds(row);
94 gridHeight += rowRect.Height;
95 if (rowRect.Y + y > displayRect.Bottom)
98 DrawRow(e, ref context, row, rowRect);
101 if ((GridLineStyle & GridLineStyle.Vertical) == GridLineStyle.Vertical && UseColumns)
102 DrawVerticalGridLines(e.Graphics, firstRowY);
104 if (_dropPosition.Node != null && DragMode && HighlightDropPosition)
105 DrawDropMark(e.Graphics);
107 e.Graphics.ResetTransform();
108 DrawScrollBarsBox(e.Graphics);
110 if (DragMode && _dragBitmap != null)
111 e.Graphics.DrawImage(_dragBitmap, PointToClient(MousePosition));
113 PerformanceAnalyzer.Finish("OnPaint");
114 EndPerformanceCount(e);
117 private void DrawRow(PaintEventArgs e, ref DrawContext context, int row, Rectangle rowRect)
119 TreeNodeAdv node = RowMap[row];
120 context.DrawSelection = DrawSelectionMode.None;
121 context.CurrentEditorOwner = CurrentEditorOwner;
124 if ((_dropPosition.Node == node) && _dropPosition.Position == NodePosition.Inside && HighlightDropPosition)
125 context.DrawSelection = DrawSelectionMode.Active;
129 if (node.IsSelected && Focused)
130 context.DrawSelection = DrawSelectionMode.Active;
131 else if (node.IsSelected && !Focused && !HideSelection)
132 context.DrawSelection = DrawSelectionMode.Inactive;
134 context.DrawFocus = Focused && CurrentNode == node;
136 OnRowDraw(e, node, context, row, rowRect);
138 if ((GridLineStyle & GridLineStyle.Horizontal) == GridLineStyle.Horizontal) {
139 e.Graphics.DrawLine(LightGrayPen, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);
144 context.DrawFocus = false;
145 if (context.DrawSelection == DrawSelectionMode.Active || context.DrawSelection == DrawSelectionMode.Inactive)
147 Rectangle focusRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
148 if (context.DrawSelection == DrawSelectionMode.Active)
150 e.Graphics.FillRectangle(GrayBrush, focusRect);
151 context.DrawSelection = DrawSelectionMode.FullRowSelect;
155 e.Graphics.FillRectangle(GrayBrush, focusRect);
156 context.DrawSelection = DrawSelectionMode.None;
162 DrawLines(e.Graphics, node, rowRect);
164 DrawNode(node, context);
167 private Brush GrayBrush = new SolidBrush(Color.FromArgb(240, 240, 240));
168 private Pen LightGrayPen = new Pen(Color.FromArgb(247, 247, 247));
170 private void DrawVerticalGridLines(Graphics gr, int y)
173 foreach (TreeColumn c in Columns)
178 gr.DrawLine(SystemPens.InactiveBorder, x - 1, y, x - 1, gr.ClipBounds.Bottom);
183 private void DrawColumnHeaders(Graphics gr)
185 PerformanceAnalyzer.Start("DrawColumnHeaders");
186 ReorderColumnState reorder = Input as ReorderColumnState;
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)
194 if (x >= OffsetX && x - OffsetX < this.Bounds.Width)// skip invisible columns
196 Rectangle rect = new Rectangle(x, 0, c.Width, ColumnHeaderHeight - 1);
198 bool pressed = ((Input is ClickColumnState || reorder != null) && ((Input as ColumnState).Column == c));
199 c.Draw(gr, rect, Font, pressed, _hotColumn == c);
202 if (reorder != null && reorder.DropColumn == c)
203 TreeColumn.DrawDropMark(gr, rect);
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));
215 PerformanceAnalyzer.Finish("DrawColumnHeaders");
218 public void DrawNode(TreeNodeAdv node, DrawContext context)
220 foreach (NodeControlInfo item in GetNodeControls(node))
222 if (item.Bounds.Right >= OffsetX && item.Bounds.X - OffsetX < this.Bounds.Width)// skip invisible nodes
224 context.Bounds = item.Bounds;
225 context.Graphics.SetClip(context.Bounds);
226 item.Control.Draw(node, context);
227 context.Graphics.ResetClip();
232 private void DrawScrollBarsBox(Graphics gr)
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));
240 private void DrawDropMark(Graphics gr)
242 if (_dropPosition.Position == NodePosition.Inside)
245 Rectangle rect = GetNodeBounds(_dropPosition.Node);
246 int right = DisplayRectangle.Right - LeftMargin + OffsetX;
248 if (_dropPosition.Position == NodePosition.After)
250 gr.DrawLine(_markPen, rect.X, y, right, y);
253 private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect)
255 if (UseColumns && Columns.Count > 0)
256 gr.SetClip(new Rectangle(0, rowRect.Y, Columns[0].Width, rowRect.Bottom));
258 TreeNodeAdv curNode = node;
259 while (curNode != _root && curNode != null)
261 int level = curNode.Level;
262 int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin;
263 int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2;
265 int y2 = y + rowRect.Height;
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;
276 y = rowRect.Height / 2;
277 if (curNode.NextNode != null || curNode == node)
278 gr.DrawLine(_linePen, x, y, x, y2);
280 curNode = curNode.Parent;
288 private double _totalTime;
289 private int _paintCount;
291 [Conditional("PERF_TEST")]
292 private void BeginPerformanceCount()
298 [Conditional("PERF_TEST")]
299 private void EndPerformanceCount(PaintEventArgs e)
301 double time = TimeCounter.Finish();
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));