PageRenderTime 145ms CodeModel.GetById 60ms app.highlight 13ms RepoModel.GetById 67ms app.codeStats 0ms

/Scenes/UserInterfaces/Controls/RadioButton.cs

#
C# | 326 lines | 193 code | 35 blank | 98 comment | 15 complexity | 7fda125cfdd2e8aa8c73f877475421c7 MD5 | raw file
  1using System.IO;
  2using Delta.Engine;
  3using Delta.Engine.Dynamic;
  4using Delta.InputSystem;
  5using Delta.Scenes.Enums;
  6using Delta.Utilities;
  7using Delta.Utilities.Datatypes;
  8using Delta.Utilities.Datatypes.Advanced;
  9using NUnit.Framework;
 10
 11namespace Delta.Scenes.UserInterfaces.Controls
 12{
 13	/// <summary>
 14	/// This is a radio button control which provides to select always only one
 15	/// option of a choice of several options. The list of options will be
 16	/// grouped by setting the 'GroupObject' property.
 17	/// </summary>
 18	public class RadioButton : Checkbox
 19	{
 20		#region Constants
 21		/// <summary>
 22		/// The current version of the implementation of this class.
 23		/// </summary>
 24		private const int VersionNumber = 1;
 25		#endregion
 26
 27		#region GroupObject (Public)
 28		/// <summary>
 29		/// The "group object" where this RadioButton belongs to.
 30		/// </summary>
 31		/// <value>
 32		/// The group object.
 33		/// </value>
 34		public ISaveLoadBinary GroupObject
 35		{
 36			get;
 37			set;
 38		}
 39		#endregion
 40
 41		#region Protected
 42
 43		#region FallbackDesign (Protected)
 44		/// <summary>
 45		/// Defines the theme which will be used if no "Theme" was set explicitely.
 46		/// </summary>
 47		protected override ControlDesign FallbackDesign
 48		{
 49			get
 50			{
 51				return Theme.Current.RadioButtonDesign;
 52			}
 53		}
 54		#endregion
 55
 56		#endregion
 57
 58		#region Constructors
 59		/// <summary>
 60		/// Create a radio button.
 61		/// </summary>
 62		public RadioButton()
 63		{
 64			GroupObject = null;
 65		}
 66		#endregion
 67
 68		#region Save (Public)
 69		/// <summary>
 70		/// Saves all data which are necessary to restore the object again.
 71		/// </summary>
 72		/// <param name="dataWriter">
 73		/// The writer which contains the stream where the data should be saved
 74		/// into now.
 75		/// </param>
 76		public override void Save(BinaryWriter dataWriter)
 77		{
 78			// At first we write the data of the base class
 79			base.Save(dataWriter);
 80
 81			// and then save the version of the current data format
 82			dataWriter.Write(VersionNumber);
 83
 84			// before we can finally save the properties
 85			// Here we only have to save the "grouping object"
 86			bool isGroupObjectAvaiable = GroupObject != null;
 87			dataWriter.Write(isGroupObjectAvaiable);
 88			if (isGroupObjectAvaiable)
 89			{
 90				Factory.Save(dataWriter, GroupObject);
 91			} // if
 92		}
 93		#endregion
 94
 95		#region Load (Public)
 96		/// <summary>
 97		/// Loads and restores all previously saved values that belongs to this
 98		/// class only from the given data reader.
 99		/// </summary>
100		/// <param name="dataReader">The reader which contains the stream with the saved data which needs to
101		/// be loaded now.</param>
102		public override void Load(BinaryReader dataReader)
103		{
104			// At first we need to load all data of the base class
105			base.Load(dataReader);
106
107			// and then check which version of the data need to load now
108			int version = dataReader.ReadInt32();
109			switch (version)
110			{
111					// Version 1
112				case VersionNumber:
113					// Load our group object if there was one
114					if (dataReader.ReadBoolean())
115					{
116						GroupObject = Factory.Load<ISaveLoadBinary>(dataReader);
117					} // if
118					break;
119
120				default:
121					Log.InvalidVersionWarning(GetType().Name, version, VersionNumber);
122					break;
123			} // switch
124		}
125		#endregion
126
127		#region Methods (Private)
128
129		#region OnClicked
130		/// <summary>
131		/// On clicked
132		/// </summary>
133		/// <param name="input">Input data like the click position.</param>
134		/// <param name="isInsideControl">
135		/// 'True' if the event is occurring inside the control, otherwise 'false'.
136		/// </param>
137		protected override void OnClicked(CommandTrigger input,
138			bool isInsideControl)
139		{
140			base.OnClicked(input, isInsideControl);
141
142			if (isInsideControl)
143			{
144				// Make sure the user can't uncheck the RadioButton by clicking
145				// on it again because we no Checkbox anymore ;)
146				// So in the case the user has currently unchecked the button (by the
147				// base code call) then just make it checked again.
148				// Note:
149				// This will also prevent a value change detection
150				if (IsChecked == false)
151				{
152					IsChecked = true;
153				} // if
154			} // if
155		}
156		#endregion
157
158		#region OnIsCheckedChanging
159		/// <summary>
160		/// On is checked changing
161		/// </summary>
162		/// <param name="oldIsChecked">Old value</param>
163		/// <returns>
164		/// 'True' if the new value can be used or 'false' if the change should be
165		/// aborted.
166		/// </returns>
167		protected override bool OnIsCheckedChanging(bool oldIsChecked)
168		{
169			// Next check if the base code will not abort the change already
170			if (base.OnIsCheckedChanging(oldIsChecked) == false)
171			{
172				return false;
173			} // if
174
175			// If we will be checked now, then we have uncheck all other RadioButton
176			// members of our group
177			if (IsChecked &&
178			    oldIsChecked == false)
179			{
180				// If our RadioButton has a group set, then receive all other
181				// "group members", else if we don't are in a group then we are only
182				// the member.
183				RadioButton[] buttonsInGroup =
184					(GroupObject != null)
185						? (Screen as Screen).GetRadioButtons(GroupObject)
186						: new[]
187						{
188							this
189						};
190
191				// Iterate through all members
192				foreach (RadioButton radioButton in buttonsInGroup)
193				{
194					// and "deactivate" all the other members
195					if (radioButton != this)
196					{
197						radioButton.IsChecked = false;
198					} // if
199				} // foreach
200			} // if
201
202			// In the case that we are only deactivated or already checked we don't
203			// need to anything here because everything was done already in the
204			//"base code"
205			return true;
206		}
207		#endregion
208
209		#endregion
210
211		/// <summary>
212		/// Tests for RadioButton controls
213		/// </summary>
214		[Category("Visual")]
215		internal class RadioButtonTests
216		{
217			#region DisplayRadioButton (Static)
218			/// <summary>
219			/// Checkbox
220			/// </summary>
221			[Test]
222			public static void DisplayRadioButton()
223			{
224				// The used UI scene for the unit test
225				Screen testScene = new Screen();
226
227				// Create a grouping condition to which both radio buttons belong to
228				ISaveLoadBinary groupTag = new DataContainer
229				{
230					StringData = "Group 1",
231				};
232
233				RadioButton radioButtonOne = new RadioButton
234				{
235					LocalArea = new Rectangle(0.3f, 0.3f, 0.4f, 0.05f),
236					//Size = new Size(0.6f, 0.1f),
237					GroupObject = groupTag,
238					Text = "Option A",
239				};
240				testScene.Add(radioButtonOne);
241
242				RadioButton radioButtonTwo = new RadioButton
243				{
244					LocalArea = new Rectangle(0.3f, 0.4f, 0.4f, 0.05f),
245					//Size = new Size(0.6f, 0.1f),
246					GroupObject = groupTag,
247					Text = "Option B",
248				};
249				testScene.Add(radioButtonTwo);
250
251				RadioButton radioButtonThree = new RadioButton
252				{
253					LocalArea = new Rectangle(0.3f, 0.5f, 0.4f, 0.05f),
254					//Size = new Size(0.6f, 0.1f),
255					GroupObject = groupTag,
256					Text = "Option C",
257				};
258				testScene.Add(radioButtonThree);
259
260				// Open now the scene to "activate" for the test
261				testScene.Open();
262
263				// We just call here Application.Start() to display the image, but we
264				// don't need to call the "Image.Draw()" explicitely, because this
265				// already handled automatically by the UI manager
266				Application.Start();
267			}
268			#endregion
269
270			#region DisabledRadioButton (Static)
271			/// <summary>
272			/// Disabled radio button
273			/// </summary>
274			[Test]
275			public static void DisabledRadioButton()
276			{
277				// The used UI scene for the unit test
278				Screen testScene = new Screen();
279
280				// Create a grouping condition to which both radio buttons belong to
281				BaseControl groupTag = new Image();
282
283				RadioButton radioButton1 = new RadioButton
284				{
285					LocalArea = new Rectangle(0.3f, 0.3f, 0.4f, 0.05f),
286					//Size = new Size(0.6f, 0.1f),
287					GroupObject = groupTag,
288					Text = "Enabled",
289				};
290				testScene.Add(radioButton1);
291
292				RadioButton radioButton2 = new RadioButton
293				{
294					LocalArea = new Rectangle(0.3f, 0.4f, 0.4f, 0.05f),
295					//Size = new Size(0.6f, 0.1f),
296					GroupObject = groupTag,
297					Text = "Enabled",
298				};
299				testScene.Add(radioButton2);
300
301				// Open now the scene to "activate" for the test
302				testScene.Open();
303
304				Application.Start(delegate
305				{
306					// Start the visual test to see the RadioButton's
307
308					// Disable/enable the RadioButton's by pressing the "Space" key
309					if (Input.Keyboard.SpaceReleased)
310					{
311						radioButton1.State = (radioButton1.State >= ElementState.Enabled)
312						                     	? ElementState.Disabled
313						                     	: ElementState.Enabled;
314						radioButton1.Text = radioButton1.State.ToString();
315
316						radioButton2.State = (radioButton2.State >= ElementState.Enabled)
317						                     	? ElementState.Disabled
318						                     	: ElementState.Enabled;
319						radioButton2.Text = radioButton2.State.ToString();
320					} // if
321				});
322			}
323			#endregion
324		}
325	}
326}