diff --git a/MLEM.Ui/Elements/TextField.cs b/MLEM.Ui/Elements/TextField.cs
index 677f7f3..b9a4128 100644
--- a/MLEM.Ui/Elements/TextField.cs
+++ b/MLEM.Ui/Elements/TextField.cs
@@ -178,9 +178,6 @@ namespace MLEM.Ui.Elements {
/// If this is true, pressing will insert a new line into the if the allows it.
/// Additionally, text will be rendered with horizontal soft wraps, and lines that are outside of the text field's bounds will be hidden.
///
- ///
- /// Moving up and down through the text field, and clicking on text to start editing at the mouse's position, are currently not supported.
- ///
public bool Multiline {
get => this.multiline;
set {
@@ -263,6 +260,10 @@ namespace MLEM.Ui.Elements {
this.CaretPos--;
} else if (this.Input.IsKeyPressed(Keys.Right)) {
this.CaretPos++;
+ } else if (this.Multiline && this.Input.IsKeyPressed(Keys.Up)) {
+ this.MoveCaretToLine(this.CaretLine - 1);
+ } else if (this.Multiline && this.Input.IsKeyPressed(Keys.Down)) {
+ this.MoveCaretToLine(this.CaretLine + 1);
} else if (this.Input.IsKeyPressed(Keys.Home)) {
this.CaretPos = 0;
} else if (this.Input.IsKeyPressed(Keys.End)) {
@@ -365,6 +366,31 @@ namespace MLEM.Ui.Elements {
this.HandleTextChange();
}
+ ///
+ /// Moves the to the given line, if it exists.
+ /// Additionally maintains the roughly based on the visual distance that the caret has from the left border of the current .
+ ///
+ /// The line to move the caret to
+ /// True if the caret was moved, false if it was not (which indicates that the line with the given index does not exist)
+ public bool MoveCaretToLine(int line) {
+ var (destStart, destEnd) = this.GetLineBounds(line);
+ if (destEnd > 0) {
+ // find the position whose distance from the start is closest to the current distance from the start
+ var destAccum = "";
+ while (destAccum.Length < destEnd - destStart) {
+ if (this.Font.Value.MeasureString(destAccum).X >= this.caretDrawOffset) {
+ this.CaretPos = destStart + destAccum.Length;
+ return true;
+ }
+ destAccum += this.text[destStart + destAccum.Length];
+ }
+ // if we don't find a proper position, just move to the end of the destination line
+ this.CaretPos = destEnd;
+ return true;
+ }
+ return false;
+ }
+
///
protected override void InitStyle(UiStyle style) {
base.InitStyle(style);
@@ -498,6 +524,31 @@ namespace MLEM.Ui.Elements {
}
}
+ private (int, int) GetLineBounds(int boundLine) {
+ if (this.splitText != null) {
+ var line = 0;
+ var index = 0;
+ var startOfLineIndex = 0;
+ for (var d = 0; d < this.splitText.Length; d++) {
+ var split = this.splitText[d];
+ for (var i = 0; i < split.Length; i++) {
+ index++;
+ if (split[i] == '\n') {
+ if (boundLine == line)
+ return (startOfLineIndex, index - 1);
+ line++;
+ startOfLineIndex = index;
+ }
+ }
+ if (boundLine == line)
+ return (startOfLineIndex, index - 1);
+ line++;
+ startOfLineIndex = index;
+ }
+ }
+ return default;
+ }
+
///
/// A delegate method used for
///