X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fteditor%2FLine.java;h=400de9a8a73db37446da0976dd4f001966a4dee3;hb=615a0d99fd0aa4437116dd083147f9150d5e6527;hp=b89d8277ed30b1ac6b1a500f9056839b9b87069c;hpb=12b55d76e3473407bf37fca3667860240cb8f3be;p=nikiroo-utils.git diff --git a/src/jexer/teditor/Line.java b/src/jexer/teditor/Line.java index b89d827..400de9a 100644 --- a/src/jexer/teditor/Line.java +++ b/src/jexer/teditor/Line.java @@ -31,132 +31,269 @@ package jexer.teditor; import java.util.ArrayList; import java.util.List; +import jexer.bits.CellAttributes; + /** * A Line represents a single line of text on the screen, as a collection of * words. */ public class Line { + // ------------------------------------------------------------------------ + // Variables -------------------------------------------------------------- + // ------------------------------------------------------------------------ + /** * The list of words. */ private ArrayList words = new ArrayList(); + /** + * The default color for the TEditor class. + */ + private CellAttributes defaultColor = null; + + /** + * The text highlighter to use. + */ + private Highlighter highlighter = null; + /** * The current cursor position on this line. */ - private int cursorX; + private int cursor = 0; /** - * The current word that the cursor position is in. + * The raw text of this line, what is passed to Word to determine + * highlighting behavior. */ - private Word currentWord; + private StringBuilder rawText; + + // ------------------------------------------------------------------------ + // Constructors ----------------------------------------------------------- + // ------------------------------------------------------------------------ /** - * We use getDisplayLength() a lot, so cache the value. + * Construct a new Line from an existing text string, and highlight + * certain strings. + * + * @param str the text string + * @param defaultColor the color for unhighlighted text + * @param highlighter the highlighter to use */ - private int displayLength = -1; + public Line(final String str, final CellAttributes defaultColor, + final Highlighter highlighter) { + + this.defaultColor = defaultColor; + this.highlighter = highlighter; + this.rawText = new StringBuilder(str); + + scanLine(); + } /** - * Get a (shallow) copy of the list of words. + * Construct a new Line from an existing text string. * - * @return the list of words + * @param str the text string + * @param defaultColor the color for unhighlighted text + */ + public Line(final String str, final CellAttributes defaultColor) { + this(str, defaultColor, null); + } + + // ------------------------------------------------------------------------ + // Line ------------------------------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * Get a (shallow) copy of the words in this line. + * + * @return a copy of the word list */ public List getWords() { return new ArrayList(words); } + /** + * Get the current cursor position. + * + * @return the cursor position + */ + public int getCursor() { + return cursor; + } + + /** + * Set the current cursor position. + * + * @param cursor the new cursor position + */ + public void setCursor(final int cursor) { + if ((cursor < 0) + || ((cursor >= getDisplayLength()) + && (getDisplayLength() > 0)) + ) { + throw new IndexOutOfBoundsException("Max length is " + + getDisplayLength() + ", requested position " + cursor); + } + this.cursor = cursor; + } + /** * Get the on-screen display length. * * @return the number of cells needed to display this line */ public int getDisplayLength() { - if (displayLength != -1) { - return displayLength; - } - int n = 0; - for (Word word: words) { - n += word.getDisplayLength(); + int n = rawText.length(); + + // For now just return the raw text length. + if (n > 0) { + // If we have any visible characters, add one to the display so + // that the cursor is immediately after the data. + return n + 1; } - displayLength = n; - return displayLength; + return n; } /** - * Construct a new Line from an existing text string. + * Get the raw string that matches this line. * - * @param str the text string + * @return the string */ - public Line(final String str) { - currentWord = new Word(); - words.add(currentWord); - for (int i = 0; i < str.length(); i++) { - char ch = str.charAt(i); - Word newWord = currentWord.addChar(ch); - if (newWord != currentWord) { + public String getRawString() { + return rawText.toString(); + } + + /** + * Scan rawText and make words out of it. + */ + private void scanLine() { + words.clear(); + Word word = new Word(this.defaultColor, this.highlighter); + words.add(word); + for (int i = 0; i < rawText.length(); i++) { + char ch = rawText.charAt(i); + Word newWord = word.addChar(ch); + if (newWord != word) { words.add(newWord); - currentWord = newWord; + word = newWord; } } + for (Word w: words) { + w.applyHighlight(); + } } /** * Decrement the cursor by one. If at the first column, do nothing. + * + * @return true if the cursor position changed */ - public void left() { - if (cursorX == 0) { - return; + public boolean left() { + if (cursor == 0) { + return false; } - // TODO + cursor--; + return true; } /** * Increment the cursor by one. If at the last column, do nothing. + * + * @return true if the cursor position changed */ - public void right() { - if (cursorX == getDisplayLength() - 1) { - return; + public boolean right() { + if (getDisplayLength() == 0) { + return false; + } + if (cursor == getDisplayLength() - 1) { + return false; } - // TODO + cursor++; + return true; } /** * Go to the first column of this line. + * + * @return true if the cursor position changed */ - public void home() { - // TODO + public boolean home() { + if (cursor > 0) { + cursor = 0; + return true; + } + return false; } /** * Go to the last column of this line. + * + * @return true if the cursor position changed */ - public void end() { - // TODO + public boolean end() { + if (cursor != getDisplayLength() - 1) { + cursor = getDisplayLength() - 1; + if (cursor < 0) { + cursor = 0; + } + return true; + } + return false; } /** * Delete the character under the cursor. */ public void del() { - // TODO + assert (words.size() > 0); + + if (cursor < getDisplayLength()) { + rawText.deleteCharAt(cursor); + } + + // Re-scan the line to determine the new word boundaries. + scanLine(); } /** * Delete the character immediately preceeding the cursor. */ public void backspace() { - // TODO + if (left()) { + del(); + } } /** - * Replace or insert a character at the cursor, depending on overwrite - * flag. + * Insert a character at the cursor. * - * @param ch the character to replace or insert + * @param ch the character to insert */ public void addChar(final char ch) { - // TODO + if (cursor < getDisplayLength() - 1) { + rawText.insert(cursor, ch); + } else { + rawText.append(ch); + } + scanLine(); + cursor++; + } + + /** + * Replace a character at the cursor. + * + * @param ch the character to replace + */ + public void replaceChar(final char ch) { + if (cursor < getDisplayLength() - 1) { + rawText.setCharAt(cursor, ch); + } else { + rawText.append(ch); + } + scanLine(); + cursor++; } }