refactor(ui): Moved logic of Menu
This commit is contained in:
parent
c2f895bc8b
commit
10b81d018c
@ -2,9 +2,7 @@ package cz.jzitnik.game.ui;
|
||||
|
||||
import org.jline.terminal.MouseEvent;
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.sprites.ui.Font;
|
||||
import cz.jzitnik.game.sprites.ui.Font.*;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -12,16 +10,44 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class Escape {
|
||||
private Game game;
|
||||
private int btnWidth;
|
||||
private int leftPad;
|
||||
private int mainTextHeight;
|
||||
private int buttonHeight;
|
||||
private int textButtonMargin;
|
||||
|
||||
private boolean[] buttonsHover = { false, false, false };
|
||||
private Menu menu;
|
||||
|
||||
public Escape(Game game) {
|
||||
this.game = game;
|
||||
this.menu = new Menu(game, "2DCraft", new String[] { "Continue", "Options", "Save and exit" },
|
||||
this::onButtonClick);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
menu.reset();
|
||||
}
|
||||
|
||||
public void render(StringBuilder buffer, Terminal terminal) {
|
||||
menu.render(buffer, terminal);
|
||||
}
|
||||
|
||||
public void mouse(MouseEvent mouseEvent, Terminal terminal, ScreenRenderer screenRenderer) {
|
||||
menu.handleMouse(mouseEvent, terminal, screenRenderer);
|
||||
}
|
||||
|
||||
private void onButtonClick(int index, ScreenRenderer screenRenderer) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
game.setWindow(Window.WORLD);
|
||||
break;
|
||||
case 1:
|
||||
// Options logic placeholder
|
||||
break;
|
||||
case 2:
|
||||
game.setWindow(Window.SAVE_EXIT);
|
||||
screenRenderer.render(game);
|
||||
game.getGameStates().dependencies.gameSaver.save(game);
|
||||
game.setWindow(Window.SAVED);
|
||||
screenRenderer.render(game);
|
||||
System.exit(0);
|
||||
break;
|
||||
}
|
||||
screenRenderer.render(game);
|
||||
}
|
||||
|
||||
public void renderSave(StringBuilder buffer, Terminal terminal) {
|
||||
@ -43,143 +69,4 @@ public class Escape {
|
||||
buffer.append("\n".repeat(top));
|
||||
buffer.append(savingText.getData());
|
||||
}
|
||||
|
||||
public void render(StringBuilder buffer, Terminal terminal) {
|
||||
var font = game.getGameStates().dependencies.font;
|
||||
var width = terminal.getWidth();
|
||||
var height = terminal.getHeight();
|
||||
|
||||
log.debug("Terminal width: {}", width);
|
||||
log.debug("Terminal height: {}", height);
|
||||
|
||||
var twodcraft = font.line(terminal, "2DCraft", Size.LARGE, Align.CENTER);
|
||||
buffer.append(twodcraft.getData());
|
||||
mainTextHeight = twodcraft.getHeight();
|
||||
|
||||
if (height < 600) {
|
||||
textButtonMargin = 15;
|
||||
} else if (height < 800) {
|
||||
textButtonMargin = 30;
|
||||
} else {
|
||||
textButtonMargin = 50;
|
||||
}
|
||||
|
||||
buffer.append("\n".repeat(textButtonMargin));
|
||||
|
||||
renderButton(buffer, "Continue", width, font, terminal, buttonsHover[0]);
|
||||
buffer.append("\n".repeat(textButtonMargin / 2));
|
||||
renderButton(buffer, "Options", width, font, terminal, buttonsHover[1]);
|
||||
buffer.append("\n".repeat(textButtonMargin / 2));
|
||||
renderButton(buffer, "Save and exit", width, font, terminal, buttonsHover[2]);
|
||||
}
|
||||
|
||||
public void mouse(MouseEvent mouseEvent, Terminal terminal, ScreenRenderer screenRenderer) {
|
||||
int x = mouseEvent.getX();
|
||||
int y = mouseEvent.getY();
|
||||
var type = mouseEvent.getType();
|
||||
|
||||
int buttonx = x - leftPad;
|
||||
int buttony = y - (mainTextHeight + textButtonMargin);
|
||||
int margin = textButtonMargin / 2;
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
if (buttonx > 0 && buttonx <= btnWidth) {
|
||||
// Continue
|
||||
if (buttony > 0 && buttony < buttonHeight) {
|
||||
if (type == MouseEvent.Type.Pressed) {
|
||||
game.setWindow(Window.WORLD);
|
||||
screenRenderer.render(game);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buttonsHover[0] == false) {
|
||||
buttonsHover[0] = true;
|
||||
changed = true;
|
||||
}
|
||||
} else if (buttonsHover[0]) {
|
||||
buttonsHover[0] = false;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Options
|
||||
if (buttony > buttonHeight + margin && buttony < 2 * buttonHeight + margin) {
|
||||
if (type == MouseEvent.Type.Pressed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buttonsHover[1] == false) {
|
||||
buttonsHover[1] = true;
|
||||
changed = true;
|
||||
}
|
||||
} else if (buttonsHover[1]) {
|
||||
buttonsHover[1] = false;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Save and exit
|
||||
if (buttony > 2 * (buttonHeight + margin) && buttony < buttonHeight + 2 * (buttonHeight + margin)) {
|
||||
if (type == MouseEvent.Type.Pressed) {
|
||||
game.setWindow(Window.SAVE_EXIT);
|
||||
screenRenderer.render(game);
|
||||
|
||||
// Save game
|
||||
game.getGameStates().dependencies.gameSaver.save(game);
|
||||
|
||||
game.setWindow(Window.SAVED);
|
||||
screenRenderer.render(game);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if (buttonsHover[2] == false) {
|
||||
buttonsHover[2] = true;
|
||||
changed = true;
|
||||
}
|
||||
} else if (buttonsHover[2]) {
|
||||
buttonsHover[2] = false;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
screenRenderer.render(game);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderButton(StringBuilder buffer, String txt, int width, Font font, Terminal terminal,
|
||||
boolean selected) {
|
||||
int btnWidth = Math.min(350, (int) (width * (3.0 / 4)));
|
||||
this.btnWidth = btnWidth;
|
||||
int leftPad = (width - btnWidth) / 2;
|
||||
this.leftPad = leftPad;
|
||||
log.debug("Button width: {}px ", btnWidth);
|
||||
|
||||
final String color = selected ? "[48;2;70;70;70m" : "[48;2;116;115;113m";
|
||||
|
||||
var text = font.line(terminal, txt, Size.SMALL, Align.CENTER, new Custom.Width(btnWidth - 4),
|
||||
new Background(color));
|
||||
int btnHeight = text.getHeight() + 4;
|
||||
this.buttonHeight = btnHeight;
|
||||
var lines = text.getData().split("\n");
|
||||
|
||||
for (int y = 0; y < btnHeight; y++) {
|
||||
buffer.append(" ".repeat(leftPad));
|
||||
if (y == 0 || y == 1 || y == btnHeight - 1 || y == btnHeight - 2) {
|
||||
buffer.append("\033").append(color).append(" ".repeat(btnWidth));
|
||||
} else {
|
||||
buffer.append("\033").append(color).append(" ".repeat(2));
|
||||
buffer.append(lines[y - 2]);
|
||||
buffer.append("\033").append(color).append(" ".repeat(2));
|
||||
}
|
||||
|
||||
buffer.append("\033[0m\n");
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for (int i = 0; i < buttonsHover.length; i++) {
|
||||
buttonsHover[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
120
src/main/java/cz/jzitnik/game/ui/Menu.java
Normal file
120
src/main/java/cz/jzitnik/game/ui/Menu.java
Normal file
@ -0,0 +1,120 @@
|
||||
package cz.jzitnik.game.ui;
|
||||
|
||||
import org.jline.terminal.MouseEvent;
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.sprites.ui.Font;
|
||||
import cz.jzitnik.game.sprites.ui.Font.*;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class Menu {
|
||||
private Game game;
|
||||
private String headingText;
|
||||
private String[] buttonLabels;
|
||||
private boolean[] buttonsHover;
|
||||
private int btnWidth;
|
||||
private int leftPad;
|
||||
private int mainTextHeight;
|
||||
private int buttonHeight;
|
||||
private int textButtonMargin;
|
||||
private ButtonClickHandler buttonClickHandler;
|
||||
|
||||
public Menu(Game game, String headingText, String[] buttonLabels, ButtonClickHandler buttonClickHandler) {
|
||||
this.game = game;
|
||||
this.headingText = headingText;
|
||||
this.buttonLabels = buttonLabels;
|
||||
this.buttonsHover = new boolean[buttonLabels.length];
|
||||
this.buttonClickHandler = buttonClickHandler;
|
||||
}
|
||||
|
||||
public void render(StringBuilder buffer, Terminal terminal) {
|
||||
var font = game.getGameStates().dependencies.font;
|
||||
var width = terminal.getWidth();
|
||||
var height = terminal.getHeight();
|
||||
|
||||
var heading = font.line(terminal, headingText, Size.LARGE, Align.CENTER);
|
||||
buffer.append(heading.getData());
|
||||
mainTextHeight = heading.getHeight();
|
||||
|
||||
textButtonMargin = (height < 600) ? 15 : (height < 800) ? 30 : 50;
|
||||
buffer.append("\n".repeat(textButtonMargin));
|
||||
|
||||
for (int i = 0; i < buttonLabels.length; i++) {
|
||||
renderButton(buffer, buttonLabels[i], width, font, terminal, buttonsHover[i]);
|
||||
buffer.append("\n".repeat(textButtonMargin / 2));
|
||||
}
|
||||
}
|
||||
|
||||
public void handleMouse(MouseEvent mouseEvent, Terminal terminal, ScreenRenderer screenRenderer) {
|
||||
int x = mouseEvent.getX();
|
||||
int y = mouseEvent.getY();
|
||||
var type = mouseEvent.getType();
|
||||
|
||||
int buttonx = x - leftPad;
|
||||
int buttony = y - (mainTextHeight + textButtonMargin);
|
||||
int margin = textButtonMargin / 2;
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
if (buttonx > 0 && buttonx <= btnWidth) {
|
||||
for (int i = 0; i < buttonLabels.length; i++) {
|
||||
int top = i * (buttonHeight + margin);
|
||||
int bottom = top + buttonHeight;
|
||||
|
||||
if (buttony > top && buttony < bottom) {
|
||||
if (type == MouseEvent.Type.Pressed) {
|
||||
buttonClickHandler.onClick(i, screenRenderer);
|
||||
return;
|
||||
}
|
||||
if (!buttonsHover[i]) {
|
||||
buttonsHover[i] = true;
|
||||
changed = true;
|
||||
}
|
||||
} else if (buttonsHover[i]) {
|
||||
buttonsHover[i] = false;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
screenRenderer.render(game);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderButton(StringBuilder buffer, String txt, int width, Font font, Terminal terminal, boolean selected) {
|
||||
btnWidth = Math.min(350, (int) (width * (3.0 / 4)));
|
||||
leftPad = (width - btnWidth) / 2;
|
||||
log.debug("Button width: {}px ", btnWidth);
|
||||
|
||||
final String color = selected ? "[48;2;70;70;70m" : "[48;2;116;115;113m";
|
||||
var text = font.line(terminal, txt, Size.SMALL, Align.CENTER, new Custom.Width(btnWidth - 4), new Background(color));
|
||||
buttonHeight = text.getHeight() + 4;
|
||||
var lines = text.getData().split("\n");
|
||||
|
||||
for (int y = 0; y < buttonHeight; y++) {
|
||||
buffer.append(" ".repeat(leftPad));
|
||||
if (y < 2 || y >= buttonHeight - 2) {
|
||||
buffer.append("\033").append(color).append(" ".repeat(btnWidth));
|
||||
} else {
|
||||
buffer.append("\033").append(color).append(" ".repeat(2));
|
||||
buffer.append(lines[y - 2]);
|
||||
buffer.append("\033").append(color).append(" ".repeat(2));
|
||||
}
|
||||
buffer.append("\033[0m\n");
|
||||
}
|
||||
}
|
||||
|
||||
interface ButtonClickHandler {
|
||||
void onClick(int index, ScreenRenderer screenRenderer);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for (int i = 0; i < buttonsHover.length; i++) {
|
||||
buttonsHover[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user