Class TextAreaModel
java.lang.Object
dev.xichil.mvui.TextAreaModel
The editing logic of a
MultiLineInput box, for backends of versions without vanilla's
MultiLineEditBox (before 1.19.3, TODO.md Phase 11): text, cursor, word wrap, scrolling and the keys,
so such a backend only draws the box and feeds it input. Mods don't need it.
A backend calls layout(int, ToIntFunction) with the box's inner width and its font's string width once it knows them
(and again when they change), feeds typed characters to type(char), key presses to key(Key) (GLFW codes,
as a Key; 1.7.10 – 1.12.2 convert with Key.fromLwjgl2(int)) and clicks to click(int, int); after each it
passes a changed text() to MultiLineInput.setValue(String). It draws lines() from
firstVisibleLine(int) on and the cursor at cursorLine(), cursorX(). There is no selection.
TextAreaModel model = new TextAreaModel(input.maxLength());
model.setText(input.value());
model.layout(boxWidth - 8, font::width);
// on a typed character:
if (model.type(c)) {
input.setValue(model.text());
}
// when drawing:
int first = model.firstVisibleLine(input.lines());
for (int i = first; i < Math.min(first + input.lines(), model.lines().size()); i++) {
drawString(model.lines().get(i).text(), x, y + (i - first) * lineHeight);
}
Not thread-safe; use it on the main thread only.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classOne line as drawn:text().substring(start, end), without its line break. -
Constructor Summary
ConstructorsConstructorDescriptionTextAreaModel(int maxLength) An empty model, cursor at 0, with no wrapping untillayout(int, ToIntFunction)is called. -
Method Summary
Modifier and TypeMethodDescriptionvoidclick(int line, int x) Puts the cursor where the player clicked: online(clamped),xpixels from its start.intcursor()The cursor's offset intext(), from 0 to its length.intThe line the cursor is on.intcursorX()The cursor's x in pixels from the start of its line.intfirstVisibleLine(int visibleLines) The first line to draw when the box showsvisibleLines: scrolled so the cursor is in view after it moved or the text changed, otherwise wherescrollleft it.booleanInsertssat the cursor (pasted text), as much of it as fits; false if nothing was inserted.booleanA pressed key: Backspace, Delete, Enter (line break), the arrows, Home and End (of the line).voidlayout(int maxWidth, ToIntFunction<String> widthOf) Wraps lines tomaxWidthpixels, measured withwidthOf(the font's string width).lines()The lines as drawn, wrapped to thelayout(int, ToIntFunction)width; at least one (empty text has one empty line).voidscroll(int lines, int visibleLines) Mouse wheel: scrolls bylines(negative is up) without moving the cursor.voidsetCursor(int offset) Moves the cursor and scrolls it into view.voidReplaces the text (e.g.text()The whole text, with'\n'line breaks.booleantype(char c) A typed character; false if it isn't allowed (control characters, '§') or the text is full.
-
Constructor Details
-
TextAreaModel
public TextAreaModel(int maxLength) An empty model, cursor at 0, with no wrapping untillayout(int, ToIntFunction)is called.- Parameters:
maxLength- the most characters the text may have, line breaks included: the entry'sMultiLineInput.maxLength()- Throws:
IllegalArgumentException- ifmaxLengthis not positive
-
-
Method Details
-
text
The whole text, with'\n'line breaks.- Returns:
- the text, with line breaks as
'\n'
-
setText
Replaces the text (e.g. the entry's on refresh); the cursor stays where it was, or at the end if that is gone.- Parameters:
newText- the new text;nullmeans empty
-
cursor
public int cursor()The cursor's offset intext(), from 0 to its length.- Returns:
- the cursor's offset in the text
-
setCursor
public void setCursor(int offset) Moves the cursor and scrolls it into view.- Parameters:
offset- the new offset; clamped to the text
-
layout
Wraps lines tomaxWidthpixels, measured withwidthOf(the font's string width).- Parameters:
maxWidth- the width to wrap to, in pixelswidthOf- the string width function in pixels, e.g.font::width
-
lines
The lines as drawn, wrapped to thelayout(int, ToIntFunction)width; at least one (empty text has one empty line).- Returns:
- an unmodifiable list
-
cursorLine
public int cursorLine()The line the cursor is on.- Returns:
- the index of the cursor's line
-
cursorX
public int cursorX()The cursor's x in pixels from the start of its line.- Returns:
- the cursor's x, in pixels from its line's start
-
firstVisibleLine
public int firstVisibleLine(int visibleLines) The first line to draw when the box showsvisibleLines: scrolled so the cursor is in view after it moved or the text changed, otherwise wherescrollleft it.- Parameters:
visibleLines- the number of lines the box shows- Returns:
- the index of the first line to draw
-
scroll
public void scroll(int lines, int visibleLines) Mouse wheel: scrolls bylines(negative is up) without moving the cursor.- Parameters:
lines- the number of lines to scroll by; negative is upvisibleLines- the number of lines the box shows
-
click
public void click(int line, int x) Puts the cursor where the player clicked: online(clamped),xpixels from its start.- Parameters:
line- the line clicked; clamped to the textx- the click's distance from the line's start, in pixels
-
type
public boolean type(char c) A typed character; false if it isn't allowed (control characters, '§') or the text is full.- Parameters:
c- the typed character- Returns:
trueif the character was inserted
-
insert
Insertssat the cursor (pasted text), as much of it as fits; false if nothing was inserted.- Parameters:
s- the text to insert at the cursor- Returns:
trueif any of the text was inserted
-
key
A pressed key: Backspace, Delete, Enter (line break), the arrows, Home and End (of the line). Returns true if the key is one of those, so the backend doesn't pass it on; whether the text changed is intext().- Parameters:
key- the pressed key- Returns:
trueif the model handled the key
-