PageRenderTime 105ms CodeModel.GetById 36ms app.highlight 14ms RepoModel.GetById 36ms app.codeStats 0ms

/Scenes/UserInterfaces/Designs/TextControlDesign.cs

#
C# | 411 lines | 272 code | 44 blank | 95 comment | 26 complexity | 19aa59fcc19a9a3cccbc682f903cbc59 MD5 | raw file
  1using System.IO;
  2using Delta.Engine.Dynamic;
  3using Delta.Rendering.Basics.Fonts;
  4using Delta.Rendering.Basics.Materials;
  5using Delta.Scenes.Enums;
  6using Delta.Scenes.UserInterfaces.Controls;
  7using Delta.Utilities;
  8using Delta.Utilities.Datatypes;
  9using NUnit.Framework;
 10
 11namespace Delta.Scenes.UserInterfaces.Designs
 12{
 13	/// <summary>
 14	/// Label design.
 15	/// </summary>
 16	public class TextControlDesign : ControlDesign, ITextDesign
 17	{
 18		#region Constants
 19		/// <summary>
 20		/// The current version of the implementation of this class.
 21		/// </summary>
 22		private const int VersionNumber = 1;
 23		#endregion
 24
 25		#region TextFont (Public)
 26		/// <summary>
 27		/// Gets or sets the font which is used to displaying the text.
 28		/// </summary>
 29		public Font TextFont
 30		{
 31			get
 32			{
 33				if (textFont == null)
 34				{
 35					Log.Warning(
 36						"The text font is not valid for '" + this + "' will now use " +
 37						"the default font of the engine instead.");
 38					textFont = Font.Default;
 39				}
 40
 41				return textFont;
 42			}
 43			set
 44			{
 45				textFont = value;
 46			}
 47		}
 48		#endregion
 49
 50		#region DisabledTextFont (Public)
 51		/// <summary>
 52		/// Gets or sets the font which is used to displaying the text if the
 53		/// control is in the "Disabled" state.
 54		/// </summary>
 55		public Font DisabledTextFont
 56		{
 57			get
 58			{
 59				if (disabledTextFont == null)
 60				{
 61					Log.Warning(
 62						"The disabled text font is not valid for '" + this + "' will " +
 63						"now use the default font of the engine instead.");
 64					disabledTextFont = Font.Default;
 65				}
 66
 67				return disabledTextFont;
 68			}
 69			set
 70			{
 71				disabledTextFont = value;
 72			}
 73		}
 74		#endregion
 75
 76		#region TextColor (Public)
 77		/// <summary>
 78		/// Get the color of the displayed text. To change the text color a new
 79		/// font must be initialized (like with all font properties).
 80		/// </summary>
 81		public Color TextColor
 82		{
 83			get
 84			{
 85				return TextFont.Color;
 86			} // get
 87		}
 88		#endregion
 89
 90		#region TextBackground (Public)
 91		/// <summary>
 92		/// The own background design for the text area instead of the "global"
 93		/// background design (enabled state).
 94		/// </summary>
 95		public Material2DColored TextBackground
 96		{
 97			get;
 98			set;
 99		}
100		#endregion
101
102		#region TextHoverBackground (Public)
103		/// <summary>
104		/// The own background design for the text area instead of the "global"
105		/// background design (hovered state).
106		/// </summary>
107		public Material2DColored TextHoverBackground
108		{
109			get;
110			set;
111		}
112		#endregion
113
114		#region DisabledTextBackground (Public)
115		/// <summary>
116		/// The own background design for the text area instead of the "global"
117		/// background design (disabled state).
118		/// </summary>
119		public Material2DColored DisabledTextBackground
120		{
121			get;
122			set;
123		}
124		#endregion
125
126		#region Pressed (Public)
127		/// <summary>
128		/// Gets or sets the design to show when the button is pressed. Note: This
129		/// design is optional, which means if it isn't set, the "basic" rendering
130		/// (with BackgroundDesign and HoverDesign) behavior will be used instead.
131		/// </summary>
132		public Material2DColored Pressed
133		{
134			get;
135			set;
136		}
137		#endregion
138
139		#region Private
140
141		#region textFont (Private)
142		/// <summary>
143		/// Text font used, usually set because this is a text control design
144		/// after all. If nothing is set will be set to the fallback Font.Default.
145		/// </summary>
146		private Font textFont;
147		#endregion
148
149		#region disabledTextFont (Private)
150		/// <summary>
151		/// Disabled text font used, can be null when it is never accessed.
152		/// </summary>
153		private Font disabledTextFont;
154		#endregion
155
156		#endregion
157		
158		#region DrawControl (Public)
159		/// <summary>
160		/// Draw control. Note: This method will only be called if the control
161		/// state is at least visible.
162		/// </summary>
163		/// <param name="control">Control to draw in this design.</param>
164		/// <param name="drawArea">The draw area.</param>
165		public override void DrawControl(BaseControl control, Rectangle drawArea)
166		{
167			// First draw the general design of the control
168			base.DrawControl(control, drawArea);
169
170			Label textControl = control as Label;
171			if (textControl == null)
172			{
173				Log.Warning(
174					"The design '" + this + "' will be applied on the non-text " +
175					"control '" + control + "' which is not really useful because " +
176					"there is no text to draw, so please use a non-text design " +
177					"instead for this control.");
178				return;
179			} // if
180
181			// and next draw the text area related style
182			switch (textControl.State)
183			{
184				case ElementState.Disabled:
185					if (DisabledTextBackground != null)
186					{
187						DrawStyle(textControl, DisabledTextBackground,
188							textControl.TextDrawArea);
189					} // if
190					break;
191
192				case ElementState.Hovered:
193				case ElementState.Active:
194					Material2DColored textHoverStyle =
195						TextHoverBackground != null
196							? TextHoverBackground
197							: TextBackground;
198					if (textHoverStyle != null)
199					{
200						DrawStyle(textControl, textHoverStyle, textControl.TextDrawArea);
201					} // if
202					break;
203
204				default:
205					Material2DColored textBackground = TextBackground;
206					if (textBackground != null)
207					{
208						DrawStyle(textControl, textBackground, textControl.TextDrawArea);
209					} // if
210					break;
211			} // switch
212		}
213		#endregion
214
215		#region Save (Public)
216		/// <summary>
217		/// Saves all data which are necessary to restore the object again.
218		/// </summary>
219		/// <param name="dataWriter">The writer which contains the stream where the data should be saved
220		/// into now.</param>
221		public override void Save(BinaryWriter dataWriter)
222		{
223			// At first we write the data of the base class
224			base.Save(dataWriter);
225
226			// and then save the version of the current data format
227			dataWriter.Write(VersionNumber);
228
229			// before we can finally save the properties
230			bool isTextFontAvailable = textFont != null;
231			dataWriter.Write(isTextFontAvailable);
232			if (isTextFontAvailable)
233			{
234				Factory.Save(dataWriter, textFont);
235			}
236
237			bool isDisabledTextFontAvailable = disabledTextFont != null;
238			dataWriter.Write(isDisabledTextFontAvailable);
239			if (isDisabledTextFontAvailable)
240			{
241				Factory.Save(dataWriter, disabledTextFont);
242			}
243
244			// Pressed style
245			bool hasPressedDesign = Pressed != null;
246			dataWriter.Write(hasPressedDesign);
247			if (hasPressedDesign)
248			{
249				SaveMaterial(dataWriter, Pressed);
250			}
251		}
252		#endregion
253
254		#region Load (Public)
255		/// <summary>
256		/// Loads and restores all previously saved values that belongs to this
257		/// class only from the given data reader.
258		/// </summary>
259		/// <param name="dataReader">The reader which contains the stream with the saved data which needs to
260		/// be loaded now.</param>
261		public override void Load(BinaryReader dataReader)
262		{
263			// At first we need to load all data of the base class
264			base.Load(dataReader);
265
266			// and then check which version of the data need to load now
267			int version = dataReader.ReadInt32();
268			switch (version)
269			{
270					// Version 1
271				case VersionNumber:
272					// Is a text font available ?
273					if (dataReader.ReadBoolean())
274					{
275						// then load the saved font
276						textFont = Factory.Load<Font>(dataReader);
277					}
278
279					if (dataReader.ReadBoolean())
280					{
281						// then load the saved font
282						disabledTextFont = Factory.Load<Font>(dataReader);
283					}
284
285					// Pressed style
286					bool hasPressedDesign = dataReader.ReadBoolean();
287					if (hasPressedDesign)
288					{
289						Pressed = LoadMaterial(dataReader);
290					}
291					else
292					{
293						Pressed = null;
294					}
295					break;
296
297				default:
298					Log.InvalidVersionWarning(GetType().Name, version, VersionNumber);
299					break;
300			}
301		}
302		#endregion
303
304		#region Methods (Private)
305
306		#region GetControlStyle
307		/// <summary>
308		/// Returns the set style of the controls based on its current state.
309		/// </summary>
310		/// <param name="control">Control</param>
311		protected override Material2DColored GetControlStyle(BaseControl control)
312		{
313			switch (control.State)
314			{
315				case ElementState.Pressed:
316					return (Pressed != null)
317					       	? Pressed
318					       	: base.GetControlStyle(control);
319
320				default:
321					return base.GetControlStyle(control);
322			}
323		}
324		#endregion
325
326		#endregion
327
328		/// <summary>
329		/// Tests for TextControlDesign
330		/// </summary>
331		[Category("LongRunning")]
332		internal class TextControlDesignTests
333		{
334			#region SaveAndLoad
335			/// <summary>
336			/// Save and load
337			/// </summary>
338			[Test]
339			public void SaveAndLoad()
340			{
341				// Create a design
342				TextControlDesign textDesign = new TextControlDesign
343				{
344					Background = BaseTheme.GetUIMaterial("ButtonBackground"),
345					DisabledBackground = BaseTheme.GetUIMaterial("ButtonBackground",
346						Color.Grey),
347					Hover = BaseTheme.GetUIMaterial("ButtonHover", Color.Yellow),
348					Pressed = BaseTheme.GetUIMaterial("ButtonPressed", Color.Yellow),
349					TextFont = new Font(Font.Default, Color.Blue),
350					DisabledTextFont = new Font(Font.Default, Color.DarkBlue),
351				};
352
353				// Next create a second instance
354				TextControlDesign loadedDesign = new TextControlDesign();
355
356				//// and save it out
357				//byte[] savedData = textDesign.Save();
358
359				//// and make a sanity check that it hasn't already the same data
360
361				//// Now load the saved data of the first instance
362				//loadedDesign.Load(savedData);
363
364				// and check that all values are the same
365				// Background design
366				Assert.Equal(loadedDesign.Background.Name, textDesign.Background.Name);
367				Assert.Equal(loadedDesign.Background.DrawLayer,
368					textDesign.Background.DrawLayer);
369				Assert.Equal(loadedDesign.Background.BlendColor,
370					textDesign.Background.BlendColor);
371
372				// Disabled background design
373				Assert.Equal(loadedDesign.DisabledBackground.Name,
374					textDesign.DisabledBackground.Name);
375				Assert.Equal(loadedDesign.DisabledBackground.DrawLayer,
376					textDesign.DisabledBackground.DrawLayer);
377				Assert.Equal(loadedDesign.DisabledBackground.BlendColor,
378					textDesign.DisabledBackground.BlendColor);
379
380				// Hover design
381				Assert.Equal(loadedDesign.Hover.Name, textDesign.Hover.Name);
382				Assert.Equal(loadedDesign.Hover.DrawLayer,
383					textDesign.Hover.DrawLayer);
384				Assert.Equal(loadedDesign.Hover.BlendColor,
385					textDesign.Hover.BlendColor);
386
387				// Pressed design
388				Assert.Equal(loadedDesign.Pressed.Name, textDesign.Pressed.Name);
389				Assert.Equal(loadedDesign.Pressed.DrawLayer,
390					textDesign.Pressed.DrawLayer);
391				Assert.Equal(loadedDesign.Pressed.BlendColor,
392					textDesign.Hover.BlendColor);
393
394				// Text font
395				Assert.Equal(loadedDesign.TextFont.FamilyName,
396					textDesign.TextFont.FamilyName);
397				Assert.Equal(loadedDesign.DisabledTextFont.FamilyName,
398					textDesign.DisabledTextFont.FamilyName);
399				Assert.Equal(loadedDesign.TextFont.LineHeight,
400					textDesign.TextFont.LineHeight);
401
402				// Text colors
403				Assert.Equal(loadedDesign.TextFont.Color,
404					textDesign.TextFont.Color);
405				Assert.Equal(loadedDesign.DisabledTextFont.Color,
406					textDesign.DisabledTextFont.Color);
407			}
408			#endregion
409		}
410	}
411}