External/Aga.Controls/Tree/TreeViewAdv.Input.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.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 }