PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Scenes/UserInterfaces/Controls/RadioButton.cs

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