moel@345: using System;
moel@345: using System.Collections.Generic;
moel@345: using System.Text;
moel@345: using System.Windows.Forms;
moel@345: 
moel@345: namespace Aga.Controls.Tree
moel@345: {
moel@345: 	internal class NormalInputState : InputState
moel@345: 	{
moel@345: 		private bool _mouseDownFlag = false;
moel@345: 
moel@345: 		public NormalInputState(TreeViewAdv tree) : base(tree)
moel@345: 		{
moel@345: 		}
moel@345: 
moel@345: 		public override void KeyDown(KeyEventArgs args)
moel@345: 		{
moel@345: 			if (Tree.CurrentNode == null && Tree.Root.Nodes.Count > 0)
moel@345: 				Tree.CurrentNode = Tree.Root.Nodes[0];
moel@345: 
moel@345: 			if (Tree.CurrentNode != null)
moel@345: 			{
moel@345: 				switch (args.KeyCode)
moel@345: 				{
moel@345: 					case Keys.Right:
moel@345: 						if (!Tree.CurrentNode.IsExpanded)
moel@345: 							Tree.CurrentNode.IsExpanded = true;
moel@345: 						else if (Tree.CurrentNode.Nodes.Count > 0)
moel@345: 							Tree.SelectedNode = Tree.CurrentNode.Nodes[0];
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.Left:
moel@345: 						if (Tree.CurrentNode.IsExpanded)
moel@345: 							Tree.CurrentNode.IsExpanded = false;
moel@345: 						else if (Tree.CurrentNode.Parent != Tree.Root)
moel@345: 							Tree.SelectedNode = Tree.CurrentNode.Parent;
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.Down:
moel@345: 						NavigateForward(1);
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.Up:
moel@345: 						NavigateBackward(1);
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.PageDown:
moel@345: 						NavigateForward(Math.Max(1, Tree.CurrentPageSize - 1));
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.PageUp:
moel@345: 						NavigateBackward(Math.Max(1, Tree.CurrentPageSize - 1));
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.Home:
moel@345: 						if (Tree.RowMap.Count > 0)
moel@345: 							FocusRow(Tree.RowMap[0]);
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.End:
moel@345: 						if (Tree.RowMap.Count > 0)
moel@345: 							FocusRow(Tree.RowMap[Tree.RowMap.Count-1]);
moel@345: 						args.Handled = true;
moel@345: 						break;
moel@345: 					case Keys.Subtract:
moel@345: 						Tree.CurrentNode.Collapse();
moel@345: 						args.Handled = true;
moel@345: 						args.SuppressKeyPress = true;
moel@345: 						break;
moel@345: 					case Keys.Add:
moel@345: 						Tree.CurrentNode.Expand();
moel@345: 						args.Handled = true;
moel@345: 						args.SuppressKeyPress = true;
moel@345: 						break;
moel@345: 					case Keys.Multiply:
moel@345: 						Tree.CurrentNode.ExpandAll();
moel@345: 						args.Handled = true;
moel@345: 						args.SuppressKeyPress = true;
moel@345: 						break;
moel@345: 					case Keys.A:
moel@345: 						if (args.Modifiers == Keys.Control)
moel@345: 							Tree.SelectAllNodes();
moel@345: 						break;
moel@345: 				}
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		public override void MouseDown(TreeNodeAdvMouseEventArgs args)
moel@345: 		{
moel@345: 			if (args.Node != null)
moel@345: 			{
moel@345: 				Tree.ItemDragMode = true;
moel@345: 				Tree.ItemDragStart = args.Location;
moel@345: 
moel@345: 				if (args.Button == MouseButtons.Left || args.Button == MouseButtons.Right)
moel@345: 				{
moel@345: 					Tree.BeginUpdate();
moel@345: 					try
moel@345: 					{
moel@345: 						Tree.CurrentNode = args.Node;
moel@345: 						if (args.Node.IsSelected)
moel@345: 							_mouseDownFlag = true;
moel@345: 						else
moel@345: 						{
moel@345: 							_mouseDownFlag = false;
moel@345: 							DoMouseOperation(args);
moel@345: 						}
moel@345: 					}
moel@345: 					finally
moel@345: 					{
moel@345: 						Tree.EndUpdate();
moel@345: 					}
moel@345: 				}
moel@345: 
moel@345: 			}
moel@345: 			else
moel@345: 			{
moel@345: 				Tree.ItemDragMode = false;
moel@345: 				MouseDownAtEmptySpace(args);
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		public override void MouseUp(TreeNodeAdvMouseEventArgs args)
moel@345: 		{
moel@345: 			Tree.ItemDragMode = false;
moel@345: 			if (_mouseDownFlag && args.Node != null)
moel@345: 			{
moel@345: 				if (args.Button == MouseButtons.Left)
moel@345: 					DoMouseOperation(args);
moel@345: 				else if (args.Button == MouseButtons.Right)
moel@345: 					Tree.CurrentNode = args.Node;
moel@345: 			}
moel@345: 			_mouseDownFlag = false;
moel@345: 		}
moel@345: 
moel@345: 
moel@345: 		private void NavigateBackward(int n)
moel@345: 		{
moel@345: 			int row = Math.Max(Tree.CurrentNode.Row - n, 0);
moel@345: 			if (row != Tree.CurrentNode.Row)
moel@345: 				FocusRow(Tree.RowMap[row]);
moel@345: 		}
moel@345: 
moel@345: 		private void NavigateForward(int n)
moel@345: 		{
moel@345: 			int row = Math.Min(Tree.CurrentNode.Row + n, Tree.RowCount - 1);
moel@345: 			if (row != Tree.CurrentNode.Row)
moel@345: 				FocusRow(Tree.RowMap[row]);
moel@345: 		}
moel@345: 
moel@345: 		protected virtual void MouseDownAtEmptySpace(TreeNodeAdvMouseEventArgs args)
moel@345: 		{
moel@345: 			Tree.ClearSelection();
moel@345: 		}
moel@345: 
moel@345: 		protected virtual void FocusRow(TreeNodeAdv node)
moel@345: 		{
moel@345: 			Tree.SuspendSelectionEvent = true;
moel@345: 			try
moel@345: 			{
moel@345: 				Tree.ClearSelectionInternal();
moel@345: 				Tree.CurrentNode = node;
moel@345: 				Tree.SelectionStart = node;
moel@345: 				node.IsSelected = true;
moel@345: 				Tree.ScrollTo(node);
moel@345: 			}
moel@345: 			finally
moel@345: 			{
moel@345: 				Tree.SuspendSelectionEvent = false;
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		protected bool CanSelect(TreeNodeAdv node)
moel@345: 		{
moel@345: 			if (Tree.SelectionMode == TreeSelectionMode.MultiSameParent)
moel@345: 			{
moel@345: 				return (Tree.SelectionStart == null || node.Parent == Tree.SelectionStart.Parent);
moel@345: 			}
moel@345: 			else
moel@345: 				return true;
moel@345: 		}
moel@345: 
moel@345: 		protected virtual void DoMouseOperation(TreeNodeAdvMouseEventArgs args)
moel@345: 		{
moel@345: 			if (Tree.SelectedNodes.Count == 1 && args.Node != null && args.Node.IsSelected)
moel@345: 				return;
moel@345: 
moel@345: 			Tree.SuspendSelectionEvent = true;
moel@345: 			try
moel@345: 			{
moel@345: 				Tree.ClearSelectionInternal();
moel@345: 				if (args.Node != null)
moel@345: 					args.Node.IsSelected = true;
moel@345: 				Tree.SelectionStart = args.Node;
moel@345: 			}
moel@345: 			finally
moel@345: 			{
moel@345: 				Tree.SuspendSelectionEvent = false;
moel@345: 			}
moel@345: 		}
moel@345: 	}
moel@345: }