diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33263eb..ca657d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,7 @@ Improvements
Fixes
- Fixed VerticalSpace height parameter being an integer
+- Fixed text not being pasted into a text field at all if it contains characters that don't match the input rule
## 5.1.0
### MLEM
diff --git a/MLEM.Ui/Elements/TextField.cs b/MLEM.Ui/Elements/TextField.cs
index ea2ec16..677f7f3 100644
--- a/MLEM.Ui/Elements/TextField.cs
+++ b/MLEM.Ui/Elements/TextField.cs
@@ -248,6 +248,146 @@ namespace MLEM.Ui.Elements {
}
}
+ ///
+ public override void Update(GameTime time) {
+ base.Update(time);
+
+ // handle first initialization if not done
+ if (this.displayedText == null)
+ this.HandleTextChange(false);
+
+ if (!this.IsSelected || this.IsHidden)
+ return;
+
+ if (this.Input.IsKeyPressed(Keys.Left)) {
+ this.CaretPos--;
+ } else if (this.Input.IsKeyPressed(Keys.Right)) {
+ this.CaretPos++;
+ } else if (this.Input.IsKeyPressed(Keys.Home)) {
+ this.CaretPos = 0;
+ } else if (this.Input.IsKeyPressed(Keys.End)) {
+ this.CaretPos = this.text.Length;
+ } else if (this.Input.IsModifierKeyDown(ModifierKey.Control)) {
+ if (this.Input.IsKeyPressed(Keys.V)) {
+ var clip = ClipboardService.GetText();
+ if (clip != null)
+ this.InsertText(clip, true);
+ } else if (this.Input.IsKeyPressed(Keys.C)) {
+ // until there is text selection, just copy the whole content
+ ClipboardService.SetText(this.Text);
+ }
+ }
+
+ this.caretBlinkTimer += time.ElapsedGameTime.TotalSeconds;
+ if (this.caretBlinkTimer >= 1)
+ this.caretBlinkTimer = 0;
+ }
+
+ ///
+ public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
+ var tex = this.Texture;
+ var color = Color.White * alpha;
+ if (this.IsMouseOver) {
+ tex = this.HoveredTexture.OrDefault(tex);
+ color = (Color) this.HoveredColor * alpha;
+ }
+ batch.Draw(tex, this.DisplayArea, color, this.Scale);
+
+ if (this.displayedText != null) {
+ var lineHeight = this.Font.Value.LineHeight * this.TextScale * this.Scale;
+ var offset = new Vector2(
+ this.TextOffsetX * this.Scale,
+ this.Multiline ? this.TextOffsetX * this.Scale : this.DisplayArea.Height / 2 - lineHeight / 2);
+ var textPos = this.DisplayArea.Location + offset;
+ if (this.text.Length > 0 || this.IsSelected) {
+ var textColor = this.TextColor.OrDefault(Color.White);
+ this.Font.Value.DrawString(batch, this.displayedText, textPos, textColor * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0);
+
+ if (this.IsSelected && this.caretBlinkTimer < 0.5F) {
+ var caretDrawPos = textPos + new Vector2(this.caretDrawOffset * this.TextScale * this.Scale, 0);
+ if (this.Multiline)
+ caretDrawPos.Y += this.Font.Value.LineHeight * (this.CaretLine - this.lineOffset) * this.TextScale * this.Scale;
+ batch.Draw(batch.GetBlankTexture(), new RectangleF(caretDrawPos, new Vector2(this.CaretWidth * this.Scale, lineHeight)), null, textColor * alpha);
+ }
+ } else if (this.PlaceholderText != null) {
+ this.Font.Value.DrawString(batch, this.PlaceholderText, textPos, this.PlaceholderColor.OrDefault(Color.Gray) * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0);
+ }
+ }
+ base.Draw(time, batch, alpha, blendState, samplerState, matrix);
+ }
+
+ ///
+ /// Replaces this text field's text with the given text.
+ /// If the resulting exceeds , the end will be cropped to fit.
+ ///
+ /// The new text
+ /// If any characters that don't match the should be left out
+ public void SetText(object text, bool removeMismatching = false) {
+ var strg = text?.ToString() ?? string.Empty;
+ if (!this.FilterText(ref strg, removeMismatching))
+ return;
+ if (this.MaximumCharacters != null && strg.Length > this.MaximumCharacters)
+ strg = strg.Substring(0, this.MaximumCharacters.Value);
+ this.text.Clear();
+ this.text.Append(strg);
+ this.CaretPos = this.text.Length;
+ this.HandleTextChange();
+ }
+
+ ///
+ /// Inserts the given text at the .
+ /// If the resulting exceeds , the end will be cropped to fit.
+ ///
+ /// The text to insert
+ /// If any characters that don't match the should be left out
+ public void InsertText(object text, bool removeMismatching = false) {
+ var strg = text?.ToString() ?? string.Empty;
+ if (!this.FilterText(ref strg, removeMismatching))
+ return;
+ if (this.MaximumCharacters != null && this.text.Length + strg.Length > this.MaximumCharacters)
+ strg = strg.Substring(0, this.MaximumCharacters.Value - this.text.Length);
+ this.text.Insert(this.CaretPos, strg);
+ this.CaretPos += strg.Length;
+ this.HandleTextChange();
+ }
+
+ ///
+ /// Removes the given amount of text at the given index
+ ///
+ /// The index
+ /// The amount of text to remove
+ public void RemoveText(int index, int length) {
+ if (index < 0 || index >= this.text.Length)
+ return;
+ this.text.Remove(index, length);
+ // ensure that caret pos is still in bounds
+ this.CaretPos = this.CaretPos;
+ this.HandleTextChange();
+ }
+
+ ///
+ protected override void InitStyle(UiStyle style) {
+ base.InitStyle(style);
+ this.TextScale.SetFromStyle(style.TextScale);
+ this.Font.SetFromStyle(style.Font);
+ this.Texture.SetFromStyle(style.TextFieldTexture);
+ this.HoveredTexture.SetFromStyle(style.TextFieldHoveredTexture);
+ this.HoveredColor.SetFromStyle(style.TextFieldHoveredColor);
+ }
+
+ private bool FilterText(ref string text, bool removeMismatching) {
+ if (removeMismatching) {
+ var result = new StringBuilder();
+ foreach (var c in text) {
+ if (this.InputRule(this, c.ToCachedString()))
+ result.Append(c);
+ }
+ text = result.ToString();
+ } else if (!this.InputRule(this, text))
+ return false;
+ return true;
+ }
+
private void HandleTextChange(bool textChanged = true) {
// not initialized yet
if (!this.Font.HasValue())
@@ -358,139 +498,6 @@ namespace MLEM.Ui.Elements {
}
}
- ///
- public override void Update(GameTime time) {
- base.Update(time);
-
- // handle first initialization if not done
- if (this.displayedText == null)
- this.HandleTextChange(false);
-
- if (!this.IsSelected || this.IsHidden)
- return;
-
- if (this.Input.IsKeyPressed(Keys.Left)) {
- this.CaretPos--;
- } else if (this.Input.IsKeyPressed(Keys.Right)) {
- this.CaretPos++;
- } else if (this.Input.IsKeyPressed(Keys.Home)) {
- this.CaretPos = 0;
- } else if (this.Input.IsKeyPressed(Keys.End)) {
- this.CaretPos = this.text.Length;
- } else if (this.Input.IsModifierKeyDown(ModifierKey.Control)) {
- if (this.Input.IsKeyPressed(Keys.V)) {
- var clip = ClipboardService.GetText();
- if (clip != null)
- this.InsertText(clip);
- } else if (this.Input.IsKeyPressed(Keys.C)) {
- // until there is text selection, just copy the whole content
- ClipboardService.SetText(this.Text);
- }
- }
-
- this.caretBlinkTimer += time.ElapsedGameTime.TotalSeconds;
- if (this.caretBlinkTimer >= 1)
- this.caretBlinkTimer = 0;
- }
-
- ///
- public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
- var tex = this.Texture;
- var color = Color.White * alpha;
- if (this.IsMouseOver) {
- tex = this.HoveredTexture.OrDefault(tex);
- color = (Color) this.HoveredColor * alpha;
- }
- batch.Draw(tex, this.DisplayArea, color, this.Scale);
-
- if (this.displayedText != null) {
- var lineHeight = this.Font.Value.LineHeight * this.TextScale * this.Scale;
- var offset = new Vector2(
- this.TextOffsetX * this.Scale,
- this.Multiline ? this.TextOffsetX * this.Scale : this.DisplayArea.Height / 2 - lineHeight / 2);
- var textPos = this.DisplayArea.Location + offset;
- if (this.text.Length > 0 || this.IsSelected) {
- var textColor = this.TextColor.OrDefault(Color.White);
- this.Font.Value.DrawString(batch, this.displayedText, textPos, textColor * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0);
-
- if (this.IsSelected && this.caretBlinkTimer < 0.5F) {
- var caretDrawPos = textPos + new Vector2(this.caretDrawOffset * this.TextScale * this.Scale, 0);
- if (this.Multiline)
- caretDrawPos.Y += this.Font.Value.LineHeight * (this.CaretLine - this.lineOffset) * this.TextScale * this.Scale;
- batch.Draw(batch.GetBlankTexture(), new RectangleF(caretDrawPos, new Vector2(this.CaretWidth * this.Scale, lineHeight)), null, textColor * alpha);
- }
- } else if (this.PlaceholderText != null) {
- this.Font.Value.DrawString(batch, this.PlaceholderText, textPos, this.PlaceholderColor.OrDefault(Color.Gray) * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0);
- }
- }
- base.Draw(time, batch, alpha, blendState, samplerState, matrix);
- }
-
- ///
- /// Replaces this text field's text with the given text.
- /// If the resulting exceeds , the end will be cropped to fit.
- ///
- /// The new text
- /// If any characters that don't match the should be left out
- public void SetText(object text, bool removeMismatching = false) {
- var strg = text?.ToString() ?? string.Empty;
- if (removeMismatching) {
- var result = new StringBuilder();
- foreach (var c in strg) {
- if (this.InputRule(this, c.ToCachedString()))
- result.Append(c);
- }
- strg = result.ToString();
- } else if (!this.InputRule(this, strg))
- return;
- if (this.MaximumCharacters != null && strg.Length > this.MaximumCharacters)
- strg = strg.Substring(0, this.MaximumCharacters.Value);
- this.text.Clear();
- this.text.Append(strg);
- this.CaretPos = this.text.Length;
- this.HandleTextChange();
- }
-
- ///
- /// Inserts the given text at the .
- /// If the resulting exceeds , the end will be cropped to fit.
- ///
- /// The text to insert
- public void InsertText(object text) {
- var strg = text.ToString();
- if (!this.InputRule(this, strg))
- return;
- if (this.MaximumCharacters != null && this.text.Length + strg.Length > this.MaximumCharacters)
- strg = strg.Substring(0, this.MaximumCharacters.Value - this.text.Length);
- this.text.Insert(this.CaretPos, strg);
- this.CaretPos += strg.Length;
- this.HandleTextChange();
- }
-
- ///
- /// Removes the given amount of text at the given index
- ///
- /// The index
- /// The amount of text to remove
- public void RemoveText(int index, int length) {
- if (index < 0 || index >= this.text.Length)
- return;
- this.text.Remove(index, length);
- // ensure that caret pos is still in bounds
- this.CaretPos = this.CaretPos;
- this.HandleTextChange();
- }
-
- ///
- protected override void InitStyle(UiStyle style) {
- base.InitStyle(style);
- this.TextScale.SetFromStyle(style.TextScale);
- this.Font.SetFromStyle(style.Font);
- this.Texture.SetFromStyle(style.TextFieldTexture);
- this.HoveredTexture.SetFromStyle(style.TextFieldHoveredTexture);
- this.HoveredColor.SetFromStyle(style.TextFieldHoveredColor);
- }
-
///
/// A delegate method used for
///