External/Aga.Controls/Tree/TreeViewAdv.Input.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.Windows.Forms;
     5 using System.Drawing;
     6 using Aga.Controls.Tree.NodeControls;
     7 using System.Drawing.Imaging;
     8 using System.Threading;
     9 
    10 namespace Aga.Controls.Tree
    11 {
    12 	public partial class TreeViewAdv
    13 	{
    14 		#region Keys
    15 
    16 		protected override bool IsInputChar(char charCode)
    17 		{
    18 			return true;
    19 		}
    20 
    21 		protected override bool IsInputKey(Keys keyData)
    22 		{
    23 			if (((keyData & Keys.Up) == Keys.Up)
    24 				|| ((keyData & Keys.Down) == Keys.Down)
    25 				|| ((keyData & Keys.Left) == Keys.Left)
    26 				|| ((keyData & Keys.Right) == Keys.Right))
    27 				return true;
    28 			else
    29 				return base.IsInputKey(keyData);
    30 		}
    31 
    32 		internal void ChangeInput()
    33 		{
    34 			if ((ModifierKeys & Keys.Shift) == Keys.Shift)
    35 			{
    36 				if (!(Input is InputWithShift))
    37 					Input = new InputWithShift(this);
    38 			}
    39 			else if ((ModifierKeys & Keys.Control) == Keys.Control)
    40 			{
    41 				if (!(Input is InputWithControl))
    42 					Input = new InputWithControl(this);
    43 			}
    44 			else
    45 			{
    46 				if (!(Input.GetType() == typeof(NormalInputState)))
    47 					Input = new NormalInputState(this);
    48 			}
    49 		}
    50 
    51 		protected override void OnKeyDown(KeyEventArgs e)
    52 		{
    53 			base.OnKeyDown(e);
    54 			if (!e.Handled)
    55 			{
    56 				if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey)
    57 					ChangeInput();
    58 				Input.KeyDown(e);
    59 				if (!e.Handled)
    60 				{
    61 					foreach (NodeControlInfo item in GetNodeControls(CurrentNode))
    62 					{
    63 						item.Control.KeyDown(e);
    64 						if (e.Handled)
    65 							break;
    66 					}
    67 				}
    68 			}
    69 		}
    70 
    71 		protected override void OnKeyUp(KeyEventArgs e)
    72 		{
    73 			base.OnKeyUp(e);
    74 			if (!e.Handled)
    75 			{
    76 				if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey)
    77 					ChangeInput();
    78 				if (!e.Handled)
    79 				{
    80 					foreach (NodeControlInfo item in GetNodeControls(CurrentNode))
    81 					{
    82 						item.Control.KeyUp(e);
    83 						if (e.Handled)
    84 							return;
    85 					}
    86 				}
    87 			}
    88 		}
    89 
    90 		protected override void OnKeyPress(KeyPressEventArgs e)
    91 		{
    92 			base.OnKeyPress(e);
    93 			if (!e.Handled)
    94 				_search.Search(e.KeyChar);
    95 		}
    96 
    97 		#endregion
    98 
    99 		#region Mouse
   100 
   101 		private TreeNodeAdvMouseEventArgs CreateMouseArgs(MouseEventArgs e)
   102 		{
   103 			TreeNodeAdvMouseEventArgs args = new TreeNodeAdvMouseEventArgs(e);
   104 			args.ViewLocation = new Point(e.X + OffsetX,
   105 				e.Y + _rowLayout.GetRowBounds(FirstVisibleRow).Y - ColumnHeaderHeight);
   106 			args.ModifierKeys = ModifierKeys;
   107 			args.Node = GetNodeAt(e.Location);
   108 			NodeControlInfo info = GetNodeControlInfoAt(args.Node, e.Location);
   109 			args.ControlBounds = info.Bounds;
   110 			args.Control = info.Control;
   111 			return args;
   112 		}
   113 
   114 		protected override void OnMouseWheel(MouseEventArgs e)
   115 		{
   116 			_search.EndSearch();
   117 			if (SystemInformation.MouseWheelScrollLines > 0)
   118 			{
   119 				int lines = e.Delta / 120 * SystemInformation.MouseWheelScrollLines;
   120 				int newValue = _vScrollBar.Value - lines;
   121 				newValue = Math.Min(_vScrollBar.Maximum - _vScrollBar.LargeChange + 1, newValue);
   122 				newValue = Math.Min(_vScrollBar.Maximum, newValue);
   123 				_vScrollBar.Value = Math.Max(_vScrollBar.Minimum, newValue);
   124 			}
   125 			base.OnMouseWheel(e);
   126 		}
   127 
   128 		protected override void OnMouseDown(MouseEventArgs e)
   129 		{
   130 			if (CurrentEditorOwner != null)
   131 			{
   132 				CurrentEditorOwner.EndEdit(true);
   133 				return;
   134 			}
   135 
   136 			if (!Focused)
   137 				Focus();
   138 
   139 			_search.EndSearch();
   140 			if (e.Button == MouseButtons.Left)
   141 			{
   142 				TreeColumn c;
   143 				c = GetColumnDividerAt(e.Location);
   144 				if (c != null)
   145 				{
   146 					Input = new ResizeColumnState(this, c, e.Location);
   147 					return;
   148 				}
   149 				c = GetColumnAt(e.Location);
   150 				if (c != null)
   151 				{
   152 					Input = new ClickColumnState(this, c, e.Location);
   153 					UpdateView();
   154 					return;
   155 				}
   156 			}
   157 
   158 			ChangeInput();
   159 			TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
   160 
   161 			if (args.Node != null && args.Control != null)
   162 				args.Control.MouseDown(args);
   163 
   164 			if (!args.Handled)
   165 				Input.MouseDown(args);
   166 
   167 			base.OnMouseDown(e);
   168 		}
   169 
   170 		protected override void OnMouseClick(MouseEventArgs e)
   171 		{
   172 			//TODO: Disable when click on plusminus icon
   173 			TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
   174 			if (args.Node != null)
   175 				OnNodeMouseClick(args);
   176 
   177 			base.OnMouseClick(e);
   178 		}
   179 
   180 		protected override void OnMouseDoubleClick(MouseEventArgs e)
   181 		{
   182 			TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
   183 
   184 			if (args.Node != null && args.Control != null)
   185 				args.Control.MouseDoubleClick(args);
   186 
   187 			if (!args.Handled)
   188 			{
   189 				if (args.Node != null)
   190 					OnNodeMouseDoubleClick(args);
   191 				else
   192 					Input.MouseDoubleClick(args);
   193 
   194 				if (!args.Handled)
   195 				{
   196 					if (args.Node != null && args.Button == MouseButtons.Left)
   197 						args.Node.IsExpanded = !args.Node.IsExpanded;
   198 				}
   199 			}
   200 
   201 			base.OnMouseDoubleClick(e);
   202 		}
   203 
   204 		protected override void OnMouseUp(MouseEventArgs e)
   205 		{
   206 			TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
   207 			if (Input is ResizeColumnState)
   208 				Input.MouseUp(args);
   209 			else
   210 			{
   211 				if (args.Node != null && args.Control != null)
   212 					args.Control.MouseUp(args);
   213 				if (!args.Handled)
   214 					Input.MouseUp(args);
   215 
   216 				base.OnMouseUp(e);
   217 			}
   218 		}
   219 
   220 		protected override void OnMouseMove(MouseEventArgs e)
   221 		{
   222 			if (Input.MouseMove(e))
   223 				return;
   224 
   225 			base.OnMouseMove(e);
   226 			SetCursor(e);
   227 			UpdateToolTip(e);
   228 			if (ItemDragMode && Dist(e.Location, ItemDragStart) > ItemDragSensivity
   229 				&& CurrentNode != null && CurrentNode.IsSelected)
   230 			{
   231 				ItemDragMode = false;
   232 				_toolTip.Active = false;
   233 				OnItemDrag(e.Button, Selection.ToArray());
   234 			}
   235 		}
   236 
   237 		protected override void OnMouseLeave(EventArgs e)
   238 		{
   239 			_hotColumn = null;
   240 			UpdateHeaders();
   241 			base.OnMouseLeave(e);
   242 		}
   243 
   244 		private void SetCursor(MouseEventArgs e)
   245 		{
   246 			TreeColumn col;
   247 			col = GetColumnDividerAt(e.Location);
   248 			if (col == null)
   249 				_innerCursor = null;
   250 			else
   251 			{
   252 				if (col.Width == 0)
   253 					_innerCursor = ResourceHelper.DVSplitCursor;
   254 				else
   255 					_innerCursor = Cursors.VSplit;
   256 			}
   257 
   258 			col = GetColumnAt(e.Location);
   259 			if (col != _hotColumn)
   260 			{
   261 				_hotColumn = col;
   262 				UpdateHeaders();
   263 			}
   264 		}
   265 
   266 		internal TreeColumn GetColumnAt(Point p)
   267 		{
   268 			if (p.Y > ColumnHeaderHeight)
   269 				return null;
   270 
   271 			int x = -OffsetX;
   272 			foreach (TreeColumn col in Columns)
   273 			{
   274 				if (col.IsVisible)
   275 				{
   276 					Rectangle rect = new Rectangle(x, 0, col.Width, ColumnHeaderHeight);
   277 					x += col.Width;
   278 					if (rect.Contains(p))
   279 						return col;
   280 				}
   281 			}
   282 			return null;
   283 		}
   284 
   285 		internal int GetColumnX(TreeColumn column)
   286 		{
   287 			int x = -OffsetX;
   288 			foreach (TreeColumn col in Columns)
   289 			{
   290 				if (col.IsVisible)
   291 				{
   292 					if (column == col)
   293 						return x;
   294 					else
   295 						x += col.Width;
   296 				}
   297 			}
   298 			return x;
   299 		}
   300 
   301 		internal TreeColumn GetColumnDividerAt(Point p)
   302 		{
   303 			if (p.Y > ColumnHeaderHeight)
   304 				return null;
   305 
   306 			int x = -OffsetX;
   307 			TreeColumn prevCol = null;
   308 			Rectangle left, right;
   309 			foreach (TreeColumn col in Columns)
   310 			{
   311 				if (col.IsVisible)
   312 				{
   313 					if (col.Width > 0)
   314 					{
   315 						left = new Rectangle(x, 0, DividerWidth / 2, ColumnHeaderHeight);
   316 						right = new Rectangle(x + col.Width - (DividerWidth / 2), 0, DividerWidth / 2, ColumnHeaderHeight);
   317 						if (left.Contains(p) && prevCol != null)
   318 							return prevCol;
   319 						else if (right.Contains(p))
   320 							return col;
   321 					}
   322 					prevCol = col;
   323 					x += col.Width;
   324 				}
   325 			}
   326 
   327 			left = new Rectangle(x, 0, DividerWidth / 2, ColumnHeaderHeight);
   328 			if (left.Contains(p) && prevCol != null)
   329 				return prevCol;
   330 
   331 			return null;
   332 		}
   333 
   334 		TreeColumn _tooltipColumn;
   335 		private void UpdateToolTip(MouseEventArgs e)
   336 		{
   337 			TreeColumn col = GetColumnAt(e.Location);
   338 			if (col != null)
   339 			{
   340 				if (col != _tooltipColumn)
   341 					SetTooltip(col.TooltipText);
   342 			}
   343 			else
   344 				DisplayNodesTooltip(e);
   345 			_tooltipColumn = col;
   346 		}
   347 
   348 		TreeNodeAdv _hotNode;
   349 		NodeControl _hotControl;
   350 		private void DisplayNodesTooltip(MouseEventArgs e)
   351 		{
   352 			if (ShowNodeToolTips)
   353 			{
   354 				TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
   355 				if (args.Node != null && args.Control != null)
   356 				{
   357 					if (args.Node != _hotNode || args.Control != _hotControl)
   358 						SetTooltip(GetNodeToolTip(args));
   359 				}
   360 				else
   361 					_toolTip.SetToolTip(this, null);
   362 
   363 				_hotControl = args.Control;
   364 				_hotNode = args.Node;
   365 			}
   366 			else
   367 				_toolTip.SetToolTip(this, null);
   368 		}
   369 
   370 		private void SetTooltip(string text)
   371 		{
   372 			if (!String.IsNullOrEmpty(text))
   373 			{
   374 				_toolTip.Active = false;
   375 				_toolTip.SetToolTip(this, text);
   376 				_toolTip.Active = true;
   377 			}
   378 			else
   379 				_toolTip.SetToolTip(this, null);
   380 		}
   381 
   382 		private string GetNodeToolTip(TreeNodeAdvMouseEventArgs args)
   383 		{
   384 			string msg = args.Control.GetToolTip(args.Node);
   385 
   386 			BaseTextControl btc = args.Control as BaseTextControl;
   387 			if (btc != null && btc.DisplayHiddenContentInToolTip && String.IsNullOrEmpty(msg))
   388 			{
   389 				Size ms = btc.GetActualSize(args.Node, _measureContext);
   390 				if (ms.Width > args.ControlBounds.Size.Width || ms.Height > args.ControlBounds.Size.Height
   391 					|| args.ControlBounds.Right - OffsetX > DisplayRectangle.Width)
   392 					msg = btc.GetLabel(args.Node);
   393 			}
   394 
   395 			if (String.IsNullOrEmpty(msg) && DefaultToolTipProvider != null)
   396 				msg = DefaultToolTipProvider.GetToolTip(args.Node, args.Control);
   397 
   398 			return msg;
   399 		}
   400 
   401 		#endregion
   402 
   403 		#region DragDrop
   404 
   405 		private bool _dragAutoScrollFlag = false;
   406 		private Bitmap _dragBitmap = null;
   407 		private System.Threading.Timer _dragTimer;
   408 
   409 		private void StartDragTimer()
   410 		{
   411 			if (_dragTimer == null)
   412 				_dragTimer = new System.Threading.Timer(new TimerCallback(DragTimerTick), null, 0, 100);
   413 		}
   414 
   415 		private void StopDragTimer()
   416 		{
   417 			if (_dragTimer != null)
   418 			{
   419 				_dragTimer.Dispose();
   420 				_dragTimer = null;
   421 			}
   422 		}
   423 
   424 		private void SetDropPosition(Point pt)
   425 		{
   426 			TreeNodeAdv node = GetNodeAt(pt);
   427 			OnDropNodeValidating(pt, ref node);
   428 			_dropPosition.Node = node;
   429 			if (node != null)
   430 			{
   431 				Rectangle first = _rowLayout.GetRowBounds(FirstVisibleRow);
   432 				Rectangle bounds = _rowLayout.GetRowBounds(node.Row);
   433 				float pos = (pt.Y + first.Y - ColumnHeaderHeight - bounds.Y) / (float)bounds.Height;
   434 				if (pos < TopEdgeSensivity)
   435 					_dropPosition.Position = NodePosition.Before;
   436 				else if (pos > (1 - BottomEdgeSensivity))
   437 					_dropPosition.Position = NodePosition.After;
   438 				else
   439 					_dropPosition.Position = NodePosition.Inside;
   440 			}
   441 		}
   442 
   443 		private void DragTimerTick(object state)
   444 		{
   445 			_dragAutoScrollFlag = true;
   446 		}
   447 
   448 		private void DragAutoScroll()
   449 		{
   450 			_dragAutoScrollFlag = false;
   451 			Point pt = PointToClient(MousePosition);
   452 			if (pt.Y < 20 && _vScrollBar.Value > 0)
   453 				_vScrollBar.Value--;
   454 			else if (pt.Y > Height - 20 && _vScrollBar.Value <= _vScrollBar.Maximum - _vScrollBar.LargeChange)
   455 				_vScrollBar.Value++;
   456 		}
   457 
   458 		public void DoDragDropSelectedNodes(DragDropEffects allowedEffects)
   459 		{
   460 			if (SelectedNodes.Count > 0)
   461 			{
   462 				TreeNodeAdv[] nodes = new TreeNodeAdv[SelectedNodes.Count];
   463 				SelectedNodes.CopyTo(nodes, 0);
   464 				DoDragDrop(nodes, allowedEffects);
   465 			}
   466 		}
   467 
   468 		private void CreateDragBitmap(IDataObject data)
   469 		{
   470 			if (UseColumns || !DisplayDraggingNodes)
   471 				return;
   472 
   473 			TreeNodeAdv[] nodes = data.GetData(typeof(TreeNodeAdv[])) as TreeNodeAdv[];
   474 			if (nodes != null && nodes.Length > 0)
   475 			{
   476 				Rectangle rect = DisplayRectangle;
   477 				Bitmap bitmap = new Bitmap(rect.Width, rect.Height);
   478 				using (Graphics gr = Graphics.FromImage(bitmap))
   479 				{
   480 					gr.Clear(BackColor);
   481 					DrawContext context = new DrawContext();
   482 					context.Graphics = gr;
   483 					context.Font = Font;
   484 					context.Enabled = true;
   485 					int y = 0;
   486 					int maxWidth = 0;
   487 					foreach (TreeNodeAdv node in nodes)
   488 					{
   489 						if (node.Tree == this)
   490 						{
   491 							int x = 0;
   492 							int height = _rowLayout.GetRowBounds(node.Row).Height;
   493 							foreach (NodeControl c in NodeControls)
   494 							{
   495 								Size s = c.GetActualSize(node, context);
   496 								if (!s.IsEmpty)
   497 								{
   498 									int width = s.Width;
   499 									rect = new Rectangle(x, y, width, height);
   500 									x += (width + 1);
   501 									context.Bounds = rect;
   502 									c.Draw(node, context);
   503 								}
   504 							}
   505 							y += height;
   506 							maxWidth = Math.Max(maxWidth, x);
   507 						}
   508 					}
   509 
   510 					if (maxWidth > 0 && y > 0)
   511 					{
   512 						_dragBitmap = new Bitmap(maxWidth, y, PixelFormat.Format32bppArgb);
   513 						using (Graphics tgr = Graphics.FromImage(_dragBitmap))
   514 							tgr.DrawImage(bitmap, Point.Empty);
   515 						BitmapHelper.SetAlphaChanelValue(_dragBitmap, 150);
   516 					}
   517 					else
   518 						_dragBitmap = null;
   519 				}
   520 			}
   521 		}
   522 
   523 		protected override void OnDragOver(DragEventArgs drgevent)
   524 		{
   525 			ItemDragMode = false;
   526 			Point pt = PointToClient(new Point(drgevent.X, drgevent.Y));
   527 			if (_dragAutoScrollFlag)
   528 				DragAutoScroll();
   529 			SetDropPosition(pt);
   530 			UpdateView();
   531 			base.OnDragOver(drgevent);
   532 		}
   533 
   534 		protected override void OnDragEnter(DragEventArgs drgevent)
   535 		{
   536 			_search.EndSearch();
   537 			DragMode = true;
   538 			CreateDragBitmap(drgevent.Data);
   539 			base.OnDragEnter(drgevent);
   540 		}
   541 
   542 		protected override void OnDragLeave(EventArgs e)
   543 		{
   544 			DragMode = false;
   545 			UpdateView();
   546 			base.OnDragLeave(e);
   547 		}
   548 
   549 		protected override void OnDragDrop(DragEventArgs drgevent)
   550 		{
   551 			DragMode = false;
   552 			UpdateView();
   553 			base.OnDragDrop(drgevent);
   554 		}
   555 
   556 		#endregion
   557 	}
   558 }