/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}