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