From e9cc9b7d997443f9add5208b05a5225a5d211026 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Thu, 21 May 2020 12:53:42 +0200 Subject: [PATCH] document raw content and text formatting --- MLEM/Content/RawContentManager.cs | 3 ++ MLEM/Content/RawContentReader.cs | 8 +-- MLEM/Content/SongReader.cs | 3 ++ MLEM/Content/SoundEffectReader.cs | 3 ++ MLEM/Content/Texture2DReader.cs | 3 ++ MLEM/Content/XmlReader.cs | 4 ++ MLEM/Extensions/ColorExtensions.cs | 3 ++ MLEM/Extensions/GraphicsExtensions.cs | 3 ++ MLEM/Extensions/NumberExtensions.cs | 3 ++ MLEM/Extensions/RandomExtensions.cs | 3 ++ MLEM/Extensions/SoundExtensions.cs | 7 +++ MLEM/Extensions/SpriteBatchExtensions.cs | 3 ++ MLEM/Font/GenericFont.cs | 15 ++++++ MLEM/Font/GenericSpriteFont.cs | 3 ++ MLEM/Formatting/Codes/AnimatedCode.cs | 3 ++ MLEM/Formatting/Codes/Code.cs | 45 ++++++++++++++++ MLEM/Formatting/Codes/ColorCode.cs | 3 ++ MLEM/Formatting/Codes/FontCode.cs | 4 ++ MLEM/Formatting/Codes/ImageCode.cs | 16 ++++++ MLEM/Formatting/Codes/LinkCode.cs | 7 +++ MLEM/Formatting/Codes/ShadowCode.cs | 3 ++ MLEM/Formatting/Codes/UnderlineCode.cs | 3 ++ MLEM/Formatting/Codes/WobblyCode.cs | 8 +++ MLEM/Formatting/TextFormatter.cs | 17 +++++++ MLEM/Formatting/Token.cs | 65 +++++++++++++++++++++++- MLEM/Formatting/TokenizedString.cs | 43 +++++++++++++++- 26 files changed, 275 insertions(+), 6 deletions(-) diff --git a/MLEM/Content/RawContentManager.cs b/MLEM/Content/RawContentManager.cs index 783f934..1e970d1 100644 --- a/MLEM/Content/RawContentManager.cs +++ b/MLEM/Content/RawContentManager.cs @@ -57,6 +57,7 @@ namespace MLEM.Content { return reader; } + /// protected override void ReloadAsset(string originalAssetName, T currentAsset) { this.Read(originalAssetName, currentAsset); } @@ -80,6 +81,7 @@ namespace MLEM.Content { throw new ContentLoadException($"Asset {assetName} not found"); } + /// public override void Unload() { foreach (var d in this.disposableAssets) d.Dispose(); @@ -87,6 +89,7 @@ namespace MLEM.Content { base.Unload(); } + /// public void Initialize() { } diff --git a/MLEM/Content/RawContentReader.cs b/MLEM/Content/RawContentReader.cs index 8bad0ed..cf16e56 100644 --- a/MLEM/Content/RawContentReader.cs +++ b/MLEM/Content/RawContentReader.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using Microsoft.Xna.Framework.Content; namespace MLEM.Content { /// @@ -11,14 +12,14 @@ namespace MLEM.Content { /// Returns if the given type can be loaded by this content reader /// /// The type of asset - /// If can be loaded by this content reader + /// If the type can be loaded by this content reader public abstract bool CanRead(Type t); /// /// Reads the content file from disk and returns it. /// /// The that is loading the asset - /// The full path to the asset, starting from the + /// The full path to the asset, starting from the /// A stream that leads to this asset /// The type of asset to load /// If this asset is being reloaded, this value contains the previous version of the asset. @@ -50,9 +51,8 @@ namespace MLEM.Content { /// Reads the content file that is represented by our generic type from disk. /// /// The that is loading the asset - /// The full path to the asset, starting from the + /// The full path to the asset, starting from the /// A stream that leads to this asset - /// The type of asset to load /// If this asset is being reloaded, this value contains the previous version of the asset. /// The loaded asset protected abstract T Read(RawContentManager manager, string assetPath, Stream stream, T existing); diff --git a/MLEM/Content/SongReader.cs b/MLEM/Content/SongReader.cs index 4576068..a6a8864 100644 --- a/MLEM/Content/SongReader.cs +++ b/MLEM/Content/SongReader.cs @@ -3,12 +3,15 @@ using System.IO; using Microsoft.Xna.Framework.Media; namespace MLEM.Content { + /// public class SongReader : RawContentReader { + /// protected override Song Read(RawContentManager manager, string assetPath, Stream stream, Song existing) { return Song.FromUri(Path.GetFileNameWithoutExtension(assetPath), new Uri(assetPath)); } + /// public override string[] GetFileExtensions() { return new[] {"ogg", "wav", "mp3"}; } diff --git a/MLEM/Content/SoundEffectReader.cs b/MLEM/Content/SoundEffectReader.cs index 26411f6..fe68f53 100644 --- a/MLEM/Content/SoundEffectReader.cs +++ b/MLEM/Content/SoundEffectReader.cs @@ -3,12 +3,15 @@ using System.IO; using Microsoft.Xna.Framework.Audio; namespace MLEM.Content { + /// public class SoundEffectReader : RawContentReader { + /// protected override SoundEffect Read(RawContentManager manager, string assetPath, Stream stream, SoundEffect existing) { return SoundEffect.FromStream(stream); } + /// public override string[] GetFileExtensions() { return new[] {"ogg", "wav", "mp3"}; } diff --git a/MLEM/Content/Texture2DReader.cs b/MLEM/Content/Texture2DReader.cs index 391b79e..8342cbe 100644 --- a/MLEM/Content/Texture2DReader.cs +++ b/MLEM/Content/Texture2DReader.cs @@ -2,8 +2,10 @@ using System.IO; using Microsoft.Xna.Framework.Graphics; namespace MLEM.Content { + /// public class Texture2DReader : RawContentReader { + /// protected override Texture2D Read(RawContentManager manager, string assetPath, Stream stream, Texture2D existing) { if (existing != null) { existing.Reload(stream); @@ -13,6 +15,7 @@ namespace MLEM.Content { } } + /// public override string[] GetFileExtensions() { return new[] {"png", "bmp", "gif", "jpg", "tif", "dds"}; } diff --git a/MLEM/Content/XmlReader.cs b/MLEM/Content/XmlReader.cs index 28b6833..85998d0 100644 --- a/MLEM/Content/XmlReader.cs +++ b/MLEM/Content/XmlReader.cs @@ -3,16 +3,20 @@ using System.IO; using System.Xml.Serialization; namespace MLEM.Content { + /// public class XmlReader : RawContentReader { + /// public override bool CanRead(Type t) { return true; } + /// public override object Read(RawContentManager manager, string assetPath, Stream stream, Type t, object existing) { return new XmlSerializer(t).Deserialize(stream); } + /// public override string[] GetFileExtensions() { return new[] {"xml"}; } diff --git a/MLEM/Extensions/ColorExtensions.cs b/MLEM/Extensions/ColorExtensions.cs index 135c7a1..bd1feea 100644 --- a/MLEM/Extensions/ColorExtensions.cs +++ b/MLEM/Extensions/ColorExtensions.cs @@ -3,6 +3,9 @@ using System.Globalization; using Microsoft.Xna.Framework; namespace MLEM.Extensions { + /// + /// A set of extensions for dealing with objects + /// public static class ColorExtensions { /// diff --git a/MLEM/Extensions/GraphicsExtensions.cs b/MLEM/Extensions/GraphicsExtensions.cs index bd2240f..e5fc78b 100644 --- a/MLEM/Extensions/GraphicsExtensions.cs +++ b/MLEM/Extensions/GraphicsExtensions.cs @@ -4,6 +4,9 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace MLEM.Extensions { + /// + /// A set of extensions for dealing with and + /// public static class GraphicsExtensions { private static int lastWidth; diff --git a/MLEM/Extensions/NumberExtensions.cs b/MLEM/Extensions/NumberExtensions.cs index 1bddce4..beb7843 100644 --- a/MLEM/Extensions/NumberExtensions.cs +++ b/MLEM/Extensions/NumberExtensions.cs @@ -3,6 +3,9 @@ using Microsoft.Xna.Framework; using MLEM.Misc; namespace MLEM.Extensions { + /// + /// A set of extensions for dealing with , , , , , and + /// public static class NumberExtensions { /// diff --git a/MLEM/Extensions/RandomExtensions.cs b/MLEM/Extensions/RandomExtensions.cs index 3fec383..783f7c2 100644 --- a/MLEM/Extensions/RandomExtensions.cs +++ b/MLEM/Extensions/RandomExtensions.cs @@ -3,6 +3,9 @@ using System.Collections.Generic; using System.Linq; namespace MLEM.Extensions { + /// + /// A set of extensions for dealing with + /// public static class RandomExtensions { /// diff --git a/MLEM/Extensions/SoundExtensions.cs b/MLEM/Extensions/SoundExtensions.cs index 362e915..a080d47 100644 --- a/MLEM/Extensions/SoundExtensions.cs +++ b/MLEM/Extensions/SoundExtensions.cs @@ -2,8 +2,15 @@ using System; using Microsoft.Xna.Framework.Audio; namespace MLEM.Extensions { + /// + /// A set of extensions for dealing wiht + /// public static class SoundExtensions { + /// + /// Stops and plays a sound effect instance in one call + /// + /// The sound to stop and play [Obsolete("When using the .NET Core version of MonoGame, the replay issue has been fixed. Just call Play() instead.")] public static void Replay(this SoundEffectInstance sound) { sound.Stop(); diff --git a/MLEM/Extensions/SpriteBatchExtensions.cs b/MLEM/Extensions/SpriteBatchExtensions.cs index 71ae5e1..93be9ca 100644 --- a/MLEM/Extensions/SpriteBatchExtensions.cs +++ b/MLEM/Extensions/SpriteBatchExtensions.cs @@ -4,6 +4,9 @@ using MLEM.Misc; using MLEM.Textures; namespace MLEM.Extensions { + /// + /// A set of extensions for dealing with + /// public static class SpriteBatchExtensions { private static Texture2D blankTexture; diff --git a/MLEM/Font/GenericFont.cs b/MLEM/Font/GenericFont.cs index 9b75b55..de07a0d 100644 --- a/MLEM/Font/GenericFont.cs +++ b/MLEM/Font/GenericFont.cs @@ -171,11 +171,26 @@ namespace MLEM.Font { } + /// + /// An enum that represents the text alignment options for + /// public enum TextAlign { + /// + /// The text is aligned as normal + /// Left, + /// + /// The position passed represents the center of the resulting string in the x axis + /// Center, + /// + /// The position passed represents the right edge of the resulting string + /// Right, + /// + /// The position passed represents the center of the resulting string, both in the x and y axes + /// CenterBothAxes } diff --git a/MLEM/Font/GenericSpriteFont.cs b/MLEM/Font/GenericSpriteFont.cs index 68de774..1ded08f 100644 --- a/MLEM/Font/GenericSpriteFont.cs +++ b/MLEM/Font/GenericSpriteFont.cs @@ -8,6 +8,9 @@ namespace MLEM.Font { /// public class GenericSpriteFont : GenericFont { + /// + /// The that is being wrapped by this generic font + /// public readonly SpriteFont Font; /// public override GenericFont Bold { get; } diff --git a/MLEM/Formatting/Codes/AnimatedCode.cs b/MLEM/Formatting/Codes/AnimatedCode.cs index de4dd56..1ddd4be 100644 --- a/MLEM/Formatting/Codes/AnimatedCode.cs +++ b/MLEM/Formatting/Codes/AnimatedCode.cs @@ -1,11 +1,14 @@ using System.Text.RegularExpressions; namespace MLEM.Formatting.Codes { + /// public class AnimatedCode : Code { + /// public AnimatedCode(Match match, Regex regex) : base(match, regex) { } + /// public override bool EndsHere(Code other) { return other is AnimatedCode; } diff --git a/MLEM/Formatting/Codes/Code.cs b/MLEM/Formatting/Codes/Code.cs index 09d1505..2ffd8e8 100644 --- a/MLEM/Formatting/Codes/Code.cs +++ b/MLEM/Formatting/Codes/Code.cs @@ -5,43 +5,88 @@ using MLEM.Font; using MLEM.Misc; namespace MLEM.Formatting.Codes { + /// + /// An instance of a formatting code that can be used for a . + /// To add a new formatting code, see + /// public class Code : GenericDataHolder { + /// + /// The regex that this code was created from + /// public readonly Regex Regex; + /// + /// The match that this code encompasses + /// public readonly Match Match; + /// + /// The token that this formatting code is a part of + /// public Token Token { get; internal set; } + /// + /// Creates a new formatting code based on a formatting code regex and its match. + /// + /// The match + /// The regex protected Code(Match match, Regex regex) { this.Match = match; this.Regex = regex; } + /// + /// Returns whether this formatting code should end when the passed formatting code starts. + /// If this method returns true, a new is started at its position. + /// + /// The code that is started here + /// If this code should end public virtual bool EndsHere(Code other) { return other.GetType() == this.GetType(); } + /// public virtual Color? GetColor(Color defaultPick) { return null; } + /// public virtual GenericFont GetFont(GenericFont defaultPick) { return null; } + /// + /// Update this formatting code's animations etc. + /// + /// The game's time public virtual void Update(GameTime time) { } + /// + /// Returns the string that this formatting code should be replaced with. + /// Usually, you'll just want an empty string here, but some formatting codes (like ) require their space to be filled by spaces. + /// + /// The font that is used + /// The replacement string for this formatting code public virtual string GetReplacementString(GenericFont font) { return string.Empty; } + /// public virtual bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { return false; } + /// public virtual void DrawSelf(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) { } + /// + /// Creates a new formatting code from the given regex and regex match. + /// + /// + /// The text formatter that created this code + /// The match for the code's regex + /// The regex used to create this code public delegate Code Constructor(TextFormatter formatter, Match match, Regex regex); } diff --git a/MLEM/Formatting/Codes/ColorCode.cs b/MLEM/Formatting/Codes/ColorCode.cs index 4b51a16..4f3a4b6 100644 --- a/MLEM/Formatting/Codes/ColorCode.cs +++ b/MLEM/Formatting/Codes/ColorCode.cs @@ -2,14 +2,17 @@ using System.Text.RegularExpressions; using Microsoft.Xna.Framework; namespace MLEM.Formatting.Codes { + /// public class ColorCode : Code { private readonly Color? color; + /// public ColorCode(Match match, Regex regex, Color? color) : base(match, regex) { this.color = color; } + /// public override Color? GetColor(Color defaultPick) { return this.color; } diff --git a/MLEM/Formatting/Codes/FontCode.cs b/MLEM/Formatting/Codes/FontCode.cs index c81824b..dc8d306 100644 --- a/MLEM/Formatting/Codes/FontCode.cs +++ b/MLEM/Formatting/Codes/FontCode.cs @@ -3,18 +3,22 @@ using System.Text.RegularExpressions; using MLEM.Font; namespace MLEM.Formatting.Codes { + /// public class FontCode : Code { private readonly Func font; + /// public FontCode(Match match, Regex regex, Func font) : base(match, regex) { this.font = font; } + /// public override GenericFont GetFont(GenericFont defaultPick) { return this.font?.Invoke(defaultPick); } + /// public override bool EndsHere(Code other) { return other is FontCode; } diff --git a/MLEM/Formatting/Codes/ImageCode.cs b/MLEM/Formatting/Codes/ImageCode.cs index 5f1cb69..5557c2f 100644 --- a/MLEM/Formatting/Codes/ImageCode.cs +++ b/MLEM/Formatting/Codes/ImageCode.cs @@ -9,20 +9,24 @@ using MLEM.Misc; using MLEM.Textures; namespace MLEM.Formatting.Codes { + /// public class ImageCode : Code { private readonly SpriteAnimation image; private string replacement; private float gapSize; + /// public ImageCode(Match match, Regex regex, SpriteAnimation image) : base(match, regex) { this.image = image; } + /// public override bool EndsHere(Code other) { return true; } + /// public override string GetReplacementString(GenericFont font) { if (this.replacement == null) { // use non-breaking space so that the image won't be line-splitted @@ -33,10 +37,12 @@ namespace MLEM.Formatting.Codes { return this.replacement; } + /// public override void Update(GameTime time) { this.image.Update(time); } + /// public override void DrawSelf(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) { var position = pos + new Vector2(this.gapSize - font.LineHeight, 0) / 2 * scale; batch.Draw(this.image.CurrentRegion, new RectangleF(position, new Vector2(font.LineHeight * scale)), Color.White.CopyAlpha(color)); @@ -44,12 +50,22 @@ namespace MLEM.Formatting.Codes { } + /// + /// A set of extensions that allow easily adding image formatting codes to a text formatter. + /// public static class ImageCodeExtensions { + /// + /// Adds a new image formatting code to the given text formatter + /// + /// The formatter to add the code to + /// The name of the formatting code. The regex for this code will be between angle brackets. + /// The image to render at the code's position public static void AddImage(this TextFormatter formatter, string name, TextureRegion image) { formatter.AddImage(name, new SpriteAnimation(1, image)); } + /// public static void AddImage(this TextFormatter formatter, string name, SpriteAnimation image) { formatter.Codes.Add(new Regex($""), (f, m, r) => new ImageCode(m, r, image)); } diff --git a/MLEM/Formatting/Codes/LinkCode.cs b/MLEM/Formatting/Codes/LinkCode.cs index d102c82..10d5c26 100644 --- a/MLEM/Formatting/Codes/LinkCode.cs +++ b/MLEM/Formatting/Codes/LinkCode.cs @@ -5,18 +5,25 @@ using Microsoft.Xna.Framework.Graphics; using MLEM.Font; namespace MLEM.Formatting.Codes { + /// public class LinkCode : UnderlineCode { private readonly Func isSelected; + /// public LinkCode(Match match, Regex regex, float thickness, float yOffset, Func isSelected) : base(match, regex, thickness, yOffset) { this.isSelected = isSelected; } + /// + /// Returns true if this link formatting code is currently selected or hovered over, based on the selection function. + /// + /// True if this code is currently selected public virtual bool IsSelected() { return this.isSelected(this.Token); } + /// public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { // since we inherit from UnderlineCode, we can just call base if selected return this.IsSelected() && base.DrawCharacter(time, batch, c, cString, indexInToken, ref pos, font, ref color, ref scale, depth); diff --git a/MLEM/Formatting/Codes/ShadowCode.cs b/MLEM/Formatting/Codes/ShadowCode.cs index 53077ab..c50a086 100644 --- a/MLEM/Formatting/Codes/ShadowCode.cs +++ b/MLEM/Formatting/Codes/ShadowCode.cs @@ -5,16 +5,19 @@ using MLEM.Extensions; using MLEM.Font; namespace MLEM.Formatting.Codes { + /// public class ShadowCode : FontCode { private readonly Color color; private readonly Vector2 offset; + /// public ShadowCode(Match match, Regex regex, Color color, Vector2 offset) : base(match, regex, null) { this.color = color; this.offset = offset; } + /// public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { font.DrawString(batch, cString, pos + this.offset * scale, this.color.CopyAlpha(color), 0, Vector2.Zero, scale, SpriteEffects.None, depth); // we return false since we still want regular drawing to occur diff --git a/MLEM/Formatting/Codes/UnderlineCode.cs b/MLEM/Formatting/Codes/UnderlineCode.cs index 9855a29..c5aa633 100644 --- a/MLEM/Formatting/Codes/UnderlineCode.cs +++ b/MLEM/Formatting/Codes/UnderlineCode.cs @@ -6,16 +6,19 @@ using MLEM.Font; using MLEM.Misc; namespace MLEM.Formatting.Codes { + /// public class UnderlineCode : FontCode { private readonly float thickness; private readonly float yOffset; + /// public UnderlineCode(Match match, Regex regex, float thickness, float yOffset) : base(match, regex, null) { this.thickness = thickness; this.yOffset = yOffset; } + /// public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { // don't underline spaces at the end of lines if (c == ' ' && this.Token.DisplayString.Length > indexInToken + 1 && this.Token.DisplayString[indexInToken + 1] == '\n') diff --git a/MLEM/Formatting/Codes/WobblyCode.cs b/MLEM/Formatting/Codes/WobblyCode.cs index c016099..6723605 100644 --- a/MLEM/Formatting/Codes/WobblyCode.cs +++ b/MLEM/Formatting/Codes/WobblyCode.cs @@ -5,21 +5,29 @@ using Microsoft.Xna.Framework.Graphics; using MLEM.Font; namespace MLEM.Formatting.Codes { + /// public class WobblyCode : AnimatedCode { private readonly float modifier; private readonly float heightModifier; + /// + /// The time that this wobbly animation has been running for. + /// To reset its animation progress, reset this value. + /// public TimeSpan TimeIntoAnimation; + /// public WobblyCode(Match match, Regex regex, float modifier, float heightModifier) : base(match, regex) { this.modifier = modifier; this.heightModifier = heightModifier; } + /// public override void Update(GameTime time) { this.TimeIntoAnimation += time.ElapsedGameTime; } + /// public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { var offset = new Vector2(0, (float) Math.Sin(this.Token.Index + indexInToken + this.TimeIntoAnimation.TotalSeconds * this.modifier) * font.LineHeight * this.heightModifier * scale); pos += offset; diff --git a/MLEM/Formatting/TextFormatter.cs b/MLEM/Formatting/TextFormatter.cs index 3e6ddc2..c36065a 100644 --- a/MLEM/Formatting/TextFormatter.cs +++ b/MLEM/Formatting/TextFormatter.cs @@ -10,10 +10,21 @@ using MLEM.Formatting.Codes; using MLEM.Misc; namespace MLEM.Formatting { + /// + /// A text formatter is used for drawing text using that contains different colors, bold/italic sections and animations. + /// To format a string of text, use the codes as specified in the constructor. To tokenize and render a formatted string, use . + /// public class TextFormatter : GenericDataHolder { + /// + /// The formatting codes that this text formatter uses. + /// The defines how the formatting code should be matched. + /// public readonly Dictionary Codes = new Dictionary(); + /// + /// Creates a new text formatter with a set of default formatting codes. + /// public TextFormatter() { // font codes this.Codes.Add(new Regex(""), (f, m, r) => new FontCode(m, r, fnt => fnt.Bold)); @@ -37,6 +48,12 @@ namespace MLEM.Formatting { this.Codes.Add(new Regex(""), (f, m, r) => new AnimatedCode(m, r)); } + /// + /// Tokenizes a string, returning a tokenized string that is ready for splitting, measuring and drawing. + /// + /// The font to use for tokenization. Note that this font needs to be the same that will later be used for splitting, measuring and/or drawing. + /// The string to tokenize + /// public TokenizedString Tokenize(GenericFont font, string s) { var tokens = new List(); var codes = new List(); diff --git a/MLEM/Formatting/Token.cs b/MLEM/Formatting/Token.cs index da09e93..c91bdba 100644 --- a/MLEM/Formatting/Token.cs +++ b/MLEM/Formatting/Token.cs @@ -8,18 +8,39 @@ using MLEM.Formatting.Codes; using MLEM.Misc; namespace MLEM.Formatting { + /// + /// A part of a that has a certain list of formatting codes applied. + /// public class Token : GenericDataHolder { + /// + /// The formatting codes that are applied on this token. + /// public readonly Code[] AppliedCodes; + /// + /// The index in the that this token starts at. + /// public readonly int Index; + /// + /// The index in the that this token starts at. + /// public readonly int RawIndex; + /// + /// The substring that this token contains. + /// public readonly string Substring; + /// + /// The string that is displayed by this token. If the tokenized string has been split, this string will contain the newline characters. + /// public string DisplayString => this.SplitSubstring ?? this.Substring; + /// + /// The substring that this token contains, without the formatting codes removed. + /// public readonly string RawSubstring; internal RectangleF[] Area; internal string SplitSubstring; - public Token(Code[] appliedCodes, int index, int rawIndex, string substring, string rawSubstring) { + internal Token(Code[] appliedCodes, int index, int rawIndex, string substring, string rawSubstring) { this.AppliedCodes = appliedCodes; this.Index = index; this.RawIndex = rawIndex; @@ -30,19 +51,53 @@ namespace MLEM.Formatting { code.Token = this; } + /// + /// Get the color that this token will be rendered with + /// + /// The default color, if none is specified + /// The color to render with public Color? GetColor(Color defaultPick) { return this.AppliedCodes.Select(c => c.GetColor(defaultPick)).FirstOrDefault(c => c.HasValue); } + /// + /// Get the font that this token will be rendered with + /// + /// The default font, if none is specified + /// The font to render with public GenericFont GetFont(GenericFont defaultPick) { return this.AppliedCodes.Select(c => c.GetFont(defaultPick)).FirstOrDefault(f => f != null); } + /// + /// Draws the token itself, including all of the instances that this token contains. + /// Note that, to draw the token's actual string, is used. + /// + /// The time + /// The sprite batch to use + /// The position to draw the token at + /// The font to use to draw + /// The color to draw with + /// The scale to draw at + /// The depth to draw at public void DrawSelf(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) { foreach (var code in this.AppliedCodes) code.DrawSelf(time, batch, pos, font, color, scale, depth); } + /// + /// Draws a given character using this token's formatting options. + /// + /// The time + /// The sprite batch to use + /// The character to draw + /// A single-character string that contains the character to draw + /// The index within this token that the character is at + /// The position to draw the token at + /// The font to use to draw + /// The color to draw with + /// The scale to draw at + /// The depth to draw at public void DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, Vector2 pos, GenericFont font, Color color, float scale, float depth) { foreach (var code in this.AppliedCodes) { if (code.DrawCharacter(time, batch, c, cString, indexInToken, ref pos, font, ref color, ref scale, depth)) @@ -53,6 +108,14 @@ namespace MLEM.Formatting { font.DrawString(batch, cString, pos, color, 0, Vector2.Zero, scale, SpriteEffects.None, depth); } + /// + /// Gets a list of rectangles that encompass this token's area. + /// Note that more than one rectangle is only returned if the string has been split. + /// This can be used to invoke events when the mouse is hovered over the token, for example. + /// + /// The position that the string is drawn at + /// The scale that the string is drawn at + /// A set of rectangles that this token contains public IEnumerable GetArea(Vector2 stringPos, float scale) { return this.Area.Select(a => new RectangleF(stringPos + a.Location * scale, a.Size * scale)); } diff --git a/MLEM/Formatting/TokenizedString.cs b/MLEM/Formatting/TokenizedString.cs index f6e574d..36e4ed8 100644 --- a/MLEM/Formatting/TokenizedString.cs +++ b/MLEM/Formatting/TokenizedString.cs @@ -9,16 +9,36 @@ using MLEM.Formatting.Codes; using MLEM.Misc; namespace MLEM.Formatting { + /// + /// A tokenized string that was created using a + /// public class TokenizedString : GenericDataHolder { + /// + /// The raw string that was used to create this tokenized string. + /// public readonly string RawString; + /// + /// The , but with formatting codes stripped out. + /// public readonly string String; + /// + /// The string that is actually displayed by this tokenized string. + /// If this string has been , this string will contain the newline characters. + /// public string DisplayString => this.splitString ?? this.String; + /// + /// The tokens that this tokenized string contains. + /// public readonly Token[] Tokens; + /// + /// All of the formatting codes that are applied over this tokenized string. + /// Note that, to get a formatting code for a certain token, use + /// public readonly Code[] AllCodes; private string splitString; - public TokenizedString(GenericFont font, string rawString, string strg, Token[] tokens) { + internal TokenizedString(GenericFont font, string rawString, string strg, Token[] tokens) { this.RawString = rawString; this.String = strg; this.Tokens = tokens; @@ -27,6 +47,13 @@ namespace MLEM.Formatting { this.CalculateTokenAreas(font); } + /// + /// Splits this tokenized string, inserting newline characters if the width of the string is bigger than the maximum width. + /// + /// + /// The font to use for width calculations + /// The maximum width + /// The scale to use fr width calculations public void Split(GenericFont font, float width, float scale) { // a split string has the same character count as the input string // but with newline characters added @@ -57,19 +84,33 @@ namespace MLEM.Formatting { this.CalculateTokenAreas(font); } + /// public Vector2 Measure(GenericFont font) { return font.MeasureString(this.DisplayString); } + /// + /// Updates the formatting codes in this formatted string, causing animations to animate etc. + /// + /// The game's time public void Update(GameTime time) { foreach (var code in this.AllCodes) code.Update(time); } + /// + /// Returns the token under the given position. + /// This can be used for hovering effects when the mouse is over a token, etc. + /// + /// The position that the string is drawn at + /// The position to use for checking the token + /// The scale that the string is drawn at + /// The token under the target position public Token GetTokenUnderPos(Vector2 stringPos, Vector2 target, float scale) { return this.Tokens.FirstOrDefault(t => t.GetArea(stringPos, scale).Any(r => r.Contains(target))); } + /// public void Draw(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) { var innerOffset = new Vector2(); foreach (var token in this.Tokens) {