MultilineTextControl.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #region File Information
  2. //-----------------------------------------------------------------------------
  3. // AMultilineTextControl.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using Microsoft.Xna.Framework;
  15. using Microsoft.Xna.Framework.Graphics;
  16. using Microsoft.Xna.Framework.Content;
  17. using Microsoft.Xna.Framework.Input.Touch;
  18. #endregion
  19. namespace DynamicMenu.Controls
  20. {
  21. public class MultilineTextControl : TextControl
  22. {
  23. #region Fields
  24. protected const int HORZ_SPACE = 10;
  25. protected const int VERT_SPACE = 5;
  26. private int topSpace;
  27. private int leftSpace;
  28. private List<string> lines = new List<string>();
  29. #endregion
  30. #region Properties
  31. /// <summary>
  32. /// The strings currently being shown by the text control
  33. /// </summary>
  34. [ContentSerializerIgnore]
  35. public List<string> Lines
  36. {
  37. get { return lines; }
  38. }
  39. /// <summary>
  40. /// The amount of space between the top of the control and the first line of text
  41. /// </summary>
  42. [ContentSerializerIgnore]
  43. public int TopSpace
  44. {
  45. get { return topSpace; }
  46. set { topSpace = value; }
  47. }
  48. /// <summary>
  49. /// The amount of space between the left of the control and the text
  50. /// </summary>
  51. [ContentSerializerIgnore]
  52. public int LeftSpace
  53. {
  54. get { return leftSpace; }
  55. set { leftSpace = value; }
  56. }
  57. #endregion
  58. #region Initialization
  59. /// <summary>
  60. /// Loads this control's content
  61. /// </summary>
  62. public override void LoadContent(GraphicsDevice _graphics, ContentManager _content)
  63. {
  64. base.LoadContent(_graphics, _content);
  65. // Now wrap the text to fit the control
  66. CalculateLines();
  67. }
  68. #endregion
  69. #region Draw
  70. /// <summary>
  71. /// Draws this control
  72. /// </summary>
  73. public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
  74. {
  75. base.Draw(gameTime, spriteBatch);
  76. if (Font == null)
  77. {
  78. // No font was loaded, so we can't show text
  79. return;
  80. }
  81. Vector2 extents = Font.MeasureString("A");
  82. Point topLeft = GetAbsoluteTopLeft();
  83. int currY = topLeft.Y + topSpace + VERT_SPACE;
  84. int left = topLeft.X + leftSpace + HORZ_SPACE;
  85. foreach (string line in lines)
  86. {
  87. if (String.IsNullOrEmpty(line))
  88. {
  89. continue;
  90. }
  91. Vector2 origin = Vector2.Zero;
  92. spriteBatch.DrawString(Font, line, new Vector2(left, currY),
  93. TextColor, 0, origin, 1, SpriteEffects.None, 1.0f);
  94. currY += (int)extents.Y + VERT_SPACE;
  95. }
  96. }
  97. #endregion
  98. #region Methods
  99. /// <summary>
  100. /// Determines how to wrap text in this control based on its size
  101. /// </summary>
  102. public virtual void CalculateLines()
  103. {
  104. lines.Clear();
  105. if (string.IsNullOrEmpty(Text))
  106. {
  107. return;
  108. }
  109. Text.Trim();
  110. int lineWidth = Width - HORZ_SPACE * 2 - leftSpace;
  111. // Divide the text into words
  112. string[] strArray = Text.Split(new Char[] { ' ', '\n' });
  113. string lineStr = "";
  114. if (Font == null)
  115. {
  116. // No font - can't calculate the lines
  117. return;
  118. }
  119. foreach (string str in strArray)
  120. {
  121. if (str.Length == 0) continue;
  122. string tempStr = lineStr;
  123. //Add a space if we aren't at the beginning of the line
  124. if (tempStr.Length != 0)
  125. {
  126. tempStr += " ";
  127. }
  128. tempStr += str;
  129. Vector2 extents = Font.MeasureString(tempStr);
  130. if (extents.X > lineWidth)
  131. {
  132. // Reached the end of the line. End the current line and start
  133. // the next with the current word
  134. lines.Add(lineStr);
  135. lineStr = str;
  136. }
  137. else
  138. {
  139. // Add the word to the line
  140. lineStr = tempStr;
  141. }
  142. }
  143. // See if there is one more line to add
  144. if (lineStr.Length > 0)
  145. {
  146. lines.Add(lineStr);
  147. }
  148. }
  149. #endregion
  150. }
  151. }