spaceisnear.game.ui.TextField.java Source code

Java tutorial

Introduction

Here is the source code for spaceisnear.game.ui.TextField.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package spaceisnear.game.ui;

import com.badlogic.gdx.*;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.scenes.scene2d.*;
import lombok.Getter;
import lombok.Setter;
import static spaceisnear.game.ui.UIElement.font;

/**
 *
 * @author White Oak
 */
public final class TextField extends UIElement {

    private static final int HEIGHT_PADDING = 2;
    private static final int WIDTH_PADDING = 10;
    private final static long DELTA_ACTED = 100L;

    private StringBuilder text = new StringBuilder();
    private int currentPosition;
    private Color textColor = new Color(0x0);
    @Getter
    private boolean focused;
    private int keycode;
    private long lastTimeActed;
    @Setter
    private Color borderColor = new Color(0x0);
    private final Color backgroundColor = new Color(0xf7f7ffdc);
    private final com.badlogic.gdx.scenes.scene2d.ui.TextField.OnscreenKeyboard keyboard = new com.badlogic.gdx.scenes.scene2d.ui.TextField.DefaultOnscreenKeyboard();
    //
    private OverflowTextField currentOverflow;

    public TextField() {
        this("");
    }

    public TextField(CharSequence text) {
        this.text.append(text);
    }

    @Override
    protected void init() {
        addListener(new InputListener() {

            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                if (currentOverflow == null) {
                    Stage stage = getStage();
                    if (stage != null) {
                        stage.setKeyboardFocus(TextField.this);
                        //         final Application.ApplicationType type = Gdx.app.getType();
                        final Application.ApplicationType type = Application.ApplicationType.Android;
                        switch (type) {
                        case Desktop:
                            int currentX = WIDTH_PADDING;
                            currentPosition = 0;
                            while (currentX < x && currentPosition < text.length()) {
                                currentPosition++;
                                //TODO
                                GlyphLayout glyphLayout = new GlyphLayout(font,
                                        text.subSequence(0, currentPosition));
                                currentX += glyphLayout.width;
                            }
                            break;
                        case Android:
                            currentPosition = text.length();
                            currentOverflow = new OverflowTextField(TextField.this, keyboard);
                            stage.addActor(currentOverflow);
                            currentOverflow.addToStage(stage);
                            keyboard.show(true);
                            break;
                        }
                    }
                }
                return true;
            }

            @Override
            public void touchDragged(InputEvent event, float x, float y, int pointer) {
                //      super.touchDragged(event, x, y, pointer);
                //      lastBlink = 0;
                //      cursorOn = false;
                //      setCursorPosition(x);
                //      hasSelection = true;
            }

            @Override
            public boolean keyDown(InputEvent event, int keycode) {
                TextField.this.keycode = keycode;
                lastTimeActed = 0;
                return true;
            }

            @Override
            public boolean keyTyped(InputEvent event, char character) {
                //      System.out.println(character);
                if (character == '\u0008') {
                    TextField.this.keycode = Input.Keys.BACKSPACE;
                    lastTimeActed = 0;
                } else if (character == '\n' || character == '\r') {
                    TextField.this.keycode = Input.Keys.ENTER;
                    lastTimeActed = 0;
                } else if (!Character.isIdentifierIgnorable(character)) {
                    addCharacter(character);
                }
                return true;
            }

            @Override
            public boolean keyUp(InputEvent event, int keycode) {
                TextField.this.keycode = 0;
                return true;
            }
        });
    }

    public boolean checkKeys(int keycode) {
        if (keycode != 0) {
            if (System.currentTimeMillis() - lastTimeActed > DELTA_ACTED) {
                switch (keycode) {
                case Input.Keys.ENTER:
                    activated();
                    break;
                case Input.Keys.BACKSPACE:
                    removeLastCharacter();
                    break;
                case Input.Keys.LEFT:
                    currentPosition--;
                    if (currentPosition < 0) {
                        currentPosition = 0;
                    }
                    break;
                case Input.Keys.RIGHT:
                    currentPosition++;
                    if (currentPosition > text.length()) {
                        currentPosition = text.length();
                    }
                    break;
                default:
                    return false;
                }
                lastTimeActed = System.currentTimeMillis();
            }
            return true;
        }
        return false;
    }

    @Override
    public float getPrefHeight() {
        return font.getLineHeight() + HEIGHT_PADDING * 2;
    }

    @Override
    public float getPrefWidth() {
        return 200;
    }

    public void addCharacter(char c) {
        if (currentPosition >= text.length()) {
            text.append(c);
        } else {
            text.insert(currentPosition, c);
        }
        currentPosition++;
    }

    public void removeLastCharacter() {
        if (currentPosition > 0) {
            text.deleteCharAt(--currentPosition);
        }
    }

    @Override
    public void paint(Batch batch) {
        if (checkKeys(keycode)) {
            keycode = 0;
        }
        ShapeRenderer renderer = getRenderer();
        focused = getStage().getKeyboardFocus() == this;
        int start = 0;
        int end = text.length();
        int startingXText = 0;
        //TODO
        GlyphLayout glyphLayout = new GlyphLayout(font, text);
        if (glyphLayout.width > getWidthWithoutPaddings()) {
            end = text.length();
            start = end - 1;
            glyphLayout.setText(font, text, start, end, textColor, getWidthWithoutPaddings(), 0, false, null);
            while (start > 0 && glyphLayout.width < getWidthWithoutPaddings()) {
                start--;
            }
            glyphLayout.setText(font, text, 0, start, textColor, getWidthWithoutPaddings(), 0, false, null);
            startingXText = (int) -glyphLayout.width;
        }
        //
        {
            Gdx.gl.glEnable(GL20.GL_BLEND);
            Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
            renderer.setProjectionMatrix(batch.getProjectionMatrix());
            renderer.begin(ShapeRenderer.ShapeType.Filled);
            renderer.setColor(backgroundColor);
            renderer.rect(0, 0, getWidth(), getHeight());
            renderer.end();
            Gdx.gl.glDisable(GL20.GL_BLEND);
        }
        {
            renderer.begin(ShapeRenderer.ShapeType.Line);
            renderer.setColor(borderColor);
            renderer.rect(0, 0, getWidth() + 1, getHeight());
            renderer.end();
        }
        //cursor
        renderer.begin(ShapeRenderer.ShapeType.Line);
        font.setColor(Color.BLACK);
        if (focused) {
            glyphLayout.setText(font, text, 0, currentPosition, textColor, getWidthWithoutPaddings(), 0, false,
                    null);
            final float x = 10 + glyphLayout.width + startingXText;
            renderer.line(x, 3, x, font.getLineHeight() + 2);
            renderer.line(x + 1, 3, x + 1, font.getLineHeight() + 2);
        }
        renderer.end();
        batch.begin();
        font.setColor(Color.BLACK);
        font.draw(batch, text.subSequence(start, end), WIDTH_PADDING + getX(), 3 + getY());
        batch.end();
    }

    private float getWidthWithoutPaddings() {
        return getWidth() - WIDTH_PADDING * 2;
    }

    public void setTextColor(Color textColor) {
        this.textColor = textColor;
    }

    public CharSequence getCharSequence() {
        return text;
    }

    public String getText() {
        return text.toString();
    }

    public void setText(CharSequence string) {
        text = new StringBuilder(string);
        currentPosition = text.length();
    }

    @Override
    public void clear() {
        text.setLength(0);
    }

    @Override
    protected void activated() {
        super.activated();
        getStage().setKeyboardFocus(null);
        if (currentOverflow != null) {
            currentOverflow.activated();
            currentOverflow = null;
        }
    }

}