*
* The MIT License (MIT)
*
- * Copyright (C) 2017 Kevin Lamonte
+ * Copyright (C) 2019 Kevin Lamonte
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
*/
public class TField extends TWidget {
- /**
- * Field text.
- */
- protected String text = "";
+ // ------------------------------------------------------------------------
+ // Variables --------------------------------------------------------------
+ // ------------------------------------------------------------------------
/**
- * Get field text.
- *
- * @return field text
+ * Background character for unfilled-in text.
*/
- public final String getText() {
- return text;
- }
+ protected char backgroundChar = GraphicsChars.HATCH;
/**
- * Set field text.
- *
- * @param text the new field text
+ * Field text.
*/
- public final void setText(String text) {
- this.text = text;
- position = 0;
- windowStart = 0;
- }
+ protected String text = "";
/**
* If true, only allow enough characters that will fit in the width. If
*/
protected TAction updateAction;
+ /**
+ * The color to use when this field is active.
+ */
+ private String activeColorKey = "tfield.active";
+
+ /**
+ * The color to use when this field is not active.
+ */
+ private String inactiveColorKey = "tfield.inactive";
+
+ // ------------------------------------------------------------------------
+ // Constructors -----------------------------------------------------------
+ // ------------------------------------------------------------------------
+
/**
* Public constructor.
*
this.updateAction = updateAction;
}
+ // ------------------------------------------------------------------------
+ // Event handlers ---------------------------------------------------------
+ // ------------------------------------------------------------------------
+
/**
* Returns true if the mouse is currently on the field.
*
return false;
}
- /**
- * Dispatch to the action function.
- *
- * @param enter if true, the user pressed Enter, else this was an update
- * to the text.
- */
- protected void dispatch(final boolean enter) {
- if (enter) {
- if (enterAction != null) {
- enterAction.DO();
- }
- } else {
- if (updateAction != null) {
- updateAction.DO();
- }
- }
- }
-
- /**
- * Draw the text field.
- */
- @Override
- public void draw() {
- CellAttributes fieldColor;
-
- if (isAbsoluteActive()) {
- fieldColor = getTheme().getColor("tfield.active");
- } else {
- fieldColor = getTheme().getColor("tfield.inactive");
- }
-
- int end = windowStart + getWidth();
- if (end > text.length()) {
- end = text.length();
- }
- getScreen().hLineXY(0, 0, getWidth(), GraphicsChars.HATCH, fieldColor);
- getScreen().putStringXY(0, 0, text.substring(windowStart, end),
- fieldColor);
-
- // Fix the cursor, it will be rendered by TApplication.drawAll().
- updateCursor();
- }
-
- /**
- * Update the cursor position.
- */
- protected void updateCursor() {
- if ((position > getWidth()) && fixed) {
- setCursorX(getWidth());
- } else if ((position - windowStart == getWidth()) && !fixed) {
- setCursorX(getWidth() - 1);
- } else {
- setCursorX(position - windowStart);
- }
- }
-
/**
* Handle mouse button presses.
*
windowStart--;
}
}
+ normalizeWindowStart();
return;
}
return;
}
if (keypress.equals(kbHome)) {
- position = 0;
- windowStart = 0;
+ home();
return;
}
if (keypress.equals(kbEnd)) {
- position = text.length();
- if (fixed == true) {
- if (position >= getWidth()) {
- position = text.length() - 1;
- }
- } else {
- windowStart = text.length() - getWidth() + 1;
- if (windowStart < 0) {
- windowStart = 0;
- }
- }
+ end();
return;
}
text = text.substring(0, position)
+ text.substring(position + 1);
}
+ dispatch(false);
return;
}
}
}
dispatch(false);
+ normalizeWindowStart();
return;
}
super.onKeypress(keypress);
}
+ // ------------------------------------------------------------------------
+ // TWidget ----------------------------------------------------------------
+ // ------------------------------------------------------------------------
+
+ /**
+ * Draw the text field.
+ */
+ @Override
+ public void draw() {
+ CellAttributes fieldColor;
+
+ if (isAbsoluteActive()) {
+ fieldColor = getTheme().getColor(activeColorKey);
+ } else {
+ fieldColor = getTheme().getColor(inactiveColorKey);
+ }
+
+ int end = windowStart + getWidth();
+ if (end > text.length()) {
+ end = text.length();
+ }
+ hLineXY(0, 0, getWidth(), backgroundChar, fieldColor);
+ putStringXY(0, 0, text.substring(windowStart, end), fieldColor);
+
+ // Fix the cursor, it will be rendered by TApplication.drawAll().
+ updateCursor();
+ }
+
+ // ------------------------------------------------------------------------
+ // TField -----------------------------------------------------------------
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get field background character.
+ *
+ * @return background character
+ */
+ public final char getBackgroundChar() {
+ return backgroundChar;
+ }
+
+ /**
+ * Set field background character.
+ *
+ * @param backgroundChar the background character
+ */
+ public void setBackgroundChar(final char backgroundChar) {
+ this.backgroundChar = backgroundChar;
+ }
+
+ /**
+ * Get field text.
+ *
+ * @return field text
+ */
+ public final String getText() {
+ return text;
+ }
+
+ /**
+ * Set field text.
+ *
+ * @param text the new field text
+ */
+ public void setText(final String text) {
+ assert (text != null);
+ this.text = text;
+ position = 0;
+ windowStart = 0;
+ }
+
+ /**
+ * Dispatch to the action function.
+ *
+ * @param enter if true, the user pressed Enter, else this was an update
+ * to the text.
+ */
+ protected void dispatch(final boolean enter) {
+ if (enter) {
+ if (enterAction != null) {
+ enterAction.DO();
+ }
+ } else {
+ if (updateAction != null) {
+ updateAction.DO();
+ }
+ }
+ }
+
+ /**
+ * Update the visible cursor position to match the location of position
+ * and windowStart.
+ */
+ protected void updateCursor() {
+ if ((position > getWidth()) && fixed) {
+ setCursorX(getWidth());
+ } else if ((position - windowStart == getWidth()) && !fixed) {
+ setCursorX(getWidth() - 1);
+ } else {
+ setCursorX(position - windowStart);
+ }
+ }
+
+ /**
+ * Normalize windowStart such that most of the field data if visible.
+ */
+ protected void normalizeWindowStart() {
+ if (fixed) {
+ // windowStart had better be zero, there is nothing to do here.
+ assert (windowStart == 0);
+ return;
+ }
+ windowStart = position - (getWidth() - 1);
+ if (windowStart < 0) {
+ windowStart = 0;
+ }
+
+ updateCursor();
+ }
+
/**
* Append char to the end of the field.
*
}
}
+ /**
+ * Position the cursor at the first column. The field may adjust the
+ * window start to show as much of the field as possible.
+ */
+ public void home() {
+ position = 0;
+ windowStart = 0;
+ }
+
+ /**
+ * Set the editing position to the last filled character. The field may
+ * adjust the window start to show as much of the field as possible.
+ */
+ public void end() {
+ position = text.length();
+ if (fixed == true) {
+ if (position >= getWidth()) {
+ position = text.length() - 1;
+ }
+ } else {
+ windowStart = text.length() - getWidth() + 1;
+ if (windowStart < 0) {
+ windowStart = 0;
+ }
+ }
+ }
+
+ /**
+ * Set the editing position. The field may adjust the window start to
+ * show as much of the field as possible.
+ *
+ * @param position the new position
+ * @throws IndexOutOfBoundsException if position is outside the range of
+ * the available text
+ */
+ public void setPosition(final int position) {
+ if ((position < 0) || (position >= text.length())) {
+ throw new IndexOutOfBoundsException("Max length is " +
+ text.length() + ", requested position " + position);
+ }
+ this.position = position;
+ normalizeWindowStart();
+ }
+
+ /**
+ * Set the active color key.
+ *
+ * @param activeColorKey ColorTheme key color to use when this field is
+ * active
+ */
+ public void setActiveColorKey(final String activeColorKey) {
+ this.activeColorKey = activeColorKey;
+ }
+
+ /**
+ * Set the inactive color key.
+ *
+ * @param inactiveColorKey ColorTheme key color to use when this field is
+ * inactive
+ */
+ public void setInactiveColorKey(final String inactiveColorKey) {
+ this.inactiveColorKey = inactiveColorKey;
+ }
+
+ /**
+ * Set the action to perform when the user presses enter.
+ *
+ * @param action the action to perform when the user presses enter
+ */
+ public void setEnterAction(final TAction action) {
+ enterAction = action;
+ }
+
+ /**
+ * Set the action to perform when the field is updated.
+ *
+ * @param action the action to perform when the field is updated
+ */
+ public void setUpdateAction(final TAction action) {
+ updateAction = action;
+ }
+
}