1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-26 14:38:34 +01:00

better text editing, part 1

This commit is contained in:
Ellpeck 2019-09-05 12:51:40 +02:00
parent b19333d627
commit 12a2e92c09
2 changed files with 52 additions and 20 deletions

View file

@ -39,7 +39,7 @@ namespace MLEM.Ui.Elements {
var field = new TextField(Anchor.TopLeft, Vector2.One, rule ?? TextField.OnlyNumbers); var field = new TextField(Anchor.TopLeft, Vector2.One, rule ?? TextField.OnlyNumbers);
field.OnTextChange = onTextChange; field.OnTextChange = onTextChange;
field.AppendText(defaultValue.ToString()); field.SetText(defaultValue.ToString());
group.AddChild(field); group.AddChild(field);
group.OnAreaUpdated += e => field.Size = new Vector2((e.Area.Width - e.Area.Height / 2) / e.Scale, 1); group.OnAreaUpdated += e => field.Size = new Vector2((e.Area.Width - e.Area.Height / 2) / e.Scale, 1);

View file

@ -30,9 +30,23 @@ namespace MLEM.Ui.Elements {
private IGenericFont font; private IGenericFont font;
private double caretBlinkTimer; private double caretBlinkTimer;
private int textStartIndex; private int textStartIndex;
private int textDisplayLength;
public Rule InputRule; public Rule InputRule;
public string MobileTitle; public string MobileTitle;
public string MobileDescription; public string MobileDescription;
private int caretPos;
public int CaretPos {
get {
this.CaretPos = MathHelper.Clamp(this.caretPos, 0, this.text.Length);
return this.caretPos;
}
set {
if (this.caretPos != value) {
this.caretPos = value;
this.HandleTextChange(false);
}
}
}
public TextField(Anchor anchor, Vector2 size, Rule rule = null, IGenericFont font = null) : base(anchor, size) { public TextField(Anchor anchor, Vector2 size, Rule rule = null, IGenericFont font = null) : base(anchor, size) {
this.InputRule = rule ?? DefaultRule; this.InputRule = rule ?? DefaultRule;
@ -43,11 +57,12 @@ namespace MLEM.Ui.Elements {
if (!this.IsSelected) if (!this.IsSelected)
return; return;
if (key == Keys.Back) { if (key == Keys.Back) {
if (this.text.Length > 0) { this.CaretPos--;
this.RemoveText(this.text.Length - 1, 1); this.RemoveText(this.CaretPos, 1);
} } else if (key == Keys.Delete) {
this.RemoveText(this.CaretPos, 1);
} else { } else {
this.AppendText(character); this.InsertText(character);
} }
}; };
} else { } else {
@ -60,32 +75,44 @@ namespace MLEM.Ui.Elements {
} }
}; };
} }
this.OnDeselected += e => this.CaretPos = 0;
this.OnSelected += e => this.CaretPos = this.text.Length;
} }
private void HandleTextChange() { private void HandleTextChange(bool textChanged = true) {
// not initialized yet // not initialized yet
if (this.font == null) if (this.font == null) {
this.textDisplayLength = this.text.Length;
return; return;
}
var length = this.font.MeasureString(this.text).X * this.TextScale; var length = this.font.MeasureString(this.text).X * this.TextScale;
var maxWidth = this.DisplayArea.Width / this.Scale - this.TextOffsetX * 2; var maxWidth = this.DisplayArea.Width / this.Scale - this.TextOffsetX * 2;
if (length > maxWidth) { if (length > maxWidth) {
for (var i = 0; i < this.text.Length; i++) { // TODO
var substring = this.text.ToString(i, this.text.Length - i); this.textStartIndex = 0;
if (this.font.MeasureString(substring).X * this.TextScale <= maxWidth) { this.textDisplayLength = this.text.Length;
this.textStartIndex = i;
break;
}
}
} else { } else {
this.textStartIndex = 0; this.textStartIndex = 0;
this.textDisplayLength = this.text.Length;
} }
this.OnTextChange?.Invoke(this, this.text.ToString()); if (textChanged)
this.OnTextChange?.Invoke(this, this.Text);
} }
public override void Update(GameTime time) { public override void Update(GameTime time) {
base.Update(time); base.Update(time);
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;
}
this.caretBlinkTimer += time.ElapsedGameTime.TotalSeconds; this.caretBlinkTimer += time.ElapsedGameTime.TotalSeconds;
if (this.caretBlinkTimer >= 1) if (this.caretBlinkTimer >= 1)
this.caretBlinkTimer = 0; this.caretBlinkTimer = 0;
@ -103,8 +130,8 @@ namespace MLEM.Ui.Elements {
var textPos = this.DisplayArea.Location.ToVector2() + new Vector2(this.TextOffsetX * this.Scale, this.DisplayArea.Height / 2); var textPos = this.DisplayArea.Location.ToVector2() + new Vector2(this.TextOffsetX * this.Scale, this.DisplayArea.Height / 2);
if (this.text.Length > 0 || this.IsSelected) { if (this.text.Length > 0 || this.IsSelected) {
var caret = this.IsSelected && this.caretBlinkTimer >= 0.5F ? "|" : ""; var caret = this.IsSelected ? this.caretBlinkTimer >= 0.5F ? "|" : " " : "";
var display = this.text.ToString(this.textStartIndex, this.text.Length - this.textStartIndex) + caret; var display = this.text.ToString(this.textStartIndex, this.textDisplayLength).Insert(this.CaretPos - this.textStartIndex, caret);
this.font.DrawCenteredString(batch, display, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true); this.font.DrawCenteredString(batch, display, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true);
} else if (this.PlaceholderText != null) { } else if (this.PlaceholderText != null) {
this.font.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true); this.font.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true);
@ -124,17 +151,22 @@ namespace MLEM.Ui.Elements {
return; return;
this.text.Clear(); this.text.Clear();
this.text.Append(text); this.text.Append(text);
this.CaretPos = this.text.Length;
this.HandleTextChange(); this.HandleTextChange();
} }
public void AppendText(object text) { public void InsertText(object text) {
if (!this.InputRule(this, text.ToString())) var strg = text.ToString();
if (!this.InputRule(this, strg))
return; return;
this.text.Append(text); this.text.Insert(this.CaretPos, strg);
this.CaretPos += strg.Length;
this.HandleTextChange(); this.HandleTextChange();
} }
public void RemoveText(int index, int length) { public void RemoveText(int index, int length) {
if (index < 0 || index >= this.text.Length)
return;
this.text.Remove(index, length); this.text.Remove(index, length);
this.HandleTextChange(); this.HandleTextChange();
} }