diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs
index c73fc33..fd9b10a 100644
--- a/MLEM.Ui/Elements/Paragraph.cs
+++ b/MLEM.Ui/Elements/Paragraph.cs
@@ -32,7 +32,13 @@ namespace MLEM.Ui.Elements {
///
/// The tokenized version of the
///
- public TokenizedString TokenizedText { get; private set; }
+ public TokenizedString TokenizedText {
+ get {
+ this.CheckTextChange();
+ this.TokenizeIfNecessary();
+ return this.tokenizedText;
+ }
+ }
///
/// The color that the text will be rendered with
///
@@ -53,14 +59,10 @@ namespace MLEM.Ui.Elements {
///
public string Text {
get {
- var ret = this.GetTextCallback?.Invoke(this) ?? this.text;
- this.CheckTextChange(ret);
- return ret;
- }
- set {
- this.text = value;
- this.CheckTextChange(value);
+ this.CheckTextChange();
+ return this.displayedText;
}
+ set => this.explicitlySetText = value;
}
///
/// If this paragraph should automatically adjust its width based on the width of the text within it
@@ -100,10 +102,11 @@ namespace MLEM.Ui.Elements {
///
public override bool IsHidden => base.IsHidden || string.IsNullOrWhiteSpace(this.Text);
- private string text;
- private string lastText;
+ private string displayedText;
+ private string explicitlySetText;
private StyleProp alignment;
private StyleProp regularFont;
+ private TokenizedString tokenizedText;
///
/// Creates a new paragraph with the given settings.
@@ -127,16 +130,15 @@ namespace MLEM.Ui.Elements {
///
protected override Vector2 CalcActualSize(RectangleF parentArea) {
var size = base.CalcActualSize(parentArea);
- this.ParseText(size);
- var textSize = this.TokenizedText.GetArea(Vector2.Zero, this.TextScale * this.TextScaleMultiplier * this.Scale).Size;
+ this.AlignAndSplit(size);
+ var textSize = this.tokenizedText.GetArea(Vector2.Zero, this.TextScale * this.TextScaleMultiplier * this.Scale).Size;
return new Vector2(this.AutoAdjustWidth ? textSize.X + this.ScaledPadding.Width : size.X, textSize.Y + this.ScaledPadding.Height);
}
///
public override void Update(GameTime time) {
base.Update(time);
- if (this.TokenizedText != null)
- this.TokenizedText.Update(time);
+ this.TokenizedText?.Update(time);
}
///
@@ -157,47 +159,19 @@ namespace MLEM.Ui.Elements {
this.Alignment = this.Alignment.OrStyle(style.TextAlignment);
}
- ///
- /// Parses this paragraph's into .
- /// Additionally, this method adds any elements for tokenized links in the text.
- ///
- /// The paragraph's default size
- protected virtual void ParseText(Vector2 size) {
- if (this.TokenizedText == null) {
- // tokenize the text
- this.TokenizedText = this.System.TextFormatter.Tokenize(this.RegularFont, this.Text, this.Alignment);
-
- // add links to the paragraph
- this.RemoveChildren(c => c is Link);
- foreach (var link in this.TokenizedText.Tokens.Where(t => t.AppliedCodes.Any(c => c is LinkCode)))
- this.AddChild(new Link(Anchor.TopLeft, link, this.TextScale * this.TextScaleMultiplier));
- }
-
- var width = size.X - this.ScaledPadding.Width;
- var scale = this.TextScale * this.TextScaleMultiplier * this.Scale;
- if (this.TruncateIfLong) {
- this.TokenizedText.Truncate(this.RegularFont, width, scale, this.Ellipsis, this.Alignment);
- } else {
- this.TokenizedText.Split(this.RegularFont, width, scale, this.Alignment);
- }
- }
-
- ///
- /// A helper method that causes the to be reset.
- /// Additionally, if this paragraph's area has changed enough to warrant it, or if it has any children.
- ///
- protected void SetTextDirty() {
- this.TokenizedText = null;
+ private void SetTextDirty() {
+ this.tokenizedText = null;
// only set our area dirty if our size changed as a result of this action
if (!this.AreaDirty && !this.CalcActualSize(this.ParentArea).Equals(this.DisplayArea.Size, Element.Epsilon))
this.SetAreaDirty();
}
- private void CheckTextChange(string newText) {
- if (this.lastText == newText)
+ private void CheckTextChange() {
+ var newText = this.GetTextCallback?.Invoke(this) ?? this.explicitlySetText;
+ if (this.displayedText == newText)
return;
- var emptyChanged = string.IsNullOrWhiteSpace(this.lastText) != string.IsNullOrWhiteSpace(newText);
- this.lastText = newText;
+ var emptyChanged = string.IsNullOrWhiteSpace(this.displayedText) != string.IsNullOrWhiteSpace(newText);
+ this.displayedText = newText;
if (emptyChanged)
this.SetAreaDirty();
this.SetTextDirty();
@@ -213,6 +187,30 @@ namespace MLEM.Ui.Elements {
return 0;
}
+ private void TokenizeIfNecessary() {
+ if (this.tokenizedText != null)
+ return;
+
+ // tokenize the text
+ this.tokenizedText = this.System.TextFormatter.Tokenize(this.RegularFont, this.Text, this.Alignment);
+
+ // add links to the paragraph
+ this.RemoveChildren(c => c is Link);
+ foreach (var link in this.tokenizedText.Tokens.Where(t => t.AppliedCodes.Any(c => c is LinkCode)))
+ this.AddChild(new Link(Anchor.TopLeft, link, this.TextScale * this.TextScaleMultiplier));
+ }
+
+ private void AlignAndSplit(Vector2 size) {
+ this.TokenizeIfNecessary();
+ var width = size.X - this.ScaledPadding.Width;
+ var scale = this.TextScale * this.TextScaleMultiplier * this.Scale;
+ if (this.TruncateIfLong) {
+ this.tokenizedText.Truncate(this.RegularFont, width, scale, this.Ellipsis, this.Alignment);
+ } else {
+ this.tokenizedText.Split(this.RegularFont, width, scale, this.Alignment);
+ }
+ }
+
///
/// A delegate method used for
///