X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTField.java;h=681ce7e93e0cbf278dd0d6aaadd7a9e92c79c813;hb=6b2633acf2b801ac7353785746dd03603195e3ca;hp=3d727ea17ce1d19003646ec6091570e6173bb860;hpb=afdec5e9d0416e1c571f1961572b8ededef81146;p=nikiroo-utils.git diff --git a/src/jexer/TField.java b/src/jexer/TField.java index 3d727ea..681ce7e 100644 --- a/src/jexer/TField.java +++ b/src/jexer/TField.java @@ -219,16 +219,17 @@ public class TField extends TWidget { if (keypress.equals(kbLeft)) { if (position > 0) { - if (position < text.length()) { - screenPosition -= StringUtils.width(text.charAt(position)); + if (position < codePointLength(text)) { + screenPosition -= StringUtils.width(text.codePointBefore(position)); + position -= Character.charCount(text.codePointBefore(position)); } else { screenPosition--; + position--; } - position--; } if (fixed == false) { if ((screenPosition == windowStart) && (windowStart > 0)) { - windowStart -= StringUtils.width(text.charAt( + windowStart -= StringUtils.width(text.codePointAt( screenToTextPosition(windowStart))); } } @@ -237,17 +238,17 @@ public class TField extends TWidget { } if (keypress.equals(kbRight)) { - if (position < text.length()) { - screenPosition += StringUtils.width(text.charAt(position)); - position++; + if (position < codePointLength(text)) { + screenPosition += StringUtils.width(text.codePointAt(position)); + position += Character.charCount(text.codePointAt(position)); if (fixed == true) { if (screenPosition == getWidth()) { screenPosition--; - position--; + position -= Character.charCount(text.codePointAt(position)); } } else { if ((screenPosition - windowStart) >= getWidth()) { - windowStart += StringUtils.width(text.charAt( + windowStart += StringUtils.width(text.codePointAt( screenToTextPosition(windowStart))); } } @@ -275,7 +276,7 @@ public class TField extends TWidget { } if (keypress.equals(kbDel)) { - if ((text.length() > 0) && (position < text.length())) { + if ((codePointLength(text) > 0) && (position < codePointLength(text))) { text = text.substring(0, position) + text.substring(position + 1); screenPosition = StringUtils.width(text.substring(0, position)); @@ -286,7 +287,7 @@ public class TField extends TWidget { if (keypress.equals(kbBackspace) || keypress.equals(kbBackspaceDel)) { if (position > 0) { - position--; + position -= Character.charCount(text.codePointBefore(position)); text = text.substring(0, position) + text.substring(position + 1); screenPosition = StringUtils.width(text.substring(0, position)); @@ -295,7 +296,7 @@ public class TField extends TWidget { if ((screenPosition >= windowStart) && (windowStart > 0) ) { - windowStart -= StringUtils.width(text.charAt( + windowStart -= StringUtils.width(text.codePointAt( screenToTextPosition(windowStart))); } } @@ -309,27 +310,27 @@ public class TField extends TWidget { && !keypress.getKey().isCtrl() ) { // Plain old keystroke, process it - if ((position == text.length()) + if ((position == codePointLength(text)) && (StringUtils.width(text) < getWidth())) { // Append case appendChar(keypress.getKey().getChar()); - } else if ((position < text.length()) + } else if ((position < codePointLength(text)) && (StringUtils.width(text) < getWidth())) { // Overwrite or insert a character if (insertMode == false) { // Replace character text = text.substring(0, position) - + keypress.getKey().getChar() + + codePointString(keypress.getKey().getChar()) + text.substring(position + 1); - screenPosition += StringUtils.width(text.charAt(position)); - position++; + screenPosition += StringUtils.width(text.codePointAt(position)); + position += Character.charCount(keypress.getKey().getChar()); } else { // Insert character insertChar(keypress.getKey().getChar()); } - } else if ((position < text.length()) + } else if ((position < codePointLength(text)) && (StringUtils.width(text) >= getWidth())) { // Multiple cases here @@ -338,21 +339,21 @@ public class TField extends TWidget { } else if ((fixed == true) && (insertMode == false)) { // Overwrite the last character, maybe move position text = text.substring(0, position) - + keypress.getKey().getChar() + + codePointString(keypress.getKey().getChar()) + text.substring(position + 1); if (screenPosition < getWidth() - 1) { - screenPosition += StringUtils.width(text.charAt(position)); - position++; + screenPosition += StringUtils.width(text.codePointAt(position)); + position += Character.charCount(keypress.getKey().getChar()); } } else if ((fixed == false) && (insertMode == false)) { // Overwrite the last character, definitely move position text = text.substring(0, position) - + keypress.getKey().getChar() + + codePointString(keypress.getKey().getChar()) + text.substring(position + 1); - screenPosition += StringUtils.width(text.charAt(position)); - position++; + screenPosition += StringUtils.width(text.codePointAt(position)); + position += Character.charCount(keypress.getKey().getChar()); } else { - if (position == text.length()) { + if (position == codePointLength(text)) { // Append this character appendChar(keypress.getKey().getChar()); } else { @@ -407,6 +408,28 @@ public class TField extends TWidget { // TField ----------------------------------------------------------------- // ------------------------------------------------------------------------ + /** + * Convert a char (codepoint) to a string. + * + * @param ch the char + * @return the string + */ + private String codePointString(final int ch) { + StringBuilder sb = new StringBuilder(1); + sb.append(Character.toChars(ch)); + return sb.toString(); + } + + /** + * Get the number of codepoints in a string. + * + * @param str the string + * @return the number of codepoints + */ + private int codePointLength(final String str) { + return str.codePointCount(0, str.length()); + } + /** * Get field background character. * @@ -476,15 +499,15 @@ public class TField extends TWidget { } int n = 0; - for (int i = 0; i < text.length(); i++) { - n += StringUtils.width(text.charAt(i)); + for (int i = 0; i < codePointLength(text); i++) { + n += StringUtils.width(text.codePointAt(i)); if (n >= screenPosition) { return i + 1; } } // screenPosition exceeds the available text length. throw new IndexOutOfBoundsException("screenPosition " + screenPosition + - " exceeds available text length " + text.length()); + " exceeds available text length " + codePointLength(text)); } /** @@ -525,15 +548,15 @@ public class TField extends TWidget { */ protected void appendChar(final int ch) { // Append the LAST character - text += ch; - position++; + text += codePointString(ch); + position += Character.charCount(ch); screenPosition += StringUtils.width(ch); - assert (position == text.length()); + assert (position == codePointLength(text)); if (fixed) { if (screenPosition >= getWidth()) { - position--; + position -= Character.charCount(ch); screenPosition -= StringUtils.width(ch); } } else { @@ -549,8 +572,9 @@ public class TField extends TWidget { * @param ch char to append */ protected void insertChar(final int ch) { - text = text.substring(0, position) + ((char) ch) + text.substring(position); - position++; + text = text.substring(0, position) + codePointString(ch) + + text.substring(position); + position += Character.charCount(ch); screenPosition += StringUtils.width(ch); if ((screenPosition - windowStart) == getWidth()) { assert (!fixed); @@ -573,11 +597,11 @@ public class TField extends TWidget { * adjust the window start to show as much of the field as possible. */ public void end() { - position = text.length(); + position = codePointLength(text); screenPosition = StringUtils.width(text); if (fixed == true) { if (screenPosition >= getWidth()) { - position = text.length() - 1; + position = codePointLength(text) - 1; screenPosition = StringUtils.width(text) - 1; } } else { @@ -597,9 +621,9 @@ public class TField extends TWidget { * the available text */ public void setPosition(final int position) { - if ((position < 0) || (position >= text.length())) { + if ((position < 0) || (position >= codePointLength(text))) { throw new IndexOutOfBoundsException("Max length is " + - StringUtils.width(text) + ", requested position " + position); + codePointLength(text) + ", requested position " + position); } this.position = position; normalizeWindowStart();