X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTField.java;h=90dd4e427abcf5660bfcc04b32b76c7c5da8edf7;hb=HEAD;hp=7b17ba87f7720da099233799792fed28a7572930;hpb=58c6a100ab285075df4df9d29923f72aa78ac0f8;p=fanfix.git diff --git a/src/jexer/TField.java b/src/jexer/TField.java index 7b17ba8..90dd4e4 100644 --- a/src/jexer/TField.java +++ b/src/jexer/TField.java @@ -31,14 +31,16 @@ package jexer; import jexer.bits.CellAttributes; import jexer.bits.GraphicsChars; import jexer.bits.StringUtils; +import jexer.event.TCommandEvent; import jexer.event.TKeypressEvent; import jexer.event.TMouseEvent; +import static jexer.TCommand.*; import static jexer.TKeypress.*; /** * TField implements an editable text field. */ -public class TField extends TWidget { +public class TField extends TWidget implements EditMenuUser { // ------------------------------------------------------------------------ // Variables -------------------------------------------------------------- @@ -47,7 +49,7 @@ public class TField extends TWidget { /** * Background character for unfilled-in text. */ - protected char backgroundChar = GraphicsChars.HATCH; + protected int backgroundChar = GraphicsChars.HATCH; /** * Field text. @@ -219,16 +221,12 @@ public class TField extends TWidget { if (keypress.equals(kbLeft)) { if (position > 0) { - if (position < text.length()) { - screenPosition -= StringUtils.width(text.charAt(position)); - } else { - screenPosition--; - } - position--; + screenPosition -= StringUtils.width(text.codePointBefore(position)); + position -= Character.charCount(text.codePointBefore(position)); } if (fixed == false) { if ((screenPosition == windowStart) && (windowStart > 0)) { - windowStart -= StringUtils.width(text.charAt( + windowStart -= StringUtils.width(text.codePointAt( screenToTextPosition(windowStart))); } } @@ -238,20 +236,25 @@ public class TField extends TWidget { if (keypress.equals(kbRight)) { if (position < text.length()) { - screenPosition += StringUtils.width(text.charAt(position)); - position++; + int lastPosition = position; + 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(lastPosition)); } } else { - if ((screenPosition - windowStart) >= getWidth()) { - windowStart += StringUtils.width(text.charAt( + while ((screenPosition - windowStart + + StringUtils.width(text.codePointAt(text.length() - 1))) + > getWidth() + ) { + windowStart += StringUtils.width(text.codePointAt( screenToTextPosition(windowStart))); } } } + assert (position <= text.length()); return; } @@ -286,7 +289,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 +298,7 @@ public class TField extends TWidget { if ((screenPosition >= windowStart) && (windowStart > 0) ) { - windowStart -= StringUtils.width(text.charAt( + windowStart -= StringUtils.width(text.codePointAt( screenToTextPosition(windowStart))); } } @@ -321,10 +324,10 @@ public class TField extends TWidget { 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()); @@ -338,19 +341,19 @@ 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()) { // Append this character @@ -374,10 +377,58 @@ public class TField extends TWidget { super.onKeypress(keypress); } + /** + * Handle posted command events. + * + * @param command command event + */ + @Override + public void onCommand(final TCommandEvent command) { + if (command.equals(cmCut)) { + // Copy text to clipboard, and then remove it. + getClipboard().copyText(text); + setText(""); + return; + } + + if (command.equals(cmCopy)) { + // Copy text to clipboard. + getClipboard().copyText(text); + return; + } + + if (command.equals(cmPaste)) { + // Paste text from clipboard. + String newText = getClipboard().pasteText(); + if (newText != null) { + setText(newText); + } + return; + } + + if (command.equals(cmClear)) { + // Remove text. + setText(""); + return; + } + + } + // ------------------------------------------------------------------------ // TWidget ---------------------------------------------------------------- // ------------------------------------------------------------------------ + /** + * Override TWidget's height: we can only set height at construction + * time. + * + * @param height new widget height (ignored) + */ + @Override + public void setHeight(final int height) { + // Do nothing + } + /** * Draw the text field. */ @@ -407,12 +458,25 @@ 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)); + assert (Character.charCount(ch) == sb.length()); + return sb.toString(); + } + /** * Get field background character. * * @return background character */ - public final char getBackgroundChar() { + public final int getBackgroundChar() { return backgroundChar; } @@ -421,7 +485,7 @@ public class TField extends TWidget { * * @param backgroundChar the background character */ - public void setBackgroundChar(final char backgroundChar) { + public void setBackgroundChar(final int backgroundChar) { this.backgroundChar = backgroundChar; } @@ -443,7 +507,11 @@ public class TField extends TWidget { assert (text != null); this.text = text; position = 0; + screenPosition = 0; windowStart = 0; + if ((fixed == true) && (this.text.length() > getWidth())) { + this.text = this.text.substring(0, getWidth()); + } } /** @@ -455,11 +523,11 @@ public class TField extends TWidget { protected void dispatch(final boolean enter) { if (enter) { if (enterAction != null) { - enterAction.DO(); + enterAction.DO(this); } } else { if (updateAction != null) { - updateAction.DO(); + updateAction.DO(this); } } } @@ -477,7 +545,7 @@ public class TField extends TWidget { int n = 0; for (int i = 0; i < text.length(); i++) { - n += StringUtils.width(text.charAt(i)); + n += StringUtils.width(text.codePointAt(i)); if (n >= screenPosition) { return i + 1; } @@ -521,19 +589,19 @@ public class TField extends TWidget { /** * Append char to the end of the field. * - * @param ch = char to append + * @param ch char to append */ - protected void appendChar(final char ch) { + 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()); if (fixed) { if (screenPosition >= getWidth()) { - position--; + position -= Character.charCount(ch); screenPosition -= StringUtils.width(ch); } } else { @@ -548,9 +616,10 @@ public class TField extends TWidget { * * @param ch char to append */ - protected void insertChar(final char ch) { - text = text.substring(0, position) + ch + text.substring(position); - position++; + protected void insertChar(final int ch) { + text = text.substring(0, position) + codePointString(ch) + + text.substring(position); + position += Character.charCount(ch); screenPosition += StringUtils.width(ch); if ((screenPosition - windowStart) == getWidth()) { assert (!fixed); @@ -577,7 +646,7 @@ public class TField extends TWidget { screenPosition = StringUtils.width(text); if (fixed == true) { if (screenPosition >= getWidth()) { - position = text.length() - 1; + position -= Character.charCount(text.codePointBefore(position)); screenPosition = StringUtils.width(text) - 1; } } else { @@ -599,7 +668,7 @@ public class TField extends TWidget { public void setPosition(final int position) { if ((position < 0) || (position >= text.length())) { throw new IndexOutOfBoundsException("Max length is " + - StringUtils.width(text) + ", requested position " + position); + text.length() + ", requested position " + position); } this.position = position; normalizeWindowStart(); @@ -643,4 +712,44 @@ public class TField extends TWidget { updateAction = action; } + // ------------------------------------------------------------------------ + // EditMenuUser ----------------------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * Check if the cut menu item should be enabled. + * + * @return true if the cut menu item should be enabled + */ + public boolean isEditMenuCut() { + return true; + } + + /** + * Check if the copy menu item should be enabled. + * + * @return true if the copy menu item should be enabled + */ + public boolean isEditMenuCopy() { + return true; + } + + /** + * Check if the paste menu item should be enabled. + * + * @return true if the paste menu item should be enabled + */ + public boolean isEditMenuPaste() { + return true; + } + + /** + * Check if the clear menu item should be enabled. + * + * @return true if the clear menu item should be enabled + */ + public boolean isEditMenuClear() { + return true; + } + }