package org.terasology.rendering.gui.components; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; import org.newdawn.slick.Color; import org.terasology.asset.AssetType; import org.terasology.asset.AssetUri; import org.terasology.logic.manager.AudioManager; import org.terasology.rendering.gui.framework.IInputDataElement; import org.terasology.rendering.gui.framework.IInputListener; import org.terasology.rendering.gui.framework.UIDisplayContainer; import javax.vecmath.Vector2f; import java.util.ArrayList; /** * A simple graphical input * * @author Anton Kireev <adeon.k87@gmail.com> * @version 0.23 */ public class UIInput extends UIDisplayContainer implements IInputDataElement { // TODO: Add text selection and paste from clipboard private final ArrayList<IInputListener> _inputListeners = new ArrayList<IInputListener>(); private final StringBuffer _inputValue = new StringBuffer(); private final UIText _inputText; private final UITextCursor _textCursor; private final Vector2f _padding = new Vector2f(10f, 10f); private int _cursorPosition = 0; //The current position of the carriage private int _maxLength = 255; //The maximum number of characters that will be accepted as input private float _textWidthInContainer = 0; //The width of the text inside the INPUT field. private String _prevInputValue = new String(); public UIInput(Vector2f size) { setSize(size); setCrop(true); setStyle("background-image", "engine:gui_menu 256/512 30/512 0 90/512"); _inputText = new UIText(); _inputText.setVisible(true); _inputText.setColor(Color.black); _inputText.setPosition(new Vector2f(getPosition().x + _padding.x, getPosition().y + _padding.y)); _textCursor = new UITextCursor(); _textCursor.setVisible(true); _textCursor.setPosition(new Vector2f(getPosition().x + _padding.x, getPosition().y + _padding.y / 2)); addDisplayElement(_inputText); addDisplayElement(_textCursor); } @Override public void update() { Vector2f mousePos = new Vector2f(Mouse.getX(), Display.getHeight() - Mouse.getY()); if (intersects(mousePos)) { if (!_clickSoundPlayed) { AudioManager.play(new AssetUri(AssetType.SOUND, "engine:PlaceBlock")); _clickSoundPlayed = true; } if (_mouseUp) { _mouseUp = false; } if (_mouseDown) { clicked(mousePos); } } else { if (_mouseDown) { _focused = false; } _clickSoundPlayed = false; _mouseUp = false; _mouseDown = false; setStyle("background-position", "0 90/512"); } if (isFocused()) { if (!_textCursor.isVisible()) { _textCursor.setVisible(true); } setStyle("background-position", "0 120/512"); } else { if (_textCursor.isVisible()) { _textCursor.setVisible(false); } setStyle("background-position", "0 90/512"); } updateTextShift(); super.update(); } public void clicked(Vector2f mousePos) { _focused = true; if (_inputValue.length() > 0 && _inputText.getTextWidth() > 0) { Vector2f absolutePosition = _inputText.calcAbsolutePosition(); float positionRelativeElement = absolutePosition.x + _inputText.getTextWidth() - mousePos.x; float averageSymbols = _inputText.getTextWidth() / _inputValue.length(); int pos = Math.abs((int) (positionRelativeElement / averageSymbols) - _inputValue.length()); if (pos > _inputValue.length()) { pos = _inputValue.length(); } else if (pos < 0) { pos = 0; } _cursorPosition = pos; } } @Override public void processKeyboardInput(int key) { if (isFocused()) { if (key == Keyboard.KEY_BACK) { _cursorPosition--; if (_cursorPosition < 0) { _cursorPosition = 0; } if (_inputValue.length() > 0) { _prevInputValue = _inputValue.toString(); _inputValue.deleteCharAt(_cursorPosition); } } else if (key == Keyboard.KEY_LEFT) { _cursorPosition--; if (_cursorPosition < 0) { _cursorPosition = 0; } } else if (key == Keyboard.KEY_RIGHT) { _cursorPosition++; if (_cursorPosition > _inputValue.length()) { _cursorPosition = _inputValue.length(); } } else { if (_inputValue.length() > _maxLength) { return; } char c = Keyboard.getEventCharacter(); if (c >= 'a' && c < 'z' + 1 || c >= '0' && c < '9' + 1 || c >= 'A' && c < 'Z' + 1 || c == ' ' || c == '_' || c == '.' || c == ',' || c == '!' || c == '-' || c == '(' || c == ')' || c == '"' || c == '\'' || c == ';' || c == '+') { _prevInputValue = _inputValue.toString(); _inputValue.insert(_cursorPosition, c); _cursorPosition++; } } _inputText.setText(_inputValue.toString()); updateTextShift(); } } public void keyPressed() { for (int i = 0; i < _inputListeners.size(); i++) { _inputListeners.get(i).keyPressed(this); } } /* * Get current input value */ @Override public String getValue() { return _inputValue.toString(); } /* * Clear _inputValue; set cursor position to "0"; set input text to ""; */ @Override public void clearData() { if (_inputValue.length() > 0) { _inputValue.delete(0, _inputValue.length() - 1); } _cursorPosition = 0; _inputText.setText(""); } /* * Set current input value */ public void setValue(String value) { _inputValue.setLength(0); _inputValue.append(value); _inputText.setText(value); updateTextShift(); } /* * Set color text into input field */ public void setTextColor(Color color) { _inputText.setColor(color); } /* * Moves the text and the graphic text cursor accourding to the cursor's position. * */ private void updateTextShift() { float cursorPos = 0f; _textWidthInContainer = _inputText.getTextWidth() + _padding.x + _inputText.getPosition().x; if (_textWidthInContainer > getPosition().x + getSize().x || getPosition().x + _inputText.getPosition().x < 0) { _inputText.setPosition(new Vector2f(_inputText.getPosition().x + (getPosition().x + getSize().x - _textWidthInContainer), _inputText.getPosition().y)); } if (_cursorPosition != _inputValue.length()) { cursorPos = (_inputText.getFont().getWidth(_inputValue.toString().substring(0, _cursorPosition)) - _textCursor.getSize().x + _inputText.getPosition().x) / 2; } else { cursorPos = (_textWidthInContainer - _padding.x) / 2; } _textCursor.setPosition(new Vector2f(cursorPos, _textCursor.getPosition().y)); } @Override public boolean isFocused() { return _focused; } /* *Change the maximum number of characters that will be accepted as input */ public void setMaxLength(int max) { _maxLength = max; } /* * Get the maximum number of characters that will be accepted as input */ public int getMaxLength() { return _maxLength; } }