PageRenderTime 94ms CodeModel.GetById 40ms app.highlight 10ms RepoModel.GetById 40ms app.codeStats 0ms

/Scenes/UserInterfaces/Controls/Checkbox.cs

#
C# | 357 lines | 203 code | 41 blank | 113 comment | 12 complexity | dec78492c6746d048247100a1afe3ab8 MD5 | raw file
  1using System.IO;
  2using Delta.Engine;
  3using Delta.InputSystem;
  4using Delta.Scenes.Enums;
  5using Delta.Utilities;
  6using Delta.Utilities.Datatypes;
  7using Delta.Utilities.Datatypes.Advanced;
  8using NUnit.Framework;
  9
 10namespace Delta.Scenes.UserInterfaces.Controls
 11{
 12	/// <summary>
 13	/// This represents a simple checkBox control for check or uncheck things.
 14	/// </summary>
 15	public class Checkbox : Button
 16	{
 17		#region Constants
 18		/// <summary>
 19		/// The current version of the implementation of this control class.
 20		/// </summary>
 21		private const int VersionNumber = 1;
 22		#endregion
 23
 24		#region Delegates
 25		/// <summary>
 26		/// The delegate declaration for the checked changed event.
 27		/// </summary>
 28		/// <param name="sender">Sender</param>
 29		public delegate void CheckedChangedEvent(Checkbox sender);
 30		#endregion
 31
 32		#region IsChecked (Public)
 33		/// <summary>
 34		/// Is the checked property enabled ?
 35		/// </summary>
 36		public bool IsChecked
 37		{
 38			get;
 39			set;
 40		}
 41		#endregion
 42
 43		#region Protected
 44
 45		#region FallbackDesign (Protected)
 46		/// <summary>
 47		/// Defines the theme which will be used if no "Design" was set
 48		/// explicitely.
 49		/// </summary>
 50		protected override ControlDesign FallbackDesign
 51		{
 52			get
 53			{
 54				return Theme.Current.CheckboxDesign;
 55			} // get
 56		}
 57		#endregion
 58
 59		#region CheckedSymbolArea (Protected)
 60		/// <summary>
 61		/// The element which describes the area where the checked or unchecked
 62		/// symbol will be shown.
 63		/// </summary>
 64		protected internal AlignableElement CheckedSymbolArea
 65		{
 66			get;
 67			private set;
 68		}
 69		#endregion
 70
 71		#endregion
 72
 73		#region Private
 74
 75		#region lastIsChecked (Private)
 76		/// <summary>
 77		/// The last set 'IsChecked' value which is used to "detect" Checked
 78		/// changes of the control by the user.
 79		/// </summary>
 80		private bool lastIsChecked;
 81		#endregion
 82
 83		#endregion
 84
 85		#region Constructors
 86		/// <summary>
 87		/// Creates a checkbox.
 88		/// </summary>
 89		public Checkbox()
 90		{
 91			// Define the area of the "checked" indicator
 92			CheckedSymbolArea = new AlignableElement
 93			{
 94				HorizontalAlignment = HorizontalAlignment.Left,
 95				VerticalAlignment = VerticalAlignment.Centered,
 96			};
 97			Add(CheckedSymbolArea);
 98
 99			// Align the text area at the right side of the control
100			TextContentElement.HorizontalAlignment = HorizontalAlignment.Right;
101			TextContentElement.VerticalAlignment = VerticalAlignment.Centered;
102
103			IsChecked = false;
104		}
105		#endregion
106
107		#region CheckedChanged (Event)
108		/// <summary>
109		/// Occurs every time the 'IsChecked' value of the Checkbox will be
110		/// changed.
111		/// </summary>
112		public event CheckedChangedEvent CheckedChanged;
113		#endregion
114
115		#region Save (Public)
116		/// <summary>
117		/// Saves all data which are necessary to restore the object again.
118		/// </summary>
119		/// <param name="dataWriter">
120		/// The writer which contains the stream where the data should be saved
121		/// into now.
122		/// </param>
123		public override void Save(BinaryWriter dataWriter)
124		{
125			// At first we write the data of the base class
126			base.Save(dataWriter);
127
128			// and then save the version of the current data format
129			dataWriter.Write(VersionNumber);
130
131			// before we can finally save the properties
132			dataWriter.Write(IsChecked);
133		}
134		#endregion
135
136		#region Load (Public)
137		/// <summary>
138		/// Loads and restores all previously saved values that belongs to this
139		/// class only from the given data reader.
140		/// </summary>
141		/// <param name="dataReader">
142		/// The reader which contains the stream with the saved data which needs to
143		/// be loaded now.
144		/// </param>
145		public override void Load(BinaryReader dataReader)
146		{
147			// At first we need to load all data of the base class
148			base.Load(dataReader);
149
150			// and then check which version of the data need to load now
151			int version = dataReader.ReadInt32();
152			switch (version)
153			{
154					// Version 1
155				case VersionNumber:
156					IsChecked = dataReader.ReadBoolean();
157					break;
158
159				default:
160					Log.InvalidVersionWarning(GetType().Name, version, VersionNumber);
161					break;
162			} // switch
163		}
164		#endregion
165
166		#region Methods (Private)
167
168		#region OnSizeChanging
169		/// <summary>
170		/// On size changing
171		/// </summary>
172		/// <param name="oldSize">Old size</param>
173		/// <returns>
174		/// 'True' if the new value can be used or 'false' if the change should be
175		/// aborted.
176		/// </returns>
177		protected override bool OnSizeChanging(Size oldSize)
178		{
179			if (base.OnSizeChanging(oldSize))
180			{
181				// Check if we need to auto-set the size of the "checked" symbol
182				if (CheckedSymbolArea.Size == Size.Zero)
183				{
184					CheckedSymbolArea.Size = new Size(Size.Height);
185				} // if
186
187				if (IsTextElementAutoSizing)
188				{
189					// The text area is whole control area except the size of the
190					// "Checked" symbol area
191					TextContentElement.Size = new Size(
192						Size.Width - CheckedSymbolArea.Size.Width, Size.Height);
193				} // if
194
195				return true;
196			} // if
197
198			return false;
199		}
200		#endregion
201
202		#region OnClicked
203		/// <summary>
204		/// Contains the whole (Checkbox) logic which happens if the control was
205		/// clicked.
206		/// </summary>
207		/// <param name="input">Input data like the click position.</param>
208		/// <param name="isInsideControl">
209		/// 'True' if the event is occurring inside the control, otherwise 'false'.
210		/// </param>
211		protected override void OnClicked(CommandTrigger input,
212			bool isInsideControl)
213		{
214			base.OnClicked(input, isInsideControl);
215
216			// Accept a click only if it is occurring inside the control
217			if (isInsideControl)
218			{
219				// We want to change the 'IsChecked' value on every click event
220				IsChecked = !IsChecked;
221				input.IsHandled = true;
222			} // if
223		}
224		#endregion
225
226		#region OnIsCheckedChanging
227		/// <summary>
228		/// On is checked changing
229		/// </summary>
230		/// <param name="oldIsChecked">Old value</param>
231		/// <returns>
232		/// 'True' if the new value can be used or 'false' if the change should be
233		/// aborted.
234		/// </returns>
235		protected virtual bool OnIsCheckedChanging(bool oldIsChecked)
236		{
237			return true;
238		}
239		#endregion
240
241		#region DetectChanges
242		/// <summary>
243		/// This method implements the checks of the changes which are should be
244		/// detected in this element. It also cares about triggering the events and
245		/// the event handler methods.
246		/// </summary>
247		protected override void DetectChanges()
248		{
249			base.DetectChanges();
250
251			// Detect 'IsChecked' changes
252			if (IsChecked != lastIsChecked)
253			{
254				// Check now if the new value should be set
255				if (OnIsCheckedChanging(lastIsChecked))
256				{
257					lastIsChecked = IsChecked;
258
259					// After setting the new value also inform all external listeners
260					// about the change
261					if (CheckedChanged != null &&
262					    // but only if it isn't just the value initialization
263					    isRuntimeValueChange)
264					{
265						CheckedChanged.Invoke(this);
266					} // if
267				} // if
268				else
269				{
270					IsChecked = lastIsChecked;
271				} // else
272			} // if
273		}
274		#endregion
275
276		#region ShortElementInfo
277		/// <summary>
278		/// Short element info
279		/// </summary>
280		protected override string ShortElementInfo()
281		{
282			return base.ShortElementInfo() + ", IsChecked='" + IsChecked + "'";
283		}
284		#endregion
285
286		#endregion
287
288		/// <summary>
289		/// Tests for Checkbox controls
290		/// </summary>
291		[Category("Visual")]
292		internal class CheckboxTests
293		{
294			#region DisplayCheckbox (Static)
295			/// <summary>
296			/// Display checkbox
297			/// </summary>
298			[Test]
299			public static void DisplayCheckbox()
300			{
301				Checkbox testCheckbox = new Checkbox
302				{
303					LocalArea = new Rectangle(0.2f, 0.3f, 0.4f, 0.05f),
304					//Size = new Size(0.6f, 0.1f),
305					IsChecked = true,
306					Text = "DisplayCheckbox",
307				};
308
309				Screen testScene = new Screen();
310				testScene.Add(testCheckbox);
311
312				// Open now the scene to "activate" for the test
313				Scene.Open(testScene);
314
315				// We just call here Application.Start() to display the image, but we
316				// don't need to call the "Image.Draw()" explicitely, because this
317				// already handled automatically by the UI manager.
318				Application.Start();
319			}
320			#endregion
321
322			#region DisabledCheckbox (Static)
323			/// <summary>
324			/// Disabled checkbox
325			/// </summary>
326			[Test]
327			public static void DisabledCheckbox()
328			{
329				Checkbox testCheckbox = new Checkbox
330				{
331					LocalArea = new Rectangle(0.2f, 0.3f, 0.4f, 0.05f),
332					IsChecked = true,
333					Text = "Enabled",
334				};
335
336				Screen testScene = new Screen();
337				testScene.Add(testCheckbox);
338
339				// Open now the scene to "activate" for the test
340				testScene.Open();
341
342				Application.Start(delegate
343				{
344					// Disable/enable the Checkbox by pressing the keyboard "Space" button
345					if (Input.Keyboard.SpaceReleased)
346					{
347						testCheckbox.State = (testCheckbox.State >= ElementState.Enabled)
348						                     	? ElementState.Disabled
349						                     	: ElementState.Enabled;
350						testCheckbox.Text = testCheckbox.State.ToString();
351					}
352				});
353			}
354			#endregion
355		}
356	}
357}