From d8726a4aa6fd9897b1d0df42ce201799ee785f4c Mon Sep 17 00:00:00 2001 From: Markil3 <75867393+Markil3@users.noreply.github.com> Date: Fri, 18 Dec 2020 11:06:59 -0700 Subject: [PATCH] Migrated both screens to use the same API, merging both files into the same library. --- .../controller/CalibrateInputScreen.java | 39 +-- .../controller/JoystickPreviewScreen.java | 226 ++++++++---------- src/main/java/markil3/controller/Main.java | 49 +++- .../controller/NewJoystickPreviewScreen.java | 80 ------- 4 files changed, 165 insertions(+), 229 deletions(-) rename {src => library/src}/main/java/markil3/controller/CalibrateInputScreen.java (97%) delete mode 100644 src/main/java/markil3/controller/NewJoystickPreviewScreen.java diff --git a/src/main/java/markil3/controller/CalibrateInputScreen.java b/library/src/main/java/markil3/controller/CalibrateInputScreen.java similarity index 97% rename from src/main/java/markil3/controller/CalibrateInputScreen.java rename to library/src/main/java/markil3/controller/CalibrateInputScreen.java index 395afda..aab007c 100644 --- a/src/main/java/markil3/controller/CalibrateInputScreen.java +++ b/library/src/main/java/markil3/controller/CalibrateInputScreen.java @@ -3,7 +3,6 @@ package markil3.controller; import com.jme3.app.Application; import com.jme3.app.SimpleApplication; import com.jme3.app.state.BaseAppState; -import com.jme3.collision.CollisionResults; import com.jme3.font.BitmapFont; import com.jme3.font.BitmapText; import com.jme3.font.Rectangle; @@ -21,14 +20,10 @@ import com.jme3.input.event.MouseButtonEvent; import com.jme3.input.event.MouseMotionEvent; import com.jme3.input.event.TouchEvent; import com.jme3.math.ColorRGBA; -import com.jme3.math.Ray; -import com.jme3.math.Vector2f; import com.jme3.renderer.Camera; -import com.jme3.scene.Geometry; import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; +import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; @@ -54,7 +49,6 @@ import static markil3.controller.JoystickPreviewScreen.R2; import static markil3.controller.JoystickPreviewScreen.R3; import static markil3.controller.JoystickPreviewScreen.SELECT; import static markil3.controller.JoystickPreviewScreen.START; -import static markil3.controller.Main.CALIBRATION_FILE; /** * Provides a series of prompts that will build a controller calibration file. @@ -71,9 +65,6 @@ public class CalibrateInputScreen extends BaseAppState new LinkedHashMap<>(); private static final LinkedHashMap AXIS_PROMPTS = new LinkedHashMap<>(); - final ColorRGBA BUTTON_COLOR = new ColorRGBA(0F, 0.1F, 0F, 1F); - final ColorRGBA HIGHLIGHTED_BUTTON_COLOR = - new ColorRGBA(0F, 0.75F, 0.25F, 1F); final String CLICK_MAPPING = "calibrateButtonClick"; static @@ -117,6 +108,7 @@ public class CalibrateInputScreen extends BaseAppState } } + private final File calibrationFile; private Node gui; protected BitmapFont guiFont; @@ -153,6 +145,15 @@ public class CalibrateInputScreen extends BaseAppState private HashMap defaultValues = new HashMap<>(); + /** + * Creates a screen for calibrating and remapping a game controller. + * @param calibrationFile - The file to store the results in. + */ + public CalibrateInputScreen(File calibrationFile) + { + this.calibrationFile = calibrationFile; + } + @Override protected void initialize(Application app) { @@ -324,6 +325,7 @@ public class CalibrateInputScreen extends BaseAppState this.getApplication().getInputManager() .removeRawInputListener(this); } + this.getApplication().getInputManager().removeListener(this); } /** @@ -343,8 +345,10 @@ public class CalibrateInputScreen extends BaseAppState */ protected void resize(int width, int height) { - float introHeight = GUIUtils.alignContainer(this.introCont, width, height); - float mainHeight = GUIUtils.alignContainer(this.mainOptions, width, height); + float introHeight = + GUIUtils.alignContainer(this.introCont, width, height); + float mainHeight = + GUIUtils.alignContainer(this.mainOptions, width, height); this.gui.setLocalTranslation(0, height / 2F, 0); this.introCont.setLocalTranslation((width) / 2F, (introHeight) / 2F, 0); this.mainOptions @@ -411,8 +415,7 @@ public class CalibrateInputScreen extends BaseAppState break; case "cancel": this.getStateManager().detach(this); - this.getStateManager() - .attach(new NewJoystickPreviewScreen()); + this.getStateManager().attach(new JoystickPreviewScreen()); break; case "close": this.getApplication().stop(); @@ -645,11 +648,11 @@ public class CalibrateInputScreen extends BaseAppState this.mainOptions.removeFromParent(); this.gamepad.removeFromParent(); - if (!CALIBRATION_FILE.exists()) + if (!calibrationFile.exists()) { try { - if (!CALIBRATION_FILE.createNewFile()) + if (!calibrationFile.createNewFile()) { throw new IOException("Could not create calibration file."); } @@ -668,7 +671,7 @@ public class CalibrateInputScreen extends BaseAppState } } - try (FileInputStream input = new FileInputStream(CALIBRATION_FILE)) + try (FileInputStream input = new FileInputStream(calibrationFile)) { props.load(input); } @@ -703,7 +706,7 @@ public class CalibrateInputScreen extends BaseAppState } } try (FileOutputStream output = new FileOutputStream( - CALIBRATION_FILE)) + calibrationFile)) { props.store(output, "Joystick Calibration File"); this.introCont.detachAllChildren(); diff --git a/library/src/main/java/markil3/controller/JoystickPreviewScreen.java b/library/src/main/java/markil3/controller/JoystickPreviewScreen.java index 859976f..69c17c2 100644 --- a/library/src/main/java/markil3/controller/JoystickPreviewScreen.java +++ b/library/src/main/java/markil3/controller/JoystickPreviewScreen.java @@ -14,15 +14,16 @@ import com.jme3.app.Application; import com.jme3.app.SimpleApplication; import com.jme3.app.state.BaseAppState; import com.jme3.asset.AssetManager; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; import com.jme3.font.BitmapFont; import com.jme3.font.BitmapText; import com.jme3.input.Joystick; import com.jme3.input.JoystickAxis; import com.jme3.input.JoystickButton; import com.jme3.input.JoystickConnectionListener; +import com.jme3.input.MouseInput; import com.jme3.input.RawInputListener; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; import com.jme3.input.event.JoyAxisEvent; import com.jme3.input.event.JoyButtonEvent; import com.jme3.input.event.KeyInputEvent; @@ -33,9 +34,8 @@ import com.jme3.material.Material; import com.jme3.material.RenderState.BlendMode; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; -import com.jme3.math.Ray; import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.shape.Quad; @@ -63,7 +63,7 @@ import java.util.Map; * @author Stephen Gold */ public class JoystickPreviewScreen extends BaseAppState - implements RawInputListener, JoystickConnectionListener + implements RawInputListener, JoystickConnectionListener, ActionListener { private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(JoystickPreviewScreen.class); @@ -122,6 +122,7 @@ public class JoystickPreviewScreen extends BaseAppState * Most gamepads may use {@link JoystickAxis#POV_Y} instead. */ public static final String DPAD_DOWN = "15"; + final String CLICK_MAPPING = "previewButtonClick"; /** * This node serves as the center of logic for each gamepad connected to @@ -559,10 +560,6 @@ public class JoystickPreviewScreen extends BaseAppState } } - final ColorRGBA BUTTON_COLOR = new ColorRGBA(0F, 0.1F, 0F, 1F); - final ColorRGBA HIGHLIGHTED_BUTTON_COLOR = - new ColorRGBA(0F, 0.75F, 0.25F, 1F); - protected Node gui; protected BitmapFont guiFont; @@ -590,6 +587,9 @@ public class JoystickPreviewScreen extends BaseAppState ((SimpleApplication) this.getApplication()).getGuiNode() .attachChild(this.gui); + + app.getInputManager().addMapping(CLICK_MAPPING, + new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); } /** @@ -670,9 +670,6 @@ public class JoystickPreviewScreen extends BaseAppState */ private void addButtons() { - Node button; - BitmapText buttonText; - Geometry buttonBackground; int i, l; /* @@ -690,33 +687,12 @@ public class JoystickPreviewScreen extends BaseAppState this.gamepadHeaders = new Node[l]; for (i = 0, l = this.gamepadCont.length; i < l; i++) { - button = new Node(); - buttonText = this.guiFont.createLabel("Gamepad " + - this.getApplication().getInputManager().getJoysticks()[i] - .getJoyId()); - buttonText.setUserData("gamepad", i); - buttonBackground = new Geometry("gamepad" + i, - new Quad(buttonText.getLineWidth() + 10, - buttonText.getLineHeight() + 5)); - buttonBackground.setMaterial( - new Material(this.getApplication().getAssetManager(), - "Common/MatDefs/Misc/Unshaded.j3md")); - if (this.gamepadCont[i].getParent() != null) - { - buttonBackground.getMaterial() - .setColor("Color", HIGHLIGHTED_BUTTON_COLOR); - } - else - { - buttonBackground.getMaterial().setColor("Color", BUTTON_COLOR); - } - buttonBackground.setUserData("gamepad", i); - buttonBackground - .setLocalTranslation(0, -buttonText.getLineHeight(), 0); - button.attachChild(buttonBackground); - button.attachChild(buttonText); - this.gui.attachChild(button); - this.gamepadHeaders[i] = button; + this.gamepadHeaders[i] = GUIUtils.createButton( + this.getApplication().getAssetManager(), this.guiFont, + "gamepad" + i, "Gamepad " + + this.getApplication().getInputManager() + .getJoysticks()[i].getJoyId()); + this.gui.attachChild(this.gamepadHeaders[i]); } } @@ -735,6 +711,7 @@ public class JoystickPreviewScreen extends BaseAppState protected void cleanup(Application app) { this.gui.removeFromParent(); + app.getInputManager().deleteMapping(CLICK_MAPPING); } @Override @@ -743,10 +720,9 @@ public class JoystickPreviewScreen extends BaseAppState this.getApplication().getInputManager().addRawInputListener(this); this.getApplication().getInputManager() .addJoystickConnectionListener(this); - this.resize(((SimpleApplication) this.getApplication()).getCamera() - .getWidth(), - ((SimpleApplication) this.getApplication()).getCamera() - .getHeight()); + this.resize(); + this.getApplication().getInputManager() + .addListener(this, CLICK_MAPPING); } @Override @@ -755,6 +731,7 @@ public class JoystickPreviewScreen extends BaseAppState this.getApplication().getInputManager().removeRawInputListener(this); this.getApplication().getInputManager() .removeJoystickConnectionListener(this); + this.getApplication().getInputManager().removeListener(this); } /** @@ -784,8 +761,8 @@ public class JoystickPreviewScreen extends BaseAppState /* * The name of the gamepad. */ - this.labels[joy.getJoyId()][0] = - this.guiFont.createLabel(joy.getName()); + this.labels[joy.getJoyId()][0] = this.guiFont.createLabel( + "Gamepad " + joy.getJoyId() + ": " + joy.getName()); this.labels[joy.getJoyId()][0].setLocalTranslation(20, -25, 0); this.gamepadCont[joy.getJoyId()] .attachChild(this.labels[joy.getJoyId()][0]); @@ -793,6 +770,8 @@ public class JoystickPreviewScreen extends BaseAppState * The key for the axis. Each of the axis rows will display the * index of the axis, its given name, its logical ID after * joystick remapping has occurred, and the axis index again. + * TODO - Whenever I add the " Gamepad X: " part to the previous + * label, this one displays all funky. */ this.labels[joy.getJoyId()][1] = this.guiFont .createLabel("Axis Index: Axis Name (logical ID, axis ID)"); @@ -912,11 +891,21 @@ public class JoystickPreviewScreen extends BaseAppState } /** - * Repositions the screen elements. - * @param width - The width of the screen. - * @param height - The height of the screen. + * Automatically scales and positions elements based on the camera + * dimensions. */ - public void resize(int width, int height) + public void resize() + { + Camera camera = this.getApplication().getCamera(); + this.resize(camera.getWidth(), camera.getHeight()); + } + + /** + * Scales and positions elements of this screen. + * @param width - The width to scale to. + * @param height - The height to scale to. + */ + protected void resize(int width, int height) { this.gui.setLocalTranslation(0, this.getScreenSize().y, 0); if (this.gamepadHeaders != null) @@ -989,18 +978,35 @@ public class JoystickPreviewScreen extends BaseAppState { } - /** - * A convenience method to discover what the mouse is currently over. - * @param x - The current X coordinate of the mouse. - * @param y - The current Y coordinate of the mouse. - * @return Collision results on the GUI. - */ - protected CollisionResults checkMouse(int x, int y) + @Override + public void onAction(String name, boolean isPressed, float tpf) { - CollisionResults results = new CollisionResults(); - Ray ray = new Ray(new Vector3f(x, y, 0), new Vector3f(x, y, 1)); - this.gui.collideWith(ray, results); - return results; + String buttonId; + int gamepad; + if (name.equals(CLICK_MAPPING)) + { + buttonId = GUIUtils.handleButtonPress(this.gui, + this.getApplication().getInputManager().getCursorPosition(), + isPressed); + if (!isPressed && buttonId != null) + { + if (buttonId.startsWith("gamepad")) + { + gamepad = Integer.parseInt(buttonId.substring(7)); + for (int i = 0, l = this.gamepadCont.length; i < l; i++) + { + if (i == gamepad) + { + this.gui.attachChild(this.gamepadCont[i]); + } + else + { + this.gamepadCont[i].removeFromParent(); + } + } + } + } + } } /** @@ -1011,36 +1017,35 @@ public class JoystickPreviewScreen extends BaseAppState @Override public void onMouseMotionEvent(MouseMotionEvent evt) { - ButtonView button = null; - CollisionResults results = this.checkMouse(evt.getX(), evt.getY()); - if (results.size() > 0) - { - for (CollisionResult result : results) - { - if (result.getGeometry().getUserData("view") != null) - { - if (result.getGeometry() - .getUserData("view") instanceof ButtonView) - { - button = result.getGeometry().getUserData("view"); - break; - } - } - } - } - if (button != null) - { - this.refLabel.setText(button.getName().substring(8)); - Vector2f size = this.getScreenSize(); - this.resize((int) size.x, (int) size.y); - } - else - { - if (this.refLabel.getText().length() > 0) - { - this.refLabel.setText(""); - } - } +// ButtonView button = null; +// CollisionResults results = this.checkMouse(evt.getX(), evt.getY()); +// if (results.size() > 0) +// { +// for (CollisionResult result : results) +// { +// if (result.getGeometry().getUserData("view") != null) +// { +// if (result.getGeometry() +// .getUserData("view") instanceof ButtonView) +// { +// button = result.getGeometry().getUserData("view"); +// break; +// } +// } +// } +// } +// if (button != null) +// { +// this.refLabel.setText(button.getName().substring(8)); +// this.resize(); +// } +// else +// { +// if (this.refLabel.getText().length() > 0) +// { +// this.refLabel.setText(""); +// } +// } } /** @@ -1050,41 +1055,6 @@ public class JoystickPreviewScreen extends BaseAppState @Override public void onMouseButtonEvent(MouseButtonEvent evt) { - Integer gamepad; - if (evt.isPressed() && evt.getButtonIndex() == 0) - { - CollisionResults results = this.checkMouse(evt.getX(), evt.getY()); - if (results.size() > 0) - { - for (CollisionResult result : results) - { - if (result.getGeometry().getUserData("gamepad") != null) - { - gamepad = result.getGeometry().getUserData("gamepad"); - for (int i = 0, l = this.gamepadCont.length; i < l; i++) - { - if (i == gamepad) - { - this.gui.attachChild(this.gamepadCont[i]); - ((Geometry) this.gamepadHeaders[i].getChild(0)) - .getMaterial().setColor("Color", - HIGHLIGHTED_BUTTON_COLOR); - evt.setConsumed(); - } - else - { - this.gamepadCont[i].removeFromParent(); - ((Geometry) this.gamepadHeaders[i].getChild(0)) - .getMaterial() - .setColor("Color", BUTTON_COLOR); - evt.setConsumed(); - } - } - break; - } - } - } - } } @Override @@ -1100,15 +1070,13 @@ public class JoystickPreviewScreen extends BaseAppState @Override public void onConnected(Joystick joystick) { - Vector2f size = this.getScreenSize(); this.updateGamepad(); - this.resize((int) size.x, (int) size.y); + this.resize(); } @Override public void onDisconnected(Joystick joystick) { - Vector2f size = this.getScreenSize(); /* * TODO - This callback will fire before the joystick is actually * removed. This is helpful at times, but it does mean we will have a @@ -1116,6 +1084,6 @@ public class JoystickPreviewScreen extends BaseAppState * removed. */ this.updateGamepad(); - this.resize((int) size.x, (int) size.y); + this.resize(); } } diff --git a/src/main/java/markil3/controller/Main.java b/src/main/java/markil3/controller/Main.java index df3cc52..84064b7 100644 --- a/src/main/java/markil3/controller/Main.java +++ b/src/main/java/markil3/controller/Main.java @@ -12,7 +12,10 @@ package markil3.controller; import com.jme3.app.DebugKeysAppState; import com.jme3.app.SimpleApplication; import com.jme3.app.StatsAppState; +import com.jme3.font.BitmapText; import com.jme3.input.JoystickCompatibilityMappings; +import com.jme3.input.controls.ActionListener; +import com.jme3.scene.Node; import com.jme3.system.AppSettings; import com.jme3.system.JmeSystem; @@ -27,7 +30,7 @@ import java.net.URL; * @author Markil 3 * @version 1.0 */ -public class Main extends SimpleApplication +public class Main extends SimpleApplication implements ActionListener { private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory. getLogger(Main.class); @@ -146,10 +149,12 @@ public class Main extends SimpleApplication app.start(); } + private Node calibrateButton; + public Main() { super(new StatsAppState(), new DebugKeysAppState(), - new NewJoystickPreviewScreen()); + new JoystickPreviewScreen()); } @Override @@ -177,5 +182,45 @@ public class Main extends SimpleApplication @Override public void simpleInitApp() { + this.calibrateButton = + GUIUtils.createButton(this.getAssetManager(), this.guiFont, + "calibrate", "Calibrate Gamepad"); + this.calibrateButton.setLocalTranslation((this.getCamera().getWidth() - + ((BitmapText) this.calibrateButton.getChild(1)).getLineWidth() - + 10) / 2F, this.getCamera().getHeight(), 0); + } + + @Override + public void simpleUpdate(float tpf) + { + JoystickPreviewScreen screen = this.getStateManager().getState(JoystickPreviewScreen.class); + if (this.calibrateButton.getParent() == null && screen != null) + { + this.guiNode.attachChild(this.calibrateButton); + this.inputManager.addListener(this, screen.CLICK_MAPPING); + } + else if (this.calibrateButton.getParent() != null && screen == null) + { + this.guiNode.detachChild(this.calibrateButton); + this.inputManager.removeListener(this); + } + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) + { + String buttonId; + JoystickPreviewScreen screen = this.getStateManager().getState(JoystickPreviewScreen.class); + if (screen != null && name.equals(screen.CLICK_MAPPING)) + { + buttonId = GUIUtils.handleButtonPress(this.calibrateButton, + this.getInputManager().getCursorPosition(), + isPressed); + if (!isPressed && "calibrate".equals(buttonId)) + { + this.getStateManager().detach(screen); + this.getStateManager().attach(new CalibrateInputScreen(CALIBRATION_FILE)); + } + } } } diff --git a/src/main/java/markil3/controller/NewJoystickPreviewScreen.java b/src/main/java/markil3/controller/NewJoystickPreviewScreen.java deleted file mode 100644 index 8558721..0000000 --- a/src/main/java/markil3/controller/NewJoystickPreviewScreen.java +++ /dev/null @@ -1,80 +0,0 @@ -package markil3.controller; - -import com.jme3.app.Application; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.font.BitmapText; -import com.jme3.input.event.MouseButtonEvent; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Quad; - -class NewJoystickPreviewScreen extends JoystickPreviewScreen -{ - private static final org.slf4j.Logger logger = - org.slf4j.LoggerFactory.getLogger(NewJoystickPreviewScreen.class); - - private Node calibrateButton; - - @Override - public void initialize(Application app) - { - super.initialize(app); - this.calibrateButton = new Node(); - BitmapText buttonText = this.guiFont.createLabel("Calibrate Gamepad"); - buttonText.setUserData("calibrate", true); - Geometry buttonBackground = new Geometry("calibrate", - new Quad(buttonText.getLineWidth() + 10, - buttonText.getLineHeight() + 5)); - buttonBackground.setMaterial(new Material(app.getAssetManager(), - "Common/MatDefs/Misc/Unshaded.j3md")); - buttonBackground.getMaterial() - .setColor("Color", new ColorRGBA(0F, 0.75F, 0.25F, 1F)); - buttonBackground.setUserData("calibrate", true); - buttonBackground.setLocalTranslation(0, -buttonText.getLineHeight(), 0); - this.calibrateButton.attachChild(buttonBackground); - this.calibrateButton.attachChild(buttonText); - this.gui.attachChild(this.calibrateButton); - } - - @Override - public void resize(int width, int height) - { - super.resize(width, height); - this.calibrateButton.setLocalTranslation( - (this.getApplication().getCamera().getWidth() - - ((BitmapText) this.calibrateButton.getChild(1)) - .getLineWidth() - 10) / 2F, - 0, 0); - } - - @Override - public void onMouseButtonEvent(MouseButtonEvent evt) - { - super.onMouseButtonEvent(evt); - if (!evt.isConsumed()) - { - if (evt.isPressed() && evt.getButtonIndex() == 0) - { - CollisionResults results = - this.checkMouse(evt.getX(), evt.getY()); - if (results.size() > 0) - { - for (CollisionResult result : results) - { - if (result.getGeometry().getUserData("calibrate") != - null) - { - evt.setConsumed(); - this.getStateManager().detach(this); - this.getStateManager().attach(new CalibrateInputScreen()); - break; - } - } - } - } - } - } -}