Class TextAreaModel

java.lang.Object
dev.xichil.mvui.TextAreaModel

public final class TextAreaModel extends Object
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 Classes
    Modifier and Type
    Class
    Description
    static final class 
    One line as drawn: text().substring(start, end), without its line break.
  • Constructor Summary

    Constructors
    Constructor
    Description
    TextAreaModel(int maxLength)
    An empty model, cursor at 0, with no wrapping until layout(int, ToIntFunction) is called.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    click(int line, int x)
    Puts the cursor where the player clicked: on line (clamped), x pixels from its start.
    int
    The cursor's offset in text(), from 0 to its length.
    int
    The line the cursor is on.
    int
    The cursor's x in pixels from the start of its line.
    int
    firstVisibleLine(int visibleLines)
    The first line to draw when the box shows visibleLines: scrolled so the cursor is in view after it moved or the text changed, otherwise where scroll left it.
    boolean
    Inserts s at the cursor (pasted text), as much of it as fits; false if nothing was inserted.
    boolean
    key(Key key)
    A pressed key: Backspace, Delete, Enter (line break), the arrows, Home and End (of the line).
    void
    layout(int maxWidth, ToIntFunction<String> widthOf)
    Wraps lines to maxWidth pixels, measured with widthOf (the font's string width).
    The lines as drawn, wrapped to the layout(int, ToIntFunction) width; at least one (empty text has one empty line).
    void
    scroll(int lines, int visibleLines)
    Mouse wheel: scrolls by lines (negative is up) without moving the cursor.
    void
    setCursor(int offset)
    Moves the cursor and scrolls it into view.
    void
    setText(String newText)
    Replaces the text (e.g.
    The whole text, with '\n' line breaks.
    boolean
    type(char c)
    A typed character; false if it isn't allowed (control characters, '§') or the text is full.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

  • Method Details

    • text

      public String text()
      The whole text, with '\n' line breaks.
      Returns:
      the text, with line breaks as '\n'
    • setText

      public void setText(String newText)
      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; null means empty
    • cursor

      public int cursor()
      The cursor's offset in text(), 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

      public void layout(int maxWidth, ToIntFunction<String> widthOf)
      Wraps lines to maxWidth pixels, measured with widthOf (the font's string width).
      Parameters:
      maxWidth - the width to wrap to, in pixels
      widthOf - the string width function in pixels, e.g. font::width
    • lines

      public List<TextAreaModel.Line> lines()
      The lines as drawn, wrapped to the layout(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 shows visibleLines: scrolled so the cursor is in view after it moved or the text changed, otherwise where scroll left 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 by lines (negative is up) without moving the cursor.
      Parameters:
      lines - the number of lines to scroll by; negative is up
      visibleLines - the number of lines the box shows
    • click

      public void click(int line, int x)
      Puts the cursor where the player clicked: on line (clamped), x pixels from its start.
      Parameters:
      line - the line clicked; clamped to the text
      x - 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:
      true if the character was inserted
    • insert

      public boolean insert(String s)
      Inserts s at 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:
      true if any of the text was inserted
    • key

      public boolean key(Key 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 in text().
      Parameters:
      key - the pressed key
      Returns:
      true if the model handled the key