1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-20 12:09:10 +02:00

added ElementHelper and did some textfield changes

This commit is contained in:
Ellpeck 2019-08-24 12:40:20 +02:00
parent 404e95c8f2
commit cb5594bada
4 changed files with 101 additions and 33 deletions

View file

@ -79,7 +79,7 @@ namespace Demos {
image.IsHidden = !image.IsHidden;
}
});
root.AddChild(new VerticalSpace(3));
root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "Note that the default style does not contain any textures or font files and, as such, is quite bland. However, the default style is quite easy to override."));
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 10), "Change Style") {
@ -97,7 +97,7 @@ namespace Demos {
root.AddChild(new VerticalSpace(3));
// a paragraph with formatting codes. To see them all or to add more, check the TextFormatting class
root.AddChild(new Paragraph(Anchor.AutoLeft, 1,"Paragraphs can also contain [Blue]formatting codes[White], including colors and [Italic]text styles[Regular]. The names of all [Orange]MonoGame Colors[White] can be used, as well as the codes [Italic]Italic[Regular] and [Bold]Bold[Regular]. \n[Italic]Even [CornflowerBlue]Cornflower Blue[White] works!"));
root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "Paragraphs can also contain [Blue]formatting codes[White], including colors and [Italic]text styles[Regular]. The names of all [Orange]MonoGame Colors[White] can be used, as well as the codes [Italic]Italic[Regular] and [Bold]Bold[Regular]. \n[Italic]Even [CornflowerBlue]Cornflower Blue[White] works!"));
root.AddChild(new VerticalSpace(3));
root.AddChild(new Paragraph(Anchor.AutoCenter, 1, "Text input:", true));
@ -155,6 +155,10 @@ namespace Demos {
PositionOffset = new Vector2(0, 1)
});
root.AddChild(new VerticalSpace(3));
root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "There are also some additional \"components\" which are created as combinations of other components. You can find all of them in the ElementHelper class. Here are some examples:"));
root.AddChild(ElementHelper.NumberField(Anchor.AutoLeft, new Vector2(1, 10))).PositionOffset = new Vector2(0, 1);
// Below are some querying examples that help you find certain elements easily
var children = root.GetChildren();

View file

@ -85,6 +85,7 @@ namespace MLEM.Ui.Elements {
public MouseCallback OnMouseEnter;
public MouseCallback OnMouseExit;
public TextInputCallback OnTextInput;
public GenericCallback OnAreaUpdated;
private UiSystem system;
public UiSystem System {
@ -289,6 +290,8 @@ namespace MLEM.Ui.Elements {
}
this.area = new Rectangle(pos, actualSize);
this.OnAreaUpdated?.Invoke(this);
foreach (var child in this.Children)
child.ForceUpdateArea();

View file

@ -0,0 +1,42 @@
using Microsoft.Xna.Framework;
using MLEM.Input;
namespace MLEM.Ui.Elements {
public static class ElementHelper {
public static Group NumberField(Anchor anchor, Vector2 size, int defaultValue = 0, int stepPerClick = 1, TextField.Rule rule = null, TextField.TextChanged onTextChange = null) {
var group = new Group(anchor, size, false);
var field = new TextField(Anchor.TopLeft, Vector2.One, rule ?? TextField.OnlyNumbers);
field.OnTextChange = onTextChange;
field.AppendText(defaultValue.ToString());
group.AddChild(field);
group.OnAreaUpdated += e => field.Size = new Vector2((e.Area.Width - e.Area.Height / 2) / e.Scale, 1);
var upButton = new Button(Anchor.TopRight, Vector2.One, "+") {
OnClicked = (element, button) => {
if (button == MouseButton.Left) {
var text = field.Text.ToString();
field.SetText(int.Parse(text) + stepPerClick);
}
}
};
group.AddChild(upButton);
group.OnAreaUpdated += e => upButton.Size = new Vector2(e.Area.Height / 2 / e.Scale);
var downButton = new Button(Anchor.BottomRight, Vector2.One, "-") {
OnClicked = (element, button) => {
if (button == MouseButton.Left) {
var text = field.Text.ToString();
field.SetText(int.Parse(text) - stepPerClick);
}
}
};
group.AddChild(downButton);
group.OnAreaUpdated += e => downButton.Size = new Vector2(e.Area.Height / 2 / e.Scale);
return group;
}
}
}

View file

@ -21,10 +21,10 @@ namespace MLEM.Ui.Elements {
public NinePatch HoveredTexture;
public Color HoveredColor;
public float TextScale;
public readonly StringBuilder Text = new StringBuilder();
private readonly StringBuilder text = new StringBuilder();
public string Text => this.text.ToString();
public string PlaceholderText;
public TextChanged OnTextChange;
public int MaxTextLength = int.MaxValue;
public float TextOffsetX = 4;
private IGenericFont font;
private double caretBlinkTimer;
@ -37,38 +37,37 @@ namespace MLEM.Ui.Elements {
this.OnTextInput += (element, key, character) => {
if (!this.IsSelected)
return;
var textChanged = false;
if (key == Keys.Back) {
if (this.Text.Length > 0) {
this.Text.Remove(this.Text.Length - 1, 1);
textChanged = true;
if (this.text.Length > 0) {
this.RemoveText(this.text.Length - 1, 1);
}
} else if (this.InputRule(this, character.ToString())) {
if (this.Text.Length < this.MaxTextLength) {
this.Text.Append(character);
textChanged = true;
}
}
if (textChanged) {
var length = this.font.MeasureString(this.Text).X * this.TextScale;
var maxWidth = this.DisplayArea.Width / this.Scale - this.TextOffsetX * 2;
if (length > maxWidth) {
for (var i = 0; i < this.Text.Length; i++) {
var substring = this.Text.ToString(i, this.Text.Length - i);
if (this.font.MeasureString(substring).X * this.TextScale <= maxWidth) {
this.textStartIndex = i;
break;
}
}
} else {
this.textStartIndex = 0;
}
this.OnTextChange?.Invoke(this, this.Text.ToString());
} else {
this.AppendText(character);
}
};
}
private void HandleTextChange() {
// not initialized yet
if (this.font == null)
return;
var length = this.font.MeasureString(this.text).X * this.TextScale;
var maxWidth = this.DisplayArea.Width / this.Scale - this.TextOffsetX * 2;
if (length > maxWidth) {
for (var i = 0; i < this.text.Length; i++) {
var substring = this.text.ToString(i, this.text.Length - i);
if (this.font.MeasureString(substring).X * this.TextScale <= maxWidth) {
this.textStartIndex = i;
break;
}
}
} else {
this.textStartIndex = 0;
}
this.OnTextChange?.Invoke(this, this.text.ToString());
}
public override void Update(GameTime time) {
base.Update(time);
@ -88,16 +87,36 @@ namespace MLEM.Ui.Elements {
batch.Draw(tex, this.DisplayArea.OffsetCopy(offset), color, this.Scale);
var textPos = this.DisplayArea.Location.ToVector2() + new Vector2(offset.X + this.TextOffsetX * this.Scale, offset.Y + 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 text = this.Text.ToString(this.textStartIndex, this.Text.Length - this.textStartIndex) + caret;
this.font.DrawCenteredString(batch, text, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true);
var display = this.text.ToString(this.textStartIndex, this.text.Length - this.textStartIndex) + caret;
this.font.DrawCenteredString(batch, display, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true);
} else if (this.PlaceholderText != null) {
this.font.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true);
}
base.Draw(time, batch, alpha, offset);
}
public void SetText(object text) {
if (!this.InputRule(this, text.ToString()))
return;
this.text.Clear();
this.text.Append(text);
this.HandleTextChange();
}
public void AppendText(object text) {
if (!this.InputRule(this, text.ToString()))
return;
this.text.Append(text);
this.HandleTextChange();
}
public void RemoveText(int index, int length) {
this.text.Remove(index, length);
this.HandleTextChange();
}
protected override void InitStyle(UiStyle style) {
base.InitStyle(style);
this.TextScale = style.TextScale;