External/Aga.Controls/Tree/NodeControls/NodeCheckBox.cs
author StephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433 090259cfd699
permissions -rw-r--r--
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using System.Drawing;
     5 using Aga.Controls.Properties;
     6 using System.Reflection;
     7 using System.Windows.Forms;
     8 using System.Windows.Forms.VisualStyles;
     9 using System.ComponentModel;
    10 
    11 namespace Aga.Controls.Tree.NodeControls
    12 {
    13 	public class NodeCheckBox : InteractiveControl
    14 	{
    15 		public const int ImageSize = 13;
    16 
    17 		private Bitmap _check;
    18 		private Bitmap _uncheck;
    19 		private Bitmap _unknown;
    20 
    21 		#region Properties
    22 
    23 		private bool _threeState;
    24 		[DefaultValue(false)]
    25 		public bool ThreeState
    26 		{
    27 			get { return _threeState; }
    28 			set { _threeState = value; }
    29 		}
    30 
    31 		#endregion
    32 
    33 		public NodeCheckBox()
    34 			: this(string.Empty)
    35 		{
    36 		}
    37 
    38 		public NodeCheckBox(string propertyName)
    39 		{
    40 			_check = Resources.check;
    41 			_uncheck = Resources.uncheck;
    42 			_unknown = Resources.unknown;
    43 			DataPropertyName = propertyName;
    44 			LeftMargin = 0;
    45 		}
    46 
    47 		public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
    48 		{
    49 			return new Size(ImageSize, ImageSize);
    50 		}
    51 
    52 		public override void Draw(TreeNodeAdv node, DrawContext context)
    53 		{
    54 			Rectangle bounds = GetBounds(node, context);
    55 			CheckState state = GetCheckState(node);
    56 			if (Application.RenderWithVisualStyles)
    57 			{
    58 				VisualStyleRenderer renderer;
    59 				if (state == CheckState.Indeterminate)
    60 					renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.MixedNormal);
    61 				else if (state == CheckState.Checked)
    62 					renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.CheckedNormal);
    63 				else
    64 					renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.UncheckedNormal);
    65 				renderer.DrawBackground(context.Graphics, new Rectangle(bounds.X, bounds.Y, ImageSize, ImageSize));
    66 			}
    67 			else
    68 			{
    69 				Image img;
    70 				if (state == CheckState.Indeterminate)
    71 					img = _unknown;
    72 				else if (state == CheckState.Checked)
    73 					img = _check;
    74 				else
    75 					img = _uncheck;
    76 				context.Graphics.DrawImage(img, bounds.Location);
    77 			}
    78 		}
    79 
    80 		protected virtual CheckState GetCheckState(TreeNodeAdv node)
    81 		{
    82 			object obj = GetValue(node);
    83 			if (obj is CheckState)
    84 				return (CheckState)obj;
    85 			else if (obj is bool)
    86 				return (bool)obj ? CheckState.Checked : CheckState.Unchecked;
    87 			else
    88 				return CheckState.Unchecked;
    89 		}
    90 
    91 		protected virtual void SetCheckState(TreeNodeAdv node, CheckState value)
    92 		{
    93 			if (VirtualMode)
    94 			{
    95 				SetValue(node, value);
    96 				OnCheckStateChanged(node);
    97 			}
    98 			else
    99 			{
   100 				Type type = GetPropertyType(node);
   101 				if (type == typeof(CheckState))
   102 				{
   103 					SetValue(node, value);
   104 					OnCheckStateChanged(node);
   105 				}
   106 				else if (type == typeof(bool))
   107 				{
   108 					SetValue(node, value != CheckState.Unchecked);
   109 					OnCheckStateChanged(node);
   110 				}
   111 			}
   112 		}
   113 
   114 		public override void MouseDown(TreeNodeAdvMouseEventArgs args)
   115 		{
   116 			if (args.Button == MouseButtons.Left && IsEditEnabled(args.Node))
   117 			{
   118 				DrawContext context = new DrawContext();
   119 				context.Bounds = args.ControlBounds;
   120 				Rectangle rect = GetBounds(args.Node, context);
   121 				if (rect.Contains(args.ViewLocation))
   122 				{
   123 					CheckState state = GetCheckState(args.Node);
   124 					state = GetNewState(state);
   125 					SetCheckState(args.Node, state);
   126 					Parent.UpdateView();
   127 					args.Handled = true;
   128 				}
   129 			}
   130 		}
   131 
   132 		public override void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
   133 		{
   134 			args.Handled = true;
   135 		}
   136 
   137 		private CheckState GetNewState(CheckState state)
   138 		{
   139 			if (state == CheckState.Indeterminate)
   140 				return CheckState.Unchecked;
   141 			else if(state == CheckState.Unchecked)
   142 				return CheckState.Checked;
   143 			else 
   144 				return ThreeState ? CheckState.Indeterminate : CheckState.Unchecked;
   145 		}
   146 
   147 		public override void KeyDown(KeyEventArgs args)
   148 		{
   149 			if (args.KeyCode == Keys.Space && EditEnabled)
   150 			{
   151 				Parent.BeginUpdate();
   152 				try
   153 				{
   154 					if (Parent.CurrentNode != null)
   155 					{
   156 						CheckState value = GetNewState(GetCheckState(Parent.CurrentNode));
   157 						foreach (TreeNodeAdv node in Parent.Selection)
   158 							if (IsEditEnabled(node))
   159 								SetCheckState(node, value);
   160 					}
   161 				}
   162 				finally
   163 				{
   164 					Parent.EndUpdate();
   165 				}
   166 				args.Handled = true;
   167 			}
   168 		}
   169 
   170 		public event EventHandler<TreePathEventArgs> CheckStateChanged;
   171 		protected void OnCheckStateChanged(TreePathEventArgs args)
   172 		{
   173 			if (CheckStateChanged != null)
   174 				CheckStateChanged(this, args);
   175 		}
   176 
   177 		protected void OnCheckStateChanged(TreeNodeAdv node)
   178 		{
   179 			TreePath path = this.Parent.GetPath(node);
   180 			OnCheckStateChanged(new TreePathEventArgs(path));
   181 		}
   182 
   183 	}
   184 }