using System;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using DevComponents.DotNetBar;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
namespace DevComponents.AdvTree
{
internal class ColumnHeaderControl : Control
{
#region Constructor
///
/// Initializes a new instance of the ColumnHeaderControl class.
///
public ColumnHeaderControl()
{
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.Opaque, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.Selectable, false);
this.SetStyle(ControlStyles.StandardDoubleClick | ControlStyles.StandardClick, true);
}
#endregion
#region Internal Implementation
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
DisplayHelp.FillRectangle(g, this.ClientRectangle, this.BackColor);
if (_Columns == null)
{
return;
}
AdvTree tree = GetTree();
if (tree != null)
{
SmoothingMode sm = g.SmoothingMode;
TextRenderingHint th = g.TextRenderingHint;
if (tree.AntiAlias)
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
}
//Creates the drawing matrix with the right zoom;
if (tree.Zoom != 1)
{
System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix(tree.Zoom);
//use it for drawing
g.Transform = mx;
}
tree.NodeDisplay.PaintColumnHeaders(_Columns, g, true);
int columnMoveMarkerIndex = _ColumnMoveMarkerIndex;
if (columnMoveMarkerIndex >= 0)
DevComponents.AdvTree.Display.ColumnHeaderDisplay.PaintColumnMoveMarker(g, tree, columnMoveMarkerIndex, _Columns);
if (tree.AntiAlias)
{
g.SmoothingMode = sm;
g.TextRenderingHint = th;
}
}
base.OnPaint(e);
}
private int _ColumnMoveMarkerIndex = -1;
///
/// Gets or sets the column move marker that marks insertion point for column that is dragged. Marker is drawn before the column specified by this index.
///
internal int ColumnMoveMarkerIndex
{
get { return _ColumnMoveMarkerIndex; }
set
{
_ColumnMoveMarkerIndex = value;
this.Invalidate();
}
}
///
/// Returns mouse position which is translated if control Zoom is not equal 1
///
/// X coordinate
/// Y coordinate
///
private Point GetLayoutPosition(float zoom, int x, int y)
{
if (zoom == 1)
return new Point(x, y);
Point[] p = new Point[] { new Point(x, y) };
using (System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix(zoom))
{
mx.Invert();
mx.TransformPoints(p);
}
return p[0];
}
private System.Drawing.Drawing2D.Matrix GetTranslationMatrix(float zoom)
{
System.Drawing.Drawing2D.Matrix mx = new System.Drawing.Drawing2D.Matrix(zoom, 0, 0, zoom, 0, 0);
return mx;
}
private AdvTree GetTree()
{
return this.Parent as AdvTree;
}
private ColumnHeaderCollection _Columns = null;
///
/// Gets or sets the column header collection to be rendered.
///
public ColumnHeaderCollection Columns
{
get { return _Columns; }
set { _Columns = value; }
}
private Cursor _OldCursor = null;
private ColumnHeader _MouseOverColumnHeader = null;
protected override void OnMouseMove(MouseEventArgs e)
{
AdvTree tree = GetTree();
Point p = GetLayoutPosition(tree.Zoom, e.X, e.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (_MouseOverColumnHeader != ch)
{
if (_MouseOverColumnHeader != null)
_MouseOverColumnHeader.InternalMouseLeave(e);
_MouseOverColumnHeader = ch;
if (_MouseOverColumnHeader != null)
{
_MouseOverColumnHeader.InternalMouseEnter(e);
Interop.WinApi.ResetHover(this);
}
}
if (ch != null)
{
ch.InternalMouseMove(e);
}
if (e.Button == MouseButtons.Left && _MouseDownHeader != null && tree.AllowUserToReorderColumns && (Math.Abs(_MouseDownPoint.X-e.X)>1))
{
tree.StartColumnReorder(p.X, p.Y);
return;
}
if (tree == null || e.Button != MouseButtons.None || !tree.AllowUserToResizeColumns) return;
if (tree.CanResizeColumnAt(p.X, p.Y))
{
if (_OldCursor == null)
{
_OldCursor = this.Cursor;
this.Cursor = Cursors.VSplit;
}
}
else
{
ReleaseCursor();
}
base.OnMouseMove(e);
}
ColumnHeader _MouseDownHeader = null;
private Point _MouseDownPoint = Point.Empty;
protected override void OnMouseDown(MouseEventArgs e)
{
AdvTree tree = GetTree();
Point p = Point.Empty;
bool canResize = false;
_MouseDownPoint = e.Location;
if (tree != null)
{
p = GetLayoutPosition(tree.Zoom, e.X, e.Y);
}
if (tree != null && tree.AllowUserToResizeColumns && e.Button == MouseButtons.Left)
canResize = tree.CanResizeColumnAt(p.X, p.Y);
if (tree != null)
{
p = GetLayoutPosition(tree.Zoom, e.X, e.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
_MouseDownHeader = ch;
if (!canResize)
ch.OnMouseDown(e);
}
}
if (tree == null || e.Button != MouseButtons.Left || !tree.AllowUserToResizeColumns) return;
if (canResize)
{
tree.StartColumnResize(p.X, p.Y);
}
this.Invalidate();
base.OnMouseDown(e);
}
protected override void OnMouseHover(EventArgs e)
{
if (Control.MouseButtons == MouseButtons.None)
{
AdvTree tree = GetTree();
Point p = this.PointToClient(Control.MousePosition);
p = GetLayoutPosition(tree.Zoom, p.X, p.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
ch.InternalMouseHover(e);
}
}
base.OnMouseHover(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
ReleaseCursor();
_MouseDownPoint = Point.Empty;
if (_MouseDownHeader!=null)
{
_MouseDownHeader.OnMouseUp(e);
_MouseDownHeader = null;
}
this.Invalidate();
base.OnMouseUp(e);
}
protected override void OnClick(EventArgs e)
{
AdvTree tree = GetTree();
Point p = Point.Empty;
if (tree != null)
{
Point tp = tree.PointToClient(Control.MousePosition);
p = GetLayoutPosition(tree.Zoom, tp.X, tp.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
ch.OnClick(e);
}
}
this.Invalidate();
base.OnClick(e);
}
internal DateTime IgnoreDoubleClickTime = DateTime.MinValue;
protected override void OnDoubleClick(EventArgs e)
{
AdvTree tree = GetTree();
Point p = Point.Empty;
if (tree != null)
{
Point tp = tree.PointToClient(Control.MousePosition);
p = GetLayoutPosition(tree.Zoom, tp.X, tp.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
DateTime now = DateTime.Now;
if (IgnoreDoubleClickTime != DateTime.MinValue && now.Subtract(IgnoreDoubleClickTime).TotalMilliseconds <= SystemInformation.DoubleClickTime)
{
IgnoreDoubleClickTime = DateTime.MinValue;
return;
}
IgnoreDoubleClickTime = DateTime.MinValue;
ch.OnDoubleClick(e);
}
}
this.Invalidate();
base.OnDoubleClick(e);
}
private void ReleaseCursor()
{
if (_OldCursor != null)
{
this.Cursor = _OldCursor;
_OldCursor = null;
}
}
protected override void OnMouseLeave(EventArgs e)
{
if (_MouseOverColumnHeader != null)
{
_MouseOverColumnHeader.InternalMouseLeave(e);
_MouseOverColumnHeader = null;
}
if (Control.MouseButtons != MouseButtons.Left)
ReleaseCursor();
base.OnMouseLeave(e);
}
#endregion
}
}