v0.9.4: overhauled text input, now multiplatform using libGDX textField

This commit is contained in:
Evan Debenham
2021-07-08 12:38:45 -04:00
parent bcdbf8ef43
commit 7307c38a3c
12 changed files with 296 additions and 56 deletions

View File

@@ -37,7 +37,7 @@ public class Script extends Program {
@SuppressWarnings("unchecked")
public synchronized static<T extends Script> T use( Class<T> c ) {
if (c != curScriptClass) {
Script script = all.get( c );
@@ -45,11 +45,7 @@ public class Script extends Program {
script = Reflection.newInstance( c );
all.put( c, script );
}
if (curScript != null) {
curScript.unuse();
}
curScript = script;
curScriptClass = c;
curScript.use();
@@ -58,6 +54,11 @@ public class Script extends Program {
return (T)curScript;
}
public synchronized static void unuse(){
curScript = null;
curScriptClass = null;
}
public synchronized static void reset() {
for (Script script:all.values()) {
@@ -77,7 +78,5 @@ public class Script extends Program {
link();
}
public void unuse() {
}
}

View File

@@ -0,0 +1,149 @@
package com.watabou.noosa;
import com.badlogic.gdx.Files;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Container;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextArea;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.watabou.glscripts.Script;
import com.watabou.glwrap.Blending;
import com.watabou.glwrap.Quad;
import com.watabou.glwrap.Texture;
import com.watabou.noosa.ui.Component;
import com.watabou.utils.FileUtils;
import com.watabou.utils.Point;
//essentially contains a libGDX text input field, plus a PD-rendered background
public class TextInput extends Component {
private Stage stage;
private Container container;
private TextField textField;
private Skin skin;
private NinePatch bg;
public TextInput( NinePatch bg, boolean multiline ){
super();
this.bg = bg;
add(bg);
stage = new Stage(new ScreenViewport());
Game.inputHandler.addInputProcessor(stage);
container = new Container<TextField>();
stage.addActor(container);
container.setTransform(true);
skin = new Skin(FileUtils.getFileHandle(Files.FileType.Internal, "gdx/textfield.json"));
int zoom = (int) Camera.main.zoom;
int textSize = multiline ? 6 : 9;
TextField.TextFieldStyle style = skin.get(TextField.TextFieldStyle.class);
style.font = Game.platform.getFont(textSize*zoom, "", false, false);
style.background = null;
textField = multiline ? new TextArea("", style) : new TextField("", style);
textField.setProgrammaticChangeEvents(true);
if (!multiline) textField.setAlignment(Align.center);
textField.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
BitmapFont f = Game.platform.getFont(textSize*zoom, textField.getText(), false, false);
TextField.TextFieldStyle style = textField.getStyle();
if (f != style.font){
style.font = f;
textField.setStyle(style);
}
}
});
container.setActor(textField);
stage.setKeyboardFocus(textField);
Gdx.input.setOnscreenKeyboardVisible(true);
}
public void setText(String text){
textField.setText(text);
textField.setCursorPosition(textField.getText().length());
}
public void setMaxLength(int maxLength){
textField.setMaxLength(maxLength);
}
public String getText(){
return textField.getText();
}
@Override
protected void layout() {
super.layout();
float contX = x;
float contY = y;
float contW = width;
float contH = height;
if (bg != null){
bg.x = x;
bg.y = y;
bg.size(width, height);
contX += bg.marginLeft();
contY += bg.marginTop();
contW -= bg.marginHor();
contH -= bg.marginVer();
}
float zoom = Camera.main.zoom;
Camera c = camera();
if (c != null){
zoom = c.zoom;
Point p = c.cameraToScreen(contX, contY);
contX = p.x/zoom;
contY = p.y/zoom;
}
container.align(Align.topLeft);
container.setPosition(contX*zoom, (Game.height-(contY*zoom)));
container.size(contW*zoom, contH*zoom);
}
@Override
public void update() {
super.update();
stage.act(Game.elapsed);
}
@Override
public void draw() {
super.draw();
Quad.releaseIndices();
Script.unuse();
Texture.clear();
stage.draw();
Quad.bindIndices();
Blending.useDefault();
}
@Override
public synchronized void destroy() {
super.destroy();
if (stage != null) {
stage.dispose();
skin.dispose();
Game.inputHandler.removeInputProcessor(stage);
Gdx.input.setOnscreenKeyboardVisible(false);
Game.platform.updateSystemUI();
}
}
}

View File

@@ -37,15 +37,6 @@ public abstract class PlatformSupport {
public abstract void updateSystemUI();
public abstract boolean connectedToUnmeteredNetwork();
//FIXME this is currently used because no platform-agnostic text input has been implemented.
//should look into doing that using either plain openGL or libgdx's libraries
public abstract void promptTextInput( String title, String hintText, int maxLen, boolean multiLine,
String posTxt, String negTxt, TextCallback callback);
public static abstract class TextCallback {
public abstract void onSelect( boolean positive, String text );
}
public void vibrate( int millis ){
//regular GDX vibration by default