feat(ui/button): implement more events & simulators
This commit implements events onHoverEnter/onHoverExit. Simulators have .click() to simulate click, .hoverEnter()/.hoverExit() and so on.
This commit is contained in:
@ -10,9 +10,12 @@ import org.vibecoders.moongazer.managers.Assets;
|
|||||||
import org.vibecoders.moongazer.ui.UITextButton;
|
import org.vibecoders.moongazer.ui.UITextButton;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.InputListener;
|
||||||
import com.badlogic.gdx.video.VideoPlayer;
|
import com.badlogic.gdx.video.VideoPlayer;
|
||||||
import com.badlogic.gdx.video.VideoPlayerCreator;
|
import com.badlogic.gdx.video.VideoPlayerCreator;
|
||||||
|
|
||||||
@ -20,8 +23,10 @@ public class MainMenu extends Scene {
|
|||||||
private VideoPlayer videoPlayer;
|
private VideoPlayer videoPlayer;
|
||||||
private FileHandle videoFileHandle;
|
private FileHandle videoFileHandle;
|
||||||
private Texture titleTexture;
|
private Texture titleTexture;
|
||||||
|
private UITextButton[] buttons;
|
||||||
private float titleY, titleX, titleWidth, titleHeight;
|
private float titleY, titleX, titleWidth, titleHeight;
|
||||||
private boolean videoPrepared = false;
|
private boolean videoPrepared = false;
|
||||||
|
private int currentChoice = -1;
|
||||||
|
|
||||||
public MainMenu(Game game) {
|
public MainMenu(Game game) {
|
||||||
super(game);
|
super(game);
|
||||||
@ -55,6 +60,7 @@ public class MainMenu extends Scene {
|
|||||||
UITextButton loadButton = new UITextButton("Load", font);
|
UITextButton loadButton = new UITextButton("Load", font);
|
||||||
UITextButton settingsButton = new UITextButton("Settings", font);
|
UITextButton settingsButton = new UITextButton("Settings", font);
|
||||||
UITextButton exitButton = new UITextButton("Exit", font);
|
UITextButton exitButton = new UITextButton("Exit", font);
|
||||||
|
buttons = new UITextButton[] { playButton, loadButton, settingsButton, exitButton };
|
||||||
|
|
||||||
int buttonWidth = 300;
|
int buttonWidth = 300;
|
||||||
int buttonHeight = 80;
|
int buttonHeight = 80;
|
||||||
@ -77,6 +83,7 @@ public class MainMenu extends Scene {
|
|||||||
exitButton.setSize(buttonWidth, buttonHeight);
|
exitButton.setSize(buttonWidth, buttonHeight);
|
||||||
exitButton.setPosition(centerX, startY - spacing * 3);
|
exitButton.setPosition(centerX, startY - spacing * 3);
|
||||||
|
|
||||||
|
// Mouse click handlers
|
||||||
playButton.onClick(() -> log.debug("Play clicked"));
|
playButton.onClick(() -> log.debug("Play clicked"));
|
||||||
loadButton.onClick(() -> log.debug("Load clicked"));
|
loadButton.onClick(() -> log.debug("Load clicked"));
|
||||||
settingsButton.onClick(() -> {
|
settingsButton.onClick(() -> {
|
||||||
@ -95,9 +102,65 @@ public class MainMenu extends Scene {
|
|||||||
root.addActor(settingsButton.getActor());
|
root.addActor(settingsButton.getActor());
|
||||||
root.addActor(exitButton.getActor());
|
root.addActor(exitButton.getActor());
|
||||||
|
|
||||||
|
// Keyboard navigation handling
|
||||||
|
initKeyboardHandling();
|
||||||
game.stage.addActor(root);
|
game.stage.addActor(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initKeyboardHandling() {
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
final int index = i;
|
||||||
|
buttons[i].onHoverEnter(() -> {
|
||||||
|
log.trace("Button hover enter: {}", index);
|
||||||
|
if (currentChoice != index) {
|
||||||
|
if (currentChoice != -1) {
|
||||||
|
buttons[currentChoice].hoverExit();
|
||||||
|
}
|
||||||
|
currentChoice = index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
buttons[i].onHoverExit(() -> {
|
||||||
|
if (currentChoice == index) {
|
||||||
|
currentChoice = -1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
root.addListener(new InputListener() {
|
||||||
|
@Override
|
||||||
|
public boolean keyDown(InputEvent event, int keycode) {
|
||||||
|
log.trace("Key pressed: {}", keycode);
|
||||||
|
switch (keycode) {
|
||||||
|
case Input.Keys.UP:
|
||||||
|
currentChoice = (currentChoice - 1 + 4) % 4;
|
||||||
|
break;
|
||||||
|
case Input.Keys.DOWN:
|
||||||
|
currentChoice = (currentChoice + 1) % 4;
|
||||||
|
break;
|
||||||
|
case Input.Keys.RIGHT:
|
||||||
|
case Input.Keys.ENTER:
|
||||||
|
if (currentChoice != -1) {
|
||||||
|
buttons[currentChoice].click();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (currentChoice != -1) {
|
||||||
|
log.trace("Current choice: {}", currentChoice);
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
if (i == currentChoice) {
|
||||||
|
buttons[i].hoverEnter();
|
||||||
|
} else {
|
||||||
|
buttons[i].hoverExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void startVideoOnce() {
|
private void startVideoOnce() {
|
||||||
if (videoPlayer == null || videoPrepared)
|
if (videoPlayer == null || videoPrepared)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
package org.vibecoders.moongazer.ui;
|
package org.vibecoders.moongazer.ui;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
import com.badlogic.gdx.scenes.scene2d.EventListener;
|
import com.badlogic.gdx.scenes.scene2d.EventListener;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Button;
|
import com.badlogic.gdx.scenes.scene2d.ui.Button;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||||
|
|
||||||
public abstract class UIButton {
|
public abstract class UIButton {
|
||||||
protected Actor actor;
|
public Actor actor;
|
||||||
protected Button button;
|
public Button button;
|
||||||
|
|
||||||
public Actor getActor() {
|
public Actor getActor() {
|
||||||
return actor;
|
return actor;
|
||||||
@ -24,12 +27,65 @@ public abstract class UIButton {
|
|||||||
actor.addListener(eventListener);
|
actor.addListener(eventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void click() {
|
||||||
|
// Thx ChatGPT
|
||||||
|
InputEvent down = new InputEvent();
|
||||||
|
down.setType(InputEvent.Type.touchDown);
|
||||||
|
down.setButton(Input.Buttons.LEFT);
|
||||||
|
down.setStageX(button.getX());
|
||||||
|
down.setStageY(button.getY());
|
||||||
|
button.fire(down);
|
||||||
|
|
||||||
|
InputEvent up = new InputEvent();
|
||||||
|
up.setType(InputEvent.Type.touchUp);
|
||||||
|
up.setButton(Input.Buttons.LEFT);
|
||||||
|
up.setStageX(button.getX());
|
||||||
|
up.setStageY(button.getY());
|
||||||
|
button.fire(up);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hoverEnter() {
|
||||||
|
InputEvent e = new InputEvent();
|
||||||
|
e.setType(InputEvent.Type.enter);
|
||||||
|
e.setPointer(-1);
|
||||||
|
button.fire(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hoverExit() {
|
||||||
|
InputEvent e = new InputEvent();
|
||||||
|
e.setType(InputEvent.Type.exit);
|
||||||
|
e.setPointer(-1);
|
||||||
|
button.fire(e);
|
||||||
|
}
|
||||||
|
|
||||||
public void onClick(Runnable action) {
|
public void onClick(Runnable action) {
|
||||||
button.addListener(new com.badlogic.gdx.scenes.scene2d.utils.ClickListener() {
|
button.addListener(new ClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) {
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
action.run();
|
action.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onHoverEnter(Runnable action) {
|
||||||
|
button.addListener(new ClickListener() {
|
||||||
|
@Override
|
||||||
|
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
|
||||||
|
if (pointer == -1) {
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onHoverExit(Runnable action) {
|
||||||
|
button.addListener(new ClickListener() {
|
||||||
|
@Override
|
||||||
|
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
|
||||||
|
if (pointer == -1) {
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user