using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RhythmBullet.Utilities.Camera; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RhythmBullet.UI.Modular.Modules { public class TextLabel : UIModule { private SpriteFont font; private float scale; private Vector2 position; private string originalText; private string displayedText; private Vector2 modifiedTextSize; public bool autoWrap; public bool autoScale; public bool useEllipses; public string ellipsis = "..."; private string ModifiedText { get { return displayedText; } set { displayedText = value; modifiedTextSize = font.MeasureString(value); } } public string Text { get { return originalText; } set { modifiedTextSize = font.MeasureString(value); originalText = value; displayedText = value; } } public TextLabel(string text, SpriteFont font, int height) { Text = text; bounds.Height = height; this.font = font; } public override void Update(GameTime gameTime) { position.X = bounds.X; position.Y = bounds.Y; if (useEllipses) AttemptToApplyEllipsis(); if (autoWrap) AttemptToWrapText(); if (autoScale) AttemptToScaleFont(); base.Update(gameTime); } public override void Draw(SpriteBatch batch) { batch.DrawString(font, Text, position, color, 0f, origin, scale, SpriteEffects.None, 0f); base.Draw(batch); } public void AttemptToApplyEllipsis() { if (modifiedTextSize.X * scale > bounds.Width && ModifiedText.Length > ellipsis.Length + 1) { RemoveLineBreaks(); StringBuilder stringBuilder = new StringBuilder(ModifiedText); do { stringBuilder.Remove(stringBuilder.Length, ellipsis.Length - 1); stringBuilder.Insert(stringBuilder.Length, ellipsis); } while (font.MeasureString(stringBuilder).X *scale > bounds.Width); ModifiedText = stringBuilder.ToString(); } } public void AttemptToScaleFont() { if (modifiedTextSize.X * scale > bounds.Width || modifiedTextSize.X * scale < bounds.Width) { scale = bounds.Width / modifiedTextSize.X; } if (modifiedTextSize.Y * scale > bounds.Height || modifiedTextSize.Y * scale > bounds.Height) { scale = bounds.Height / modifiedTextSize.Y; } } public void RemoveLineBreaks() { ModifiedText = ModifiedText.Replace("\n", " "); } public void ResetToOriginalText() { ModifiedText = originalText; } public void AttemptToWrapText(bool unwrap = false) { if (unwrap) RemoveLineBreaks(); if (modifiedTextSize.X * scale > bounds.Width) { ModifiedText = ModifiedText.Replace("\n", " "); string[] words = ModifiedText.Split(' '); StringBuilder stringBuilder = new StringBuilder(); float currentScaledLineWidth = 0f; for (int w = 0; w < words.Length; w++) { string word = words[w]; float scaledWidth = font.MeasureString(word).X * scale; if (currentScaledLineWidth + scaledWidth <= bounds.Width) { stringBuilder.Append(word); currentScaledLineWidth += scaledWidth; } else { stringBuilder.AppendLine(); currentScaledLineWidth = 0; } } ModifiedText = stringBuilder.ToString(); } } } }