diff --git a/CHANGELOG.md b/CHANGELOG.md
index 35c3d85..c0a785a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,7 @@ Improvements
- Increased TextFormatter macro recursion limit to 64
- Allow changing the default values used by default TextFormatter codes
- Allow setting ExternalGestureHandling through the InputHandler constructor
+- Allow specifying start and end indices when drawing a TokenizedString
Fixes
- Fixed control characters being included in TextInput
@@ -40,6 +41,7 @@ Additions
Improvements
- Increased Element area calculation recursion limit to 64
- Improved the SquishingGroup algorithm by prioritizing each element's final size
+- Allow specifying start and end indices when drawing a Paragraph
Fixes
- Fixed images not updating their hidden state properly when the displayed texture changes
diff --git a/Demos/TextFormattingDemo.cs b/Demos/TextFormattingDemo.cs
index 2170d56..95d1354 100644
--- a/Demos/TextFormattingDemo.cs
+++ b/Demos/TextFormattingDemo.cs
@@ -34,6 +34,8 @@ namespace Demos {
return TextFormattingDemo.DefaultScale * Math.Min(viewport.Width / 1280F, viewport.Height / 720F);
}
}
+ private int startIndex;
+ private int endIndex;
public TextFormattingDemo(MlemGame game) : base(game) {}
@@ -60,6 +62,7 @@ namespace Demos {
// we specify our text alignment here too, so that all data is cached correctly for display
this.tokenizedText = this.formatter.Tokenize(this.font, TextFormattingDemo.Text, TextAlignment.Center);
this.tokenizedText.Split(this.font, this.GraphicsDevice.Viewport.Width * TextFormattingDemo.WidthMultiplier, this.Scale, TextAlignment.Center);
+ this.endIndex = this.tokenizedText.String.Length;
}
public override void DoDraw(GameTime time) {
@@ -81,8 +84,8 @@ namespace Demos {
}
}
- // draw the text itself
- this.tokenizedText.Draw(time, this.SpriteBatch, pos, this.font, Color.White, this.Scale, 0);
+ // draw the text itself (start and end indices are optional)
+ this.tokenizedText.Draw(time, this.SpriteBatch, pos, this.font, Color.White, this.Scale, 0, this.startIndex, this.endIndex);
this.SpriteBatch.End();
}
@@ -90,8 +93,18 @@ namespace Demos {
public override void Update(GameTime time) {
// update our tokenized string to animate the animation codes
this.tokenizedText.Update(time);
+
+ // change some demo showcase info based on keybinds
if (this.InputHandler.IsPressed(Keys.B))
this.drawBounds = !this.drawBounds;
+ if (this.startIndex > 0 && this.InputHandler.IsDown(Keys.Left))
+ this.startIndex--;
+ if (this.startIndex < this.tokenizedText.String.Length && this.InputHandler.IsDown(Keys.Right))
+ this.startIndex++;
+ if (this.endIndex > 0 && this.InputHandler.IsDown(Keys.Down))
+ this.endIndex--;
+ if (this.endIndex < this.tokenizedText.String.Length && this.InputHandler.IsDown(Keys.Up))
+ this.endIndex++;
}
public override void Clear() {
diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs
index 1bd9eb1..a6950f8 100644
--- a/MLEM.Ui/Elements/Paragraph.cs
+++ b/MLEM.Ui/Elements/Paragraph.cs
@@ -139,6 +139,16 @@ namespace MLEM.Ui.Elements {
this.SetTextDirty();
}
}
+ ///
+ /// The inclusive index in this paragraph's to start drawing at.
+ /// This value is passed to .
+ ///
+ public int? DrawStartIndex;
+ ///
+ /// The exclusive index in this paragraph's to stop drawing at.
+ /// This value is passed to .
+ ///
+ public int? DrawEndIndex;
///
public override bool IsHidden => base.IsHidden || string.IsNullOrWhiteSpace(this.Text);
@@ -206,7 +216,7 @@ namespace MLEM.Ui.Elements {
var pos = this.DisplayArea.Location + new Vector2(this.GetAlignmentOffset(), 0);
var sc = this.TextScale * this.TextScaleMultiplier * this.Scale;
var color = this.TextColor.OrDefault(Color.White) * alpha;
- this.TokenizedText.Draw(time, batch, pos, this.RegularFont, color, sc, 0);
+ this.TokenizedText.Draw(time, batch, pos, this.RegularFont, color, sc, 0, this.DrawStartIndex, this.DrawEndIndex);
base.Draw(time, batch, alpha, context);
}
diff --git a/MLEM/Formatting/TokenizedString.cs b/MLEM/Formatting/TokenizedString.cs
index 54a30b7..db49998 100644
--- a/MLEM/Formatting/TokenizedString.cs
+++ b/MLEM/Formatting/TokenizedString.cs
@@ -189,29 +189,37 @@ namespace MLEM.Formatting {
}
///
- public void Draw(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) {
+ public void Draw(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth, int? startIndex = null, int? endIndex = null) {
var innerOffset = new Vector2(this.initialInnerOffset * scale, 0);
for (var t = 0; t < this.Tokens.Length; t++) {
var token = this.Tokens[t];
+ if (endIndex != null && token.Index >= endIndex)
+ return;
+
var drawFont = token.GetFont(font);
var drawColor = token.GetColor(color);
- token.DrawSelf(time, batch, pos + innerOffset, drawFont, drawColor, scale, depth);
+ if (startIndex == null || token.Index >= startIndex)
+ token.DrawSelf(time, batch, pos + innerOffset, drawFont, drawColor, scale, depth);
innerOffset.X += token.GetSelfWidth(drawFont) * scale;
var indexInToken = 0;
for (var l = 0; l < token.SplitDisplayString.Length; l++) {
- var charIndex = 0;
+ var cpsIndex = 0;
var line = new CodePointSource(token.SplitDisplayString[l]);
- while (charIndex < line.Length) {
- var (codePoint, length) = line.GetCodePoint(charIndex);
+ while (cpsIndex < line.Length) {
+ if (endIndex != null && token.Index + indexInToken >= endIndex)
+ return;
+
+ var (codePoint, length) = line.GetCodePoint(cpsIndex);
var character = CodePointSource.ToString(codePoint);
- token.DrawCharacter(time, batch, codePoint, character, indexInToken, pos + innerOffset, drawFont, drawColor, scale, depth);
+ if (startIndex == null || token.Index + indexInToken >= startIndex)
+ token.DrawCharacter(time, batch, codePoint, character, indexInToken, pos + innerOffset, drawFont, drawColor, scale, depth);
innerOffset.X += drawFont.MeasureString(character).X * scale;
- charIndex += length;
- indexInToken++;
+ indexInToken += length;
+ cpsIndex += length;
}
// only split at a new line, not between tokens!