mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Compare commits
11 Commits
7e913ff50f
...
TimerSongD
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da27399dda | ||
|
|
c98edc37a6 | ||
|
|
c21f254234 | ||
|
|
fd85a73608 | ||
|
|
ea7a5e11ba | ||
|
|
164708dcf5 | ||
|
|
eb5e69a59c | ||
|
|
b3c9f89f99 | ||
|
|
6b619604ec | ||
|
|
1ec1c0d13d | ||
|
|
0ab071693f |
@@ -1,400 +0,0 @@
|
|||||||
package org.toop.app.view;
|
|
||||||
|
|
||||||
import org.toop.framework.audio.events.AudioEvents;
|
|
||||||
import org.toop.framework.eventbus.EventFlow;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
import javafx.scene.control.ScrollPane;
|
|
||||||
import javafx.scene.control.Separator;
|
|
||||||
import javafx.scene.control.Slider;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import javafx.scene.layout.Region;
|
|
||||||
import javafx.scene.layout.StackPane;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class View {
|
|
||||||
private final boolean mainView;
|
|
||||||
|
|
||||||
private final StackPane view;
|
|
||||||
private final Map<String, Node> nodeMap;
|
|
||||||
|
|
||||||
protected View(boolean mainView, String cssClass) {
|
|
||||||
this.mainView = mainView;
|
|
||||||
|
|
||||||
view = new StackPane();
|
|
||||||
view.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
nodeMap = new HashMap<String, Node>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(Pos position, Node node) {
|
|
||||||
assert node != null;
|
|
||||||
|
|
||||||
StackPane.setAlignment(node, position);
|
|
||||||
view.getChildren().add(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Region hspacer() {
|
|
||||||
final Region hspacer = new Region();
|
|
||||||
hspacer.getStyleClass().add("hspacer");
|
|
||||||
|
|
||||||
return hspacer;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Region vspacer() {
|
|
||||||
final Region vspacer = new Region();
|
|
||||||
vspacer.getStyleClass().add("vspacer");
|
|
||||||
|
|
||||||
return vspacer;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ScrollPane fit(String identifier, String cssClass, Node node) {
|
|
||||||
assert node != null;
|
|
||||||
|
|
||||||
final ScrollPane fit = new ScrollPane(node);
|
|
||||||
fit.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
fit.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
|
|
||||||
fit.setFitToWidth(true);
|
|
||||||
fit.setFitToHeight(true);
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, fit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fit;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ScrollPane fit(String identifier, Node node) {
|
|
||||||
return fit(identifier, "fit", node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ScrollPane fit(Node node) {
|
|
||||||
return fit("", node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HBox hbox(String identifier, String cssClass, Node... nodes) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final HBox hbox = new HBox();
|
|
||||||
hbox.getStyleClass().add(cssClass);
|
|
||||||
hbox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
|
|
||||||
|
|
||||||
for (final Node node : nodes) {
|
|
||||||
if (node != null) {
|
|
||||||
hbox.getChildren().add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, hbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HBox hbox(String identifier, Node... nodes) {
|
|
||||||
return hbox(identifier, "container", nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HBox hbox(Node... nodes) {
|
|
||||||
return hbox("", nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HBox hboxFill(String identifier, String cssClass, Node... nodes) {
|
|
||||||
final HBox hbox = hbox(identifier, cssClass, nodes);
|
|
||||||
|
|
||||||
for (final Node node : hbox.getChildren()) {
|
|
||||||
if (node instanceof Region) {
|
|
||||||
((Region)node).setMaxHeight(Double.MAX_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HBox hboxFill(String identifier, Node... nodes) {
|
|
||||||
final HBox hbox = hbox(identifier, nodes);
|
|
||||||
|
|
||||||
for (final Node node : hbox.getChildren()) {
|
|
||||||
if (node instanceof Region) {
|
|
||||||
((Region)node).setMaxHeight(Double.MAX_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HBox hboxFill(Node... nodes) {
|
|
||||||
final HBox hbox = hbox(nodes);
|
|
||||||
|
|
||||||
for (final Node node : hbox.getChildren()) {
|
|
||||||
if (node instanceof Region) {
|
|
||||||
((Region)node).setMaxHeight(Double.MAX_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected VBox vbox(String identifier, String cssClass, Node... nodes) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final VBox vbox = new VBox();
|
|
||||||
vbox.getStyleClass().add(cssClass);
|
|
||||||
vbox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
|
|
||||||
|
|
||||||
for (final Node node : nodes) {
|
|
||||||
if (node != null) {
|
|
||||||
vbox.getChildren().add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, vbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
return vbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected VBox vbox(String identifier, Node... nodes) {
|
|
||||||
return vbox(identifier, "container", nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected VBox vbox(Node... nodes) {
|
|
||||||
return vbox("", nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected VBox vboxFill(String identifier, String cssClass, Node... nodes) {
|
|
||||||
final VBox vbox = vbox(identifier, cssClass, nodes);
|
|
||||||
|
|
||||||
for (final Node node : vbox.getChildren()) {
|
|
||||||
if (node instanceof Region) {
|
|
||||||
((Region)node).setMaxWidth(Double.MAX_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected VBox vboxFill(String identifier, Node... nodes) {
|
|
||||||
final VBox vbox = vbox(identifier, nodes);
|
|
||||||
|
|
||||||
for (final Node node : vbox.getChildren()) {
|
|
||||||
if (node instanceof Region) {
|
|
||||||
((Region)node).setMaxWidth(Double.MAX_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected VBox vboxFill(Node... nodes) {
|
|
||||||
final VBox vbox = vbox(nodes);
|
|
||||||
|
|
||||||
for (final Node node : vbox.getChildren()) {
|
|
||||||
if (node instanceof Region) {
|
|
||||||
((Region)node).setMaxWidth(Double.MAX_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Separator separator(String identifier, String cssClass) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final Separator separator = new Separator();
|
|
||||||
separator.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
return separator;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Separator separator(String identifier) {
|
|
||||||
return separator(identifier, "separator");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Separator separator() {
|
|
||||||
return separator("");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Text header(String identifier, String cssClass) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final Text header = new Text();
|
|
||||||
header.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, header);
|
|
||||||
}
|
|
||||||
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Text header(String identifier) {
|
|
||||||
return header(identifier, "header");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Text header() {
|
|
||||||
return header("");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Text text(String identifier, String cssClass) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final Text text = new Text();
|
|
||||||
text.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Text text(String identifier) {
|
|
||||||
return text(identifier, "text");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Text text() {
|
|
||||||
return text("");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Button button(String identifier, String cssClass) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final Button button = new Button();
|
|
||||||
button.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
button.setOnMouseClicked(_ -> {
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Button button(String identifier) {
|
|
||||||
return button(identifier, "button");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Button button() {
|
|
||||||
return button("");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Slider slider(String identifier, String cssClass) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final Slider slider = new Slider();
|
|
||||||
slider.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
slider.setMinorTickCount(0);
|
|
||||||
slider.setMajorTickUnit(1);
|
|
||||||
slider.setBlockIncrement(1);
|
|
||||||
|
|
||||||
slider.setSnapToTicks(true);
|
|
||||||
slider.setShowTickLabels(true);
|
|
||||||
|
|
||||||
slider.setOnMouseClicked(_ -> {
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, slider);
|
|
||||||
}
|
|
||||||
|
|
||||||
return slider;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Slider slider(String identifier) {
|
|
||||||
return slider(identifier, "slider");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Slider slider() {
|
|
||||||
return slider("");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TextField input(String identifier, String cssClass) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final TextField input = new TextField();
|
|
||||||
input.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
input.setOnMouseClicked(_ -> {
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TextField input(String identifier) {
|
|
||||||
return input(identifier, "input");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TextField input() {
|
|
||||||
return input("");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> ComboBox<T> combobox(String identifier, String cssClass) {
|
|
||||||
assert !nodeMap.containsKey(identifier);
|
|
||||||
|
|
||||||
final ComboBox<T> combobox = new ComboBox<T>();
|
|
||||||
combobox.getStyleClass().add(cssClass);
|
|
||||||
|
|
||||||
combobox.setOnMouseClicked(_ -> {
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!identifier.isEmpty()) {
|
|
||||||
nodeMap.put(identifier, combobox);
|
|
||||||
}
|
|
||||||
|
|
||||||
return combobox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> ComboBox<T> combobox(String identifier) {
|
|
||||||
return combobox(identifier, "combo-box");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> ComboBox<T> combobox() {
|
|
||||||
return combobox("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected <T extends Node> T get(String identifier) {
|
|
||||||
assert nodeMap.containsKey(identifier);
|
|
||||||
return (T) nodeMap.get(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void clear() {
|
|
||||||
view.getChildren().clear();
|
|
||||||
nodeMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMainView() { return mainView; }
|
|
||||||
public Region getView() { return view; }
|
|
||||||
|
|
||||||
public abstract void setup();
|
|
||||||
public void cleanup() {
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
package org.toop.app.view;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.scene.layout.StackPane;
|
|
||||||
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
public final class ViewStack {
|
|
||||||
private static boolean setup = false;
|
|
||||||
|
|
||||||
private static StackPane root;
|
|
||||||
|
|
||||||
private static View active;
|
|
||||||
private static Stack<View> stack;
|
|
||||||
|
|
||||||
public static void setup(Scene scene) {
|
|
||||||
assert scene != null;
|
|
||||||
|
|
||||||
if (setup) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
root = new StackPane();
|
|
||||||
|
|
||||||
active = null;
|
|
||||||
stack = new Stack<View>();
|
|
||||||
|
|
||||||
scene.setRoot(root);
|
|
||||||
|
|
||||||
setup = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void cleanup() {
|
|
||||||
assert setup;
|
|
||||||
|
|
||||||
final var count = stack.size();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active != null) {
|
|
||||||
active.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
setup = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reload() {
|
|
||||||
assert setup;
|
|
||||||
|
|
||||||
for (final var view : stack) {
|
|
||||||
view.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active != null) {
|
|
||||||
active.cleanup();
|
|
||||||
active.setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final var view : stack) {
|
|
||||||
view.setup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void push(View view) {
|
|
||||||
assert setup;
|
|
||||||
assert view != null;
|
|
||||||
|
|
||||||
if (view.isMainView()) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
if (active != null) {
|
|
||||||
root.getChildren().removeFirst();
|
|
||||||
active.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
root.getChildren().addFirst(view.getView());
|
|
||||||
view.setup();
|
|
||||||
|
|
||||||
active = view;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
stack.push(view);
|
|
||||||
root.getChildren().addLast(view.getView());
|
|
||||||
view.setup();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void pop() {
|
|
||||||
assert setup;
|
|
||||||
|
|
||||||
if (stack.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
final var last = stack.pop();
|
|
||||||
root.getChildren().removeLast();
|
|
||||||
last.cleanup();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package org.toop.app.view.displays;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ProgressBar;
|
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import javafx.scene.paint.Color;
|
|
||||||
import org.toop.app.widget.Widget;
|
|
||||||
import org.toop.framework.audio.AudioEventListener;
|
|
||||||
import org.toop.framework.audio.events.AudioEvents;
|
|
||||||
import org.toop.framework.eventbus.EventFlow;
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
import org.toop.framework.eventbus.GlobalEventBus;
|
|
||||||
|
|
||||||
public class SongDisplay extends VBox implements Widget {
|
|
||||||
|
|
||||||
private final Text songTitle;
|
|
||||||
private final ProgressBar progressBar;
|
|
||||||
private final Text progressText;
|
|
||||||
private boolean paused = false;
|
|
||||||
|
|
||||||
public SongDisplay() {
|
|
||||||
new EventFlow()
|
|
||||||
.listen(this::updateTheSong);
|
|
||||||
|
|
||||||
setAlignment(Pos.CENTER);
|
|
||||||
getStyleClass().add("song-display");
|
|
||||||
|
|
||||||
songTitle = new Text("song playing");
|
|
||||||
songTitle.getStyleClass().add("song-title");
|
|
||||||
|
|
||||||
progressBar = new ProgressBar(0);
|
|
||||||
progressBar.getStyleClass().add("progress-bar");
|
|
||||||
|
|
||||||
progressText = new Text("0:00/0:00");
|
|
||||||
progressText.getStyleClass().add("progress-text");
|
|
||||||
|
|
||||||
Button skipButton = new Button(">>");
|
|
||||||
Button pauseButton = new Button("⏸");
|
|
||||||
Button previousButton = new Button("<<");
|
|
||||||
|
|
||||||
skipButton.getStyleClass().setAll("skip-button");
|
|
||||||
pauseButton.getStyleClass().setAll("pause-button");
|
|
||||||
previousButton.getStyleClass().setAll("previous-button");
|
|
||||||
|
|
||||||
skipButton.setOnAction( event -> {
|
|
||||||
GlobalEventBus.post(new AudioEvents.SkipMusic());
|
|
||||||
paused = false;
|
|
||||||
pauseButton.setText(getPlayString(paused));
|
|
||||||
});
|
|
||||||
|
|
||||||
pauseButton.setOnAction(event -> {
|
|
||||||
GlobalEventBus.post(new AudioEvents.PauseMusic());
|
|
||||||
paused = !paused;
|
|
||||||
pauseButton.setText(getPlayString(paused));
|
|
||||||
});
|
|
||||||
|
|
||||||
previousButton.setOnAction( event -> {
|
|
||||||
GlobalEventBus.post(new AudioEvents.PreviousMusic());
|
|
||||||
paused = false;
|
|
||||||
pauseButton.setText(getPlayString(paused));
|
|
||||||
});
|
|
||||||
|
|
||||||
HBox control = new HBox(10, previousButton, pauseButton, skipButton);
|
|
||||||
control.setAlignment(Pos.CENTER);
|
|
||||||
control.getStyleClass().add("controls");
|
|
||||||
|
|
||||||
getChildren().addAll(songTitle, progressBar, progressText, control);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTheSong(AudioEvents.PlayingMusic event) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
String text = event.name();
|
|
||||||
text = text.substring(0, text.length() - 4);
|
|
||||||
songTitle.setText(text);
|
|
||||||
double currentPos = event.currentPosition();
|
|
||||||
double duration = event.duration();
|
|
||||||
if (currentPos / duration > 0.05) {
|
|
||||||
double progress = currentPos / duration;
|
|
||||||
progressBar.setProgress(progress);
|
|
||||||
}
|
|
||||||
else if (currentPos / duration < 0.05) {
|
|
||||||
progressBar.setProgress(0.05);
|
|
||||||
}
|
|
||||||
progressText.setText(getTimeString(event.currentPosition(), event.duration()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTimeString(long position, long duration) {
|
|
||||||
long positionMinutes = position / 60;
|
|
||||||
long durationMinutes = duration / 60;
|
|
||||||
long positionSeconds = position % 60;
|
|
||||||
long durationSeconds = duration % 60;
|
|
||||||
String positionSecondsStr = String.valueOf(positionSeconds);
|
|
||||||
String durationSecondsStr = String.valueOf(durationSeconds);
|
|
||||||
|
|
||||||
if (positionSeconds < 10) {
|
|
||||||
positionSecondsStr = "0" + positionSeconds;
|
|
||||||
}
|
|
||||||
if (durationSeconds < 10) {
|
|
||||||
durationSecondsStr = "0" + durationSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
String time = positionMinutes + ":" + positionSecondsStr + " / " + durationMinutes + ":" + durationSecondsStr;
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getNode() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
private String getPlayString(boolean paused) {
|
|
||||||
if (paused) {
|
|
||||||
return "▶";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return "⏸";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.GameInformation;
|
|
||||||
import org.toop.app.Server;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.Slider;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public final class ChallengeView extends View {
|
|
||||||
private final GameInformation.Player playerInformation;
|
|
||||||
|
|
||||||
private final String challenger;
|
|
||||||
private final String game;
|
|
||||||
|
|
||||||
private final Consumer<GameInformation.Player> onAccept;
|
|
||||||
|
|
||||||
public ChallengeView(String challenger, String game, Consumer<GameInformation.Player> onAccept) {
|
|
||||||
super(false, "bg-popup");
|
|
||||||
|
|
||||||
playerInformation = new GameInformation.Player();
|
|
||||||
|
|
||||||
this.challenger = challenger;
|
|
||||||
this.game = game;
|
|
||||||
|
|
||||||
this.onAccept = onAccept;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text challengeText = text();
|
|
||||||
challengeText.setText(AppContext.getString("you-were-challenged-by"));
|
|
||||||
|
|
||||||
final Text challengerHeader = header();
|
|
||||||
challengerHeader.setText(challenger);
|
|
||||||
|
|
||||||
final Text gameText = text();
|
|
||||||
gameText.setText(AppContext.getString("to-a-game-of") + " " + game);
|
|
||||||
|
|
||||||
final Button acceptButton = button();
|
|
||||||
acceptButton.setText(AppContext.getString("accept"));
|
|
||||||
acceptButton.setOnAction(_ -> {
|
|
||||||
onAccept.accept(playerInformation);
|
|
||||||
});
|
|
||||||
|
|
||||||
final Button denyButton = button();
|
|
||||||
denyButton.setText(AppContext.getString("deny"));
|
|
||||||
denyButton.setOnAction(_ -> {
|
|
||||||
ViewStack.pop();
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<Node> nodes = new ArrayList<>();
|
|
||||||
|
|
||||||
if (playerInformation.isHuman) {
|
|
||||||
final Button playerToggle = button();
|
|
||||||
playerToggle.setText(AppContext.getString("player"));
|
|
||||||
playerToggle.setOnAction(_ -> {
|
|
||||||
playerInformation.isHuman = false;
|
|
||||||
cleanup();
|
|
||||||
setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vbox(playerToggle));
|
|
||||||
} else {
|
|
||||||
final Button computerToggle = button();
|
|
||||||
computerToggle.setText(AppContext.getString("computer"));
|
|
||||||
computerToggle.setOnAction(_ -> {
|
|
||||||
playerInformation.isHuman = true;
|
|
||||||
cleanup();
|
|
||||||
setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vbox(computerToggle));
|
|
||||||
|
|
||||||
final Text computerDifficultyText = text();
|
|
||||||
computerDifficultyText.setText(AppContext.getString("computer-difficulty"));
|
|
||||||
|
|
||||||
final Slider computerDifficultySlider = slider();
|
|
||||||
computerDifficultySlider.setMin(0);
|
|
||||||
computerDifficultySlider.setMax(Server.gameToType(game).getMaxDepth());
|
|
||||||
computerDifficultySlider.setValue(playerInformation.computerDifficulty);
|
|
||||||
computerDifficultySlider.valueProperty().addListener((_, _, newValue) -> {
|
|
||||||
playerInformation.computerDifficulty = newValue.intValue();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vbox(computerDifficultyText, computerDifficultySlider));
|
|
||||||
}
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(hboxFill(
|
|
||||||
vboxFill(
|
|
||||||
challengeText,
|
|
||||||
challengerHeader,
|
|
||||||
gameText,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
hboxFill(
|
|
||||||
acceptButton,
|
|
||||||
denyButton
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
nodes.toArray(new Node[0])
|
|
||||||
)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.App;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.animation.KeyFrame;
|
|
||||||
import javafx.animation.KeyValue;
|
|
||||||
import javafx.animation.Timeline;
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ScrollPane;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
import javafx.util.Duration;
|
|
||||||
|
|
||||||
public final class CreditsView extends View {
|
|
||||||
public CreditsView() {
|
|
||||||
super(false, "bg-primary");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text scrumMasterHeader = header();
|
|
||||||
scrumMasterHeader.setText(AppContext.getString("scrum-master") + ": Stef");
|
|
||||||
|
|
||||||
final Text productOwnerHeader = header();
|
|
||||||
productOwnerHeader.setText(AppContext.getString("product-owner") + ": Omar");
|
|
||||||
|
|
||||||
final Text mergeCommanderHeader = header();
|
|
||||||
mergeCommanderHeader.setText(AppContext.getString("merge-commander") + ": Bas");
|
|
||||||
|
|
||||||
final Text localizationHeader = header();
|
|
||||||
localizationHeader.setText(AppContext.getString("localization") + ": Ticho");
|
|
||||||
|
|
||||||
final Text aiHeader = header();
|
|
||||||
aiHeader.setText(AppContext.getString("ai") + ": Michiel");
|
|
||||||
|
|
||||||
final Text developersHeader = header();
|
|
||||||
developersHeader.setText(AppContext.getString("developers") + ": Michiel, Bas, Stef, Omar, Ticho");
|
|
||||||
|
|
||||||
final Text moralSupportHeader = header();
|
|
||||||
moralSupportHeader.setText(AppContext.getString("moral-support") + ": Wesley");
|
|
||||||
|
|
||||||
final Text openglHeader = header();
|
|
||||||
openglHeader.setText(AppContext.getString("opengl") + ": Omar");
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit("credits-fit", vboxFill("credits-container", "credits-container",
|
|
||||||
vbox("credits-spacer-top", ""),
|
|
||||||
|
|
||||||
scrumMasterHeader,
|
|
||||||
productOwnerHeader,
|
|
||||||
mergeCommanderHeader,
|
|
||||||
localizationHeader,
|
|
||||||
aiHeader,
|
|
||||||
developersHeader,
|
|
||||||
moralSupportHeader,
|
|
||||||
openglHeader,
|
|
||||||
|
|
||||||
vbox("credits-spacer-bottom", "")
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
final Button backButton = button();
|
|
||||||
backButton.setText(AppContext.getString("back"));
|
|
||||||
backButton.setOnAction(_ -> { ViewStack.pop(); });
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_LEFT,
|
|
||||||
vboxFill(
|
|
||||||
backButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
playCredits(100, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playCredits(int lineHeight, int length) {
|
|
||||||
final ScrollPane creditsFit = get("credits-fit");
|
|
||||||
creditsFit.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
|
||||||
creditsFit.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
|
||||||
|
|
||||||
final VBox creditsContainer = get("credits-container");
|
|
||||||
creditsContainer.setSpacing(lineHeight);
|
|
||||||
|
|
||||||
final VBox creditsSpacerTop = get("credits-spacer-top");
|
|
||||||
creditsSpacerTop.setMinHeight(App.getHeight() - lineHeight);
|
|
||||||
|
|
||||||
final VBox creditsSpacerBottom = get("credits-spacer-bottom");
|
|
||||||
creditsSpacerBottom.setMinHeight(App.getHeight() - lineHeight);
|
|
||||||
|
|
||||||
final Timeline timeline = new Timeline(
|
|
||||||
new KeyFrame(Duration.seconds(0), new KeyValue(creditsFit.vvalueProperty(), 0.0)),
|
|
||||||
new KeyFrame(Duration.seconds(length), new KeyValue(creditsFit.vvalueProperty(), 1.0))
|
|
||||||
);
|
|
||||||
|
|
||||||
timeline.setCycleCount(Timeline.INDEFINITE);
|
|
||||||
timeline.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
public final class ErrorView extends View {
|
|
||||||
private final String error;
|
|
||||||
|
|
||||||
public ErrorView(String error) {
|
|
||||||
super(false, "bg-popup");
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text errorHeader = header();
|
|
||||||
errorHeader.setText(AppContext.getString("error"));
|
|
||||||
|
|
||||||
final Text errorText = text();
|
|
||||||
errorText.setText(error);
|
|
||||||
|
|
||||||
final Button okButton = button();
|
|
||||||
okButton.setText(AppContext.getString("ok"));
|
|
||||||
okButton.setOnAction(_ -> { ViewStack.pop(); });
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
vboxFill(
|
|
||||||
errorHeader,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
vspacer(),
|
|
||||||
errorText,
|
|
||||||
vspacer(),
|
|
||||||
|
|
||||||
separator(),
|
|
||||||
okButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ListView;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public final class GameView extends View {
|
|
||||||
// TODO: This should be it's own file...
|
|
||||||
private static class GameOverView extends View {
|
|
||||||
private final boolean iWon;
|
|
||||||
private final String winner;
|
|
||||||
|
|
||||||
// TODO: Make winner generic, there is no "I won" unless you play online or against bot. Should be a generic "... won" to simplify
|
|
||||||
public GameOverView(boolean iWon, String winner) {
|
|
||||||
super(false, "bg-popup");
|
|
||||||
|
|
||||||
this.iWon = iWon;
|
|
||||||
this.winner = winner;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text gameOverHeader = header();
|
|
||||||
gameOverHeader.setText(AppContext.getString("game-over"));
|
|
||||||
|
|
||||||
final Button okButton = button();
|
|
||||||
okButton.setText(AppContext.getString("ok"));
|
|
||||||
okButton.setOnAction(_ -> { ViewStack.pop(); });
|
|
||||||
|
|
||||||
Text gameOverText = text();
|
|
||||||
|
|
||||||
if (winner.isEmpty()) {
|
|
||||||
gameOverText.setText(AppContext.getString("the-game-ended-in-a-draw"));
|
|
||||||
} else {
|
|
||||||
if (iWon) {
|
|
||||||
gameOverText.setText(AppContext.getString("you-win") + " " + winner);
|
|
||||||
} else {
|
|
||||||
gameOverText.setText(AppContext.getString("you-lost-against") + " " + winner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(vboxFill(
|
|
||||||
gameOverHeader,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
vspacer(),
|
|
||||||
gameOverText,
|
|
||||||
vspacer(),
|
|
||||||
|
|
||||||
separator(),
|
|
||||||
okButton
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Button forfeitButton;
|
|
||||||
private final Button exitButton;
|
|
||||||
|
|
||||||
private final Text currentPlayerHeader;
|
|
||||||
private final Text currentMoveHeader;
|
|
||||||
|
|
||||||
private final Text nextPlayerHeader;
|
|
||||||
|
|
||||||
private final Text gameStateFeedback = text();
|
|
||||||
|
|
||||||
private final ListView<Text> chatListView;
|
|
||||||
private final TextField chatInput;
|
|
||||||
|
|
||||||
public GameView(Runnable onForfeit, Runnable onExit, Consumer<String> onMessage) {
|
|
||||||
assert onExit != null;
|
|
||||||
|
|
||||||
super(true, "bg-primary");
|
|
||||||
|
|
||||||
if (onForfeit != null) {
|
|
||||||
forfeitButton = button();
|
|
||||||
forfeitButton.setText(AppContext.getString("forfeit"));
|
|
||||||
forfeitButton.setOnAction(_ -> onForfeit.run());
|
|
||||||
} else {
|
|
||||||
forfeitButton = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
if (onMessage != null) {
|
|
||||||
chatListView = new ListView<Text>();
|
|
||||||
|
|
||||||
chatInput = input();
|
|
||||||
chatInput.setOnAction(_ -> {
|
|
||||||
onMessage.accept(chatInput.getText());
|
|
||||||
chatInput.setText("");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
chatListView = null;
|
|
||||||
chatInput = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
exitButton = button();
|
|
||||||
exitButton.setText(AppContext.getString("exit"));
|
|
||||||
exitButton.setOnAction(_ -> onExit.run());
|
|
||||||
|
|
||||||
currentPlayerHeader = header("", "header");
|
|
||||||
currentMoveHeader = header();
|
|
||||||
nextPlayerHeader = header();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
add(
|
|
||||||
Pos.TOP_CENTER,
|
|
||||||
gameStateFeedback
|
|
||||||
);
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_LEFT,
|
|
||||||
vboxFill(
|
|
||||||
forfeitButton,
|
|
||||||
exitButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (chatListView != null) {
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
chatListView,
|
|
||||||
chatInput
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void nextPlayer(boolean isMe, String currentPlayer, String currentMove, String nextPlayer) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
gameStateFeedback.setText("Waiting on " + currentPlayer + " to make their move.");
|
|
||||||
currentPlayerHeader.setText(currentPlayer);
|
|
||||||
currentMoveHeader.setText(currentMove);
|
|
||||||
|
|
||||||
nextPlayerHeader.setText(nextPlayer);
|
|
||||||
|
|
||||||
if (isMe) {
|
|
||||||
currentPlayerHeader.getStyleClass().add("my-turn");
|
|
||||||
} else {
|
|
||||||
currentPlayerHeader.getStyleClass().remove("my-turn");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateChat(String message) {
|
|
||||||
if (chatListView == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Text messageText = text();
|
|
||||||
messageText.setText(message);
|
|
||||||
|
|
||||||
chatListView.getItems().add(messageText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void gameOver(boolean iWon, String winner) {
|
|
||||||
ViewStack.push(new GameOverView(iWon, winner));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.GameInformation;
|
|
||||||
import org.toop.app.game.Connect4Game;
|
|
||||||
import org.toop.app.game.ReversiGame;
|
|
||||||
import org.toop.app.game.TicTacToeGameThread;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.app.widget.Primitive;
|
|
||||||
import org.toop.app.widget.tutorial.BaseTutorialWidget;
|
|
||||||
import org.toop.app.widget.tutorial.TicTacToeTutorialWidget;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.Slider;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
import org.toop.local.AppSettings;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public final class LocalMultiplayerView extends View {
|
|
||||||
private final GameInformation information;
|
|
||||||
|
|
||||||
public LocalMultiplayerView(GameInformation information) {
|
|
||||||
super(true, "bg-primary");
|
|
||||||
this.information = information;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalMultiplayerView(GameInformation.Type type) {
|
|
||||||
this(new GameInformation(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Button playButton = button();
|
|
||||||
playButton.setText(AppContext.getString("play"));
|
|
||||||
playButton.setOnAction(_ -> {
|
|
||||||
for (final GameInformation.Player player : information.players) {
|
|
||||||
if (player.name.isEmpty()) {
|
|
||||||
ViewStack.push(new ErrorView(AppContext.getString("please-enter-your-name")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (information.type) {
|
|
||||||
case TICTACTOE: new TicTacToeGameThread(information); break;
|
|
||||||
case REVERSI: new ReversiGame(information); break;
|
|
||||||
case CONNECT4: new Connect4Game(information); break;
|
|
||||||
// case BATTLESHIP: new BattleshipGame(information); break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(vboxFill(
|
|
||||||
hbox(
|
|
||||||
setupPlayers()
|
|
||||||
),
|
|
||||||
|
|
||||||
separator(),
|
|
||||||
playButton
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
final Button backButton = button();
|
|
||||||
backButton.setText(AppContext.getString("back"));
|
|
||||||
backButton.setOnAction(_ -> { ViewStack.push(new MainView()); });
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_LEFT,
|
|
||||||
vboxFill(
|
|
||||||
backButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private VBox[] setupPlayers() {
|
|
||||||
final VBox[] playerBoxes = new VBox[information.type.getPlayerCount()];
|
|
||||||
|
|
||||||
for (int i = 0; i < playerBoxes.length; i++) {
|
|
||||||
final int index = i;
|
|
||||||
|
|
||||||
List<Node> nodes = new ArrayList<>();
|
|
||||||
|
|
||||||
final Text playerHeader = header();
|
|
||||||
playerHeader.setText(AppContext.getString("player") + " #" + (i + 1));
|
|
||||||
|
|
||||||
nodes.add(playerHeader);
|
|
||||||
nodes.add(separator());
|
|
||||||
|
|
||||||
final Text nameText = text();
|
|
||||||
nameText.setText(AppContext.getString("name"));
|
|
||||||
|
|
||||||
if (information.players[i].isHuman) {
|
|
||||||
final Button playerToggle = button();
|
|
||||||
playerToggle.setText(AppContext.getString("player"));
|
|
||||||
playerToggle.setOnAction(_ -> {
|
|
||||||
information.players[index].isHuman = false;
|
|
||||||
cleanup();
|
|
||||||
setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vboxFill(playerToggle));
|
|
||||||
|
|
||||||
final TextField playerNameInput = input();
|
|
||||||
playerNameInput.setPromptText(AppContext.getString("enter-your-name"));
|
|
||||||
playerNameInput.setText(information.players[i].name);
|
|
||||||
playerNameInput.textProperty().addListener((_, _, newValue) -> {
|
|
||||||
information.players[index].name = newValue;
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vboxFill(nameText, playerNameInput));
|
|
||||||
} else {
|
|
||||||
final Button computerToggle = button();
|
|
||||||
computerToggle.setText(AppContext.getString("computer"));
|
|
||||||
computerToggle.setOnAction(_ -> {
|
|
||||||
information.players[index].isHuman = true;
|
|
||||||
cleanup();
|
|
||||||
setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vboxFill(computerToggle));
|
|
||||||
|
|
||||||
information.players[i].name = "Pism Bot V" + i;
|
|
||||||
|
|
||||||
final Text computerNameText = text();
|
|
||||||
computerNameText.setText(information.players[index].name);
|
|
||||||
|
|
||||||
nodes.add(vboxFill(nameText, computerNameText));
|
|
||||||
|
|
||||||
final Text computerDifficultyText = text();
|
|
||||||
computerDifficultyText.setText(AppContext.getString("computer-difficulty"));
|
|
||||||
|
|
||||||
final Slider computerDifficultySlider = slider();
|
|
||||||
computerDifficultySlider.setMin(0);
|
|
||||||
computerDifficultySlider.setMax(information.type.getMaxDepth());
|
|
||||||
computerDifficultySlider.setValue(information.players[i].computerDifficulty);
|
|
||||||
computerDifficultySlider.valueProperty().addListener((_, _, newValue) -> {
|
|
||||||
information.players[index].computerDifficulty = newValue.intValue();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vboxFill(computerDifficultyText, computerDifficultySlider));
|
|
||||||
|
|
||||||
final Text computerThinkTimeText = text();
|
|
||||||
computerThinkTimeText.setText(AppContext.getString("computer-think-time"));
|
|
||||||
|
|
||||||
final Slider computerThinkTimeSlider = slider();
|
|
||||||
computerThinkTimeSlider.setMin(0);
|
|
||||||
computerThinkTimeSlider.setMax(5);
|
|
||||||
computerThinkTimeSlider.setValue(information.players[i].computerThinkTime);
|
|
||||||
computerThinkTimeSlider.valueProperty().addListener((_, _, newValue) -> {
|
|
||||||
information.players[index].computerThinkTime = newValue.intValue();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vboxFill(computerThinkTimeText, computerThinkTimeSlider));
|
|
||||||
}
|
|
||||||
|
|
||||||
playerBoxes[i] = vboxFill(nodes.toArray(new Node[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return playerBoxes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.GameInformation;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
|
|
||||||
public final class LocalView extends View {
|
|
||||||
public LocalView() {
|
|
||||||
super(true, "bg-primary");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Button ticTacToeButton = button();
|
|
||||||
ticTacToeButton.setText(AppContext.getString("tic-tac-toe"));
|
|
||||||
ticTacToeButton.setOnAction(_ -> { ViewStack.push(new LocalMultiplayerView(GameInformation.Type.TICTACTOE)); });
|
|
||||||
|
|
||||||
final Button reversiButton = button();
|
|
||||||
reversiButton.setText(AppContext.getString("reversi"));
|
|
||||||
reversiButton.setOnAction(_ -> { ViewStack.push(new LocalMultiplayerView(GameInformation.Type.REVERSI)); });
|
|
||||||
|
|
||||||
final Button connect4Button = button();
|
|
||||||
connect4Button.setText(AppContext.getString("connect4"));
|
|
||||||
connect4Button.setOnAction(_ -> { ViewStack.push(new LocalMultiplayerView(GameInformation.Type.CONNECT4)); });
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(vboxFill(
|
|
||||||
ticTacToeButton,
|
|
||||||
reversiButton,
|
|
||||||
connect4Button
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
final Button backButton = button();
|
|
||||||
backButton.setText(AppContext.getString("back"));
|
|
||||||
backButton.setOnAction(_ -> { ViewStack.push(new MainView()); });
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_LEFT,
|
|
||||||
vboxFill(
|
|
||||||
backButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.App;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
|
|
||||||
public final class MainView extends View {
|
|
||||||
public MainView() {
|
|
||||||
super(true, "bg-primary");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Button localButton = button();
|
|
||||||
localButton.setText(AppContext.getString("local"));
|
|
||||||
localButton.setOnAction(_ -> { ViewStack.push(new LocalView()); });
|
|
||||||
|
|
||||||
final Button onlineButton = button();
|
|
||||||
onlineButton.setText(AppContext.getString("online"));
|
|
||||||
onlineButton.setOnAction(_ -> { ViewStack.push(new OnlineView()); });
|
|
||||||
|
|
||||||
final Button creditsButton = button();
|
|
||||||
creditsButton.setText(AppContext.getString("credits"));
|
|
||||||
creditsButton.setOnAction(_ -> { ViewStack.push(new CreditsView()); });
|
|
||||||
|
|
||||||
final Button optionsButton = button();
|
|
||||||
optionsButton.setText(AppContext.getString("options"));
|
|
||||||
optionsButton.setOnAction(_ -> { ViewStack.push(new OptionsView()); });
|
|
||||||
|
|
||||||
final Button quitButton = button();
|
|
||||||
quitButton.setText(AppContext.getString("quit"));
|
|
||||||
quitButton.setOnAction(_ -> { App.startQuit(); });
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(vboxFill(
|
|
||||||
localButton,
|
|
||||||
onlineButton,
|
|
||||||
creditsButton,
|
|
||||||
optionsButton,
|
|
||||||
quitButton
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.Server;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
public class OnlineView extends View {
|
|
||||||
public OnlineView() {
|
|
||||||
super(true, "bg-primary");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text serverInformationHeader = header();
|
|
||||||
serverInformationHeader.setText(AppContext.getString("server-information"));
|
|
||||||
|
|
||||||
final Text serverIPText = text();
|
|
||||||
serverIPText.setText(AppContext.getString("ip-address"));
|
|
||||||
|
|
||||||
final TextField serverIPInput = input();
|
|
||||||
serverIPInput.setPromptText(AppContext.getString("enter-the-server-ip"));
|
|
||||||
|
|
||||||
final Text serverPortText = text();
|
|
||||||
serverPortText.setText(AppContext.getString("port"));
|
|
||||||
|
|
||||||
final TextField serverPortInput = input();
|
|
||||||
serverPortInput.setPromptText(AppContext.getString("enter-the-server-port"));
|
|
||||||
|
|
||||||
final Text playerNameText = text();
|
|
||||||
playerNameText.setText(AppContext.getString("player-name"));
|
|
||||||
|
|
||||||
final TextField playerNameInput = input();
|
|
||||||
playerNameInput.setPromptText(AppContext.getString("enter-your-name"));
|
|
||||||
|
|
||||||
final Button connectButton = button();
|
|
||||||
connectButton.setText(AppContext.getString("connect"));
|
|
||||||
connectButton.setOnAction(_ -> {
|
|
||||||
new Server(serverIPInput.getText(), serverPortInput.getText(), playerNameInput.getText());
|
|
||||||
});
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(vboxFill(
|
|
||||||
serverInformationHeader,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
serverIPText,
|
|
||||||
serverIPInput
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
serverPortText,
|
|
||||||
serverPortInput
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
playerNameText,
|
|
||||||
playerNameInput
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
connectButton
|
|
||||||
)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
final Button backButton = button();
|
|
||||||
backButton.setText(AppContext.getString("back"));
|
|
||||||
backButton.setOnAction(_ -> { ViewStack.push(new MainView()); });
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_LEFT,
|
|
||||||
vboxFill(
|
|
||||||
backButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.App;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.framework.audio.VolumeControl;
|
|
||||||
import org.toop.framework.audio.events.AudioEvents;
|
|
||||||
import org.toop.framework.eventbus.EventFlow;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
import org.toop.local.AppSettings;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
import javafx.scene.control.Slider;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
import javafx.util.StringConverter;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public final class OptionsView extends View {
|
|
||||||
public OptionsView() {
|
|
||||||
super(false, "bg-secondary");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text generalHeader = header();
|
|
||||||
generalHeader.setText(AppContext.getString("general"));
|
|
||||||
|
|
||||||
final Text volumeHeader = header();
|
|
||||||
volumeHeader.setText(AppContext.getString("volume"));
|
|
||||||
|
|
||||||
final Text styleHeader = header();
|
|
||||||
styleHeader.setText(AppContext.getString("style"));
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(hboxFill(
|
|
||||||
vboxFill(
|
|
||||||
generalHeader,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
text("language-text"),
|
|
||||||
combobox("language-combobox")
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
button("fullscreen-button")
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
volumeHeader,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
text("master-volume-text"),
|
|
||||||
slider("master-volume-slider")
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
text("effects-volume-text"),
|
|
||||||
slider("effects-volume-slider")
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
text("music-volume-text"),
|
|
||||||
slider("music-volume-slider")
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
styleHeader,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
text("theme-text"),
|
|
||||||
combobox("theme-combobox")
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
text("layout-text"),
|
|
||||||
combobox("layout-combobox")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
setupLanguageOption();
|
|
||||||
setupMasterVolumeOption();
|
|
||||||
setupEffectsVolumeOption();
|
|
||||||
setupMusicVolumeOption();
|
|
||||||
setupThemeOption();
|
|
||||||
setupLayoutOption();
|
|
||||||
setupFullscreenOption();
|
|
||||||
|
|
||||||
final Button backButton = button();
|
|
||||||
backButton.setText(AppContext.getString("back"));
|
|
||||||
backButton.setOnAction(_ -> { ViewStack.pop(); });
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_LEFT,
|
|
||||||
vboxFill(
|
|
||||||
backButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupLanguageOption() {
|
|
||||||
final Text languageText = get("language-text");
|
|
||||||
languageText.setText(AppContext.getString("language"));
|
|
||||||
|
|
||||||
final ComboBox<Locale> languageCombobox = get("language-combobox");
|
|
||||||
languageCombobox.getItems().addAll(AppContext.getLocalization().getAvailableLocales());
|
|
||||||
languageCombobox.setValue(AppContext.getLocale());
|
|
||||||
|
|
||||||
languageCombobox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
|
|
||||||
AppSettings.getSettings().setLocale(newValue.toString());
|
|
||||||
AppContext.setLocale(newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
languageCombobox.setConverter(new StringConverter<>() {
|
|
||||||
@Override
|
|
||||||
public String toString(Locale locale) {
|
|
||||||
return AppContext.getString(locale.getDisplayName().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Locale fromString(String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMasterVolumeOption() {
|
|
||||||
final Text masterVolumeText = get("master-volume-text");
|
|
||||||
masterVolumeText.setText(AppContext.getString("master-volume"));
|
|
||||||
|
|
||||||
final Slider masterVolumeSlider = get("master-volume-slider");
|
|
||||||
masterVolumeSlider.setMin(0);
|
|
||||||
masterVolumeSlider.setMax(100);
|
|
||||||
masterVolumeSlider.setValue(AppSettings.getSettings().getVolume());
|
|
||||||
|
|
||||||
masterVolumeSlider.valueProperty().addListener((_, _, newValue) -> {
|
|
||||||
AppSettings.getSettings().setVolume(newValue.intValue());
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newValue.doubleValue(), VolumeControl.MASTERVOLUME)).asyncPostEvent();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupEffectsVolumeOption() {
|
|
||||||
final Text effectsVolumeText = get("effects-volume-text");
|
|
||||||
effectsVolumeText.setText(AppContext.getString("effects-volume"));
|
|
||||||
|
|
||||||
final Slider effectsVolumeSlider = get("effects-volume-slider");
|
|
||||||
effectsVolumeSlider.setMin(0);
|
|
||||||
effectsVolumeSlider.setMax(100);
|
|
||||||
effectsVolumeSlider.setValue(AppSettings.getSettings().getFxVolume());
|
|
||||||
|
|
||||||
effectsVolumeSlider.valueProperty().addListener((_, _, newValue) -> {
|
|
||||||
AppSettings.getSettings().setFxVolume(newValue.intValue());
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newValue.doubleValue(), VolumeControl.FX)).asyncPostEvent();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMusicVolumeOption() {
|
|
||||||
final Text musicVolumeText = get("music-volume-text");
|
|
||||||
musicVolumeText.setText(AppContext.getString("music-volume"));
|
|
||||||
|
|
||||||
final Slider musicVolumeSlider = get("music-volume-slider");
|
|
||||||
musicVolumeSlider.setMin(0);
|
|
||||||
musicVolumeSlider.setMax(100);
|
|
||||||
musicVolumeSlider.setValue(AppSettings.getSettings().getMusicVolume());
|
|
||||||
|
|
||||||
musicVolumeSlider.valueProperty().addListener((_, _, newValue) -> {
|
|
||||||
AppSettings.getSettings().setMusicVolume(newValue.intValue());
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newValue.doubleValue(), VolumeControl.MUSIC)).asyncPostEvent();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupThemeOption() {
|
|
||||||
final Text themeText = get("theme-text");
|
|
||||||
themeText.setText(AppContext.getString("theme"));
|
|
||||||
|
|
||||||
final ComboBox<String> themeCombobox = get("theme-combobox");
|
|
||||||
themeCombobox.getItems().addAll("dark", "light", "high-contrast");
|
|
||||||
themeCombobox.setValue(AppSettings.getSettings().getTheme());
|
|
||||||
|
|
||||||
themeCombobox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
|
|
||||||
AppSettings.getSettings().setTheme(newValue);
|
|
||||||
App.setStyle(newValue, AppSettings.getSettings().getLayoutSize());
|
|
||||||
});
|
|
||||||
|
|
||||||
themeCombobox.setConverter(new StringConverter<>() {
|
|
||||||
@Override
|
|
||||||
public String toString(String theme) {
|
|
||||||
return AppContext.getString(theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String fromString(String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupLayoutOption() {
|
|
||||||
final Text layoutText = get("layout-text");
|
|
||||||
layoutText.setText(AppContext.getString("layout-size"));
|
|
||||||
|
|
||||||
final ComboBox<String> layoutCombobox = get("layout-combobox");
|
|
||||||
layoutCombobox.getItems().addAll("small", "medium", "large");
|
|
||||||
layoutCombobox.setValue(AppSettings.getSettings().getLayoutSize());
|
|
||||||
|
|
||||||
layoutCombobox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
|
|
||||||
AppSettings.getSettings().setLayoutSize(newValue);
|
|
||||||
App.setStyle(AppSettings.getSettings().getTheme(), newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
layoutCombobox.setConverter(new StringConverter<>() {
|
|
||||||
@Override
|
|
||||||
public String toString(String layout) {
|
|
||||||
return AppContext.getString(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String fromString(String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupFullscreenOption() {
|
|
||||||
final Button fullscreenButton = get("fullscreen-button");
|
|
||||||
|
|
||||||
if (AppSettings.getSettings().getFullscreen()) {
|
|
||||||
fullscreenButton.setText(AppContext.getString("windowed"));
|
|
||||||
fullscreenButton.setOnAction(_ -> {
|
|
||||||
AppSettings.getSettings().setFullscreen(false);
|
|
||||||
App.setFullscreen(false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
fullscreenButton.setText(AppContext.getString("fullscreen"));
|
|
||||||
fullscreenButton.setOnAction(_ -> {
|
|
||||||
AppSettings.getSettings().setFullscreen(true);
|
|
||||||
App.setFullscreen(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.App;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
public final class QuitView extends View {
|
|
||||||
public QuitView() {
|
|
||||||
super(false, "bg-popup");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text sureHeader = header();
|
|
||||||
sureHeader.setText(AppContext.getString("are-you-sure"));
|
|
||||||
|
|
||||||
final Button yesButton = button();
|
|
||||||
yesButton.setText(AppContext.getString("yes"));
|
|
||||||
yesButton.setOnAction(_ -> { App.quit(); });
|
|
||||||
|
|
||||||
final Button noButton = button();
|
|
||||||
noButton.setText(AppContext.getString("no"));
|
|
||||||
noButton.setOnAction(_ -> { App.stopQuit(); });
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(vbox(
|
|
||||||
sureHeader,
|
|
||||||
|
|
||||||
hbox(
|
|
||||||
yesButton,
|
|
||||||
noButton
|
|
||||||
)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.GameInformation;
|
|
||||||
import org.toop.app.Server;
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
import javafx.scene.control.Slider;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
public final class SendChallengeView extends View {
|
|
||||||
private final Server server;
|
|
||||||
private final String opponent;
|
|
||||||
private final BiConsumer<GameInformation.Player, String> onSend;
|
|
||||||
|
|
||||||
private final GameInformation.Player playerInformation;
|
|
||||||
|
|
||||||
public SendChallengeView(Server server, String opponent, BiConsumer<GameInformation.Player, String> onSend) {
|
|
||||||
super(false, "bg-popup");
|
|
||||||
|
|
||||||
this.server = server;
|
|
||||||
this.opponent = opponent;
|
|
||||||
this.onSend = onSend;
|
|
||||||
|
|
||||||
playerInformation = new GameInformation.Player();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text challengeText = text();
|
|
||||||
challengeText.setText(AppContext.getString("challenge"));
|
|
||||||
|
|
||||||
final Text opponentHeader = header();
|
|
||||||
opponentHeader.setText(opponent);
|
|
||||||
|
|
||||||
final Text gameText = text();
|
|
||||||
gameText.setText(AppContext.getString("to-a-game-of"));
|
|
||||||
|
|
||||||
final ComboBox<String> gamesCombobox = combobox();
|
|
||||||
gamesCombobox.getItems().addAll(server.getGameList());
|
|
||||||
gamesCombobox.setValue(gamesCombobox.getItems().getFirst());
|
|
||||||
|
|
||||||
final Button sendButton = button();
|
|
||||||
sendButton.setText(AppContext.getString("send"));
|
|
||||||
sendButton.setOnAction(_ -> { onSend.accept(playerInformation, gamesCombobox.getValue()); });
|
|
||||||
|
|
||||||
final Button cancelButton = button();
|
|
||||||
cancelButton.setText(AppContext.getString("cancel"));
|
|
||||||
cancelButton.setOnAction(_ -> {
|
|
||||||
ViewStack.pop(); });
|
|
||||||
|
|
||||||
final List<Node> nodes = new ArrayList<>();
|
|
||||||
|
|
||||||
if (playerInformation.isHuman) {
|
|
||||||
final Button playerToggle = button();
|
|
||||||
playerToggle.setText(AppContext.getString("player"));
|
|
||||||
playerToggle.setOnAction(_ -> {
|
|
||||||
playerInformation.isHuman = false;
|
|
||||||
cleanup();
|
|
||||||
setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vbox(playerToggle));
|
|
||||||
} else {
|
|
||||||
final Button computerToggle = button();
|
|
||||||
computerToggle.setText(AppContext.getString("computer"));
|
|
||||||
computerToggle.setOnAction(_ -> {
|
|
||||||
playerInformation.isHuman = true;
|
|
||||||
cleanup();
|
|
||||||
setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vbox(computerToggle));
|
|
||||||
|
|
||||||
final Text computerDifficultyText = text();
|
|
||||||
computerDifficultyText.setText(AppContext.getString("computer-difficulty"));
|
|
||||||
|
|
||||||
final Slider computerDifficultySlider = slider();
|
|
||||||
computerDifficultySlider.setMin(0);
|
|
||||||
computerDifficultySlider.setMax(Server.gameToType(gamesCombobox.getValue()).getMaxDepth());
|
|
||||||
computerDifficultySlider.setValue(playerInformation.computerDifficulty);
|
|
||||||
computerDifficultySlider.valueProperty().addListener((_, _, newValue) -> {
|
|
||||||
playerInformation.computerDifficulty = newValue.intValue();
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.add(vbox(computerDifficultyText, computerDifficultySlider));
|
|
||||||
}
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(hboxFill(
|
|
||||||
vboxFill(
|
|
||||||
challengeText,
|
|
||||||
opponentHeader,
|
|
||||||
gameText,
|
|
||||||
gamesCombobox,
|
|
||||||
separator(),
|
|
||||||
|
|
||||||
hboxFill(
|
|
||||||
sendButton,
|
|
||||||
cancelButton
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
vboxFill(
|
|
||||||
nodes.toArray(new Node[0])
|
|
||||||
)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package org.toop.app.view.views;
|
|
||||||
|
|
||||||
import org.toop.app.view.View;
|
|
||||||
import org.toop.app.view.ViewStack;
|
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
|
||||||
import org.toop.local.AppContext;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ListView;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public final class ServerView extends View {
|
|
||||||
private final String user;
|
|
||||||
private final Consumer<String> onPlayerClicked;
|
|
||||||
private final Runnable onDisconnect;
|
|
||||||
|
|
||||||
private ListView<Button> listView;
|
|
||||||
|
|
||||||
public ServerView(String user, Consumer<String> onPlayerClicked, Runnable onDisconnect) {
|
|
||||||
super(true, "bg-primary");
|
|
||||||
|
|
||||||
this.user = user;
|
|
||||||
this.onPlayerClicked = onPlayerClicked;
|
|
||||||
this.onDisconnect = onDisconnect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(List<String> players) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
listView.getItems().clear();
|
|
||||||
|
|
||||||
for (int i = 0; i < players.size(); i++) {
|
|
||||||
final int finalI = i;
|
|
||||||
|
|
||||||
final Button button = button();
|
|
||||||
button.setText(players.get(i));
|
|
||||||
button.setOnAction(_ -> {
|
|
||||||
onPlayerClicked.accept(players.get(finalI));
|
|
||||||
});
|
|
||||||
|
|
||||||
listView.getItems().add(button);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
final Text playerHeader = header();
|
|
||||||
playerHeader.setText(user);
|
|
||||||
|
|
||||||
listView = new ListView<Button>();
|
|
||||||
|
|
||||||
final SongDisplay songdisplay = new SongDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_RIGHT,
|
|
||||||
fit(vboxFill(
|
|
||||||
songdisplay
|
|
||||||
)));
|
|
||||||
|
|
||||||
add(Pos.CENTER,
|
|
||||||
fit(vboxFill(
|
|
||||||
vbox(
|
|
||||||
playerHeader,
|
|
||||||
separator()
|
|
||||||
),
|
|
||||||
|
|
||||||
listView
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
final Button disconnectButton = button();
|
|
||||||
disconnectButton.setText(AppContext.getString("disconnect"));
|
|
||||||
disconnectButton.setOnAction(_ -> {
|
|
||||||
onDisconnect.run();
|
|
||||||
ViewStack.push(new OnlineView());
|
|
||||||
});
|
|
||||||
|
|
||||||
add(Pos.BOTTOM_LEFT,
|
|
||||||
vboxFill(
|
|
||||||
disconnectButton
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -47,8 +47,7 @@ public final class Primitive {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageView image(File file) {
|
public static ImageView image(ImageAsset imageAsset) {
|
||||||
ImageAsset imageAsset = new ImageAsset(file);
|
|
||||||
ImageView imageView = new ImageView(imageAsset.getImage());
|
ImageView imageView = new ImageView(imageAsset.getImage());
|
||||||
imageView.getStyleClass().add("image");
|
imageView.getStyleClass().add("image");
|
||||||
imageView.setPreserveRatio(true);
|
imageView.setPreserveRatio(true);
|
||||||
|
|||||||
5
app/src/main/java/org/toop/app/widget/Updatable.java
Normal file
5
app/src/main/java/org/toop/app/widget/Updatable.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package org.toop.app.widget;
|
||||||
|
|
||||||
|
public interface Updatable {
|
||||||
|
void update();
|
||||||
|
}
|
||||||
@@ -1,7 +1,21 @@
|
|||||||
package org.toop.app.widget.complex;
|
package org.toop.app.widget.complex;
|
||||||
|
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
|
||||||
public abstract class PopupWidget extends StackWidget {
|
public abstract class PopupWidget extends StackWidget {
|
||||||
|
private final Button popButton;
|
||||||
|
|
||||||
public PopupWidget() {
|
public PopupWidget() {
|
||||||
super("bg-popup");
|
super("bg-popup");
|
||||||
|
|
||||||
|
popButton = new Button("X");
|
||||||
|
popButton.setOnAction(_ -> hide());
|
||||||
|
|
||||||
|
add(Pos.TOP_RIGHT, popButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setOnPop(Runnable onPop) {
|
||||||
|
popButton.setOnAction(_ -> onPop.run());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package org.toop.app.widget.display;
|
package org.toop.app.widget.display;
|
||||||
|
|
||||||
|
import javafx.animation.KeyFrame;
|
||||||
|
import javafx.animation.Timeline;
|
||||||
|
import javafx.util.Duration;
|
||||||
import org.toop.app.widget.Widget;
|
import org.toop.app.widget.Widget;
|
||||||
import org.toop.framework.audio.events.AudioEvents;
|
import org.toop.framework.audio.events.AudioEvents;
|
||||||
import org.toop.framework.eventbus.EventFlow;
|
import org.toop.framework.eventbus.EventFlow;
|
||||||
@@ -15,10 +18,13 @@ import javafx.scene.layout.Region;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
|
|
||||||
|
import java.util.Timer;
|
||||||
|
|
||||||
public class SongDisplay extends VBox implements Widget {
|
public class SongDisplay extends VBox implements Widget {
|
||||||
private final Text songTitle;
|
private final Text songTitle;
|
||||||
private final ProgressBar progressBar;
|
private final ProgressBar progressBar;
|
||||||
private final Text progressText;
|
private final Text progressText;
|
||||||
|
private boolean canClick = true;
|
||||||
|
|
||||||
public SongDisplay() {
|
public SongDisplay() {
|
||||||
new EventFlow()
|
new EventFlow()
|
||||||
@@ -49,10 +55,13 @@ public class SongDisplay extends VBox implements Widget {
|
|||||||
previousButton.getStyleClass().setAll("previous-button");
|
previousButton.getStyleClass().setAll("previous-button");
|
||||||
|
|
||||||
skipButton.setOnAction( event -> {
|
skipButton.setOnAction( event -> {
|
||||||
|
if (!canClick) { return; }
|
||||||
GlobalEventBus.post(new AudioEvents.SkipMusic());
|
GlobalEventBus.post(new AudioEvents.SkipMusic());
|
||||||
|
doCooldown();
|
||||||
});
|
});
|
||||||
|
|
||||||
pauseButton.setOnAction(event -> {
|
pauseButton.setOnAction(event -> {
|
||||||
|
if (!canClick) { return; }
|
||||||
GlobalEventBus.post(new AudioEvents.PauseMusic());
|
GlobalEventBus.post(new AudioEvents.PauseMusic());
|
||||||
if (pauseButton.getText().equals("⏸")) {
|
if (pauseButton.getText().equals("⏸")) {
|
||||||
pauseButton.setText("▶");
|
pauseButton.setText("▶");
|
||||||
@@ -60,10 +69,13 @@ public class SongDisplay extends VBox implements Widget {
|
|||||||
else if (pauseButton.getText().equals("▶")) {
|
else if (pauseButton.getText().equals("▶")) {
|
||||||
pauseButton.setText("⏸");
|
pauseButton.setText("⏸");
|
||||||
}
|
}
|
||||||
|
doCooldown();
|
||||||
});
|
});
|
||||||
|
|
||||||
previousButton.setOnAction( event -> {
|
previousButton.setOnAction( event -> {
|
||||||
|
if (!canClick) { return; }
|
||||||
GlobalEventBus.post(new AudioEvents.PreviousMusic());
|
GlobalEventBus.post(new AudioEvents.PreviousMusic());
|
||||||
|
doCooldown();
|
||||||
});
|
});
|
||||||
|
|
||||||
HBox control = new HBox(10, previousButton, pauseButton, skipButton);
|
HBox control = new HBox(10, previousButton, pauseButton, skipButton);
|
||||||
@@ -110,6 +122,16 @@ public class SongDisplay extends VBox implements Widget {
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doCooldown() {
|
||||||
|
canClick = false;
|
||||||
|
Timeline cooldown = new Timeline(
|
||||||
|
new KeyFrame(Duration.millis(300), event -> canClick = true)
|
||||||
|
);
|
||||||
|
cooldown.setCycleCount(1);
|
||||||
|
cooldown.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node getNode() {
|
public Node getNode() {
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -20,5 +20,10 @@ public class QuitPopup extends PopupWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
add(Pos.CENTER, confirmWidget);
|
add(Pos.CENTER, confirmWidget);
|
||||||
|
|
||||||
|
setOnPop(() -> {
|
||||||
|
App.stopQuit();
|
||||||
|
hide();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,60 +1,116 @@
|
|||||||
package org.toop.app.widget.tutorial;
|
package org.toop.app.widget.tutorial;
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
|
import org.apache.maven.surefire.shared.lang3.tuple.ImmutablePair;
|
||||||
import org.toop.app.widget.Primitive;
|
import org.toop.app.widget.Primitive;
|
||||||
import org.toop.app.widget.complex.ViewWidget;
|
import org.toop.app.widget.Updatable;
|
||||||
|
import org.toop.app.widget.WidgetContainer;
|
||||||
|
import org.toop.app.widget.complex.PopupWidget;
|
||||||
|
|
||||||
import javafx.scene.control.Button;
|
import org.toop.framework.resource.resources.ImageAsset;
|
||||||
import org.toop.local.AppContext;
|
import org.toop.local.AppContext;
|
||||||
|
|
||||||
import java.io.File;
|
import java.util.List;
|
||||||
|
|
||||||
public class BaseTutorialWidget extends ViewWidget {
|
/**
|
||||||
|
* A widget base for all the tutorial widgets.
|
||||||
|
*
|
||||||
|
* <p>Usage example:
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
* public class Connect4TutorialWidget extends BaseTutorialWidget {
|
||||||
|
* public Connect4TutorialWidget(Runnable nextScreen) {
|
||||||
|
* super(List.of(
|
||||||
|
* new ImmutablePair<>("connect4.1", ResourceManager.get("connect41.png")),
|
||||||
|
* new ImmutablePair<>("connect4.2", ResourceManager.get("connect42.png"))
|
||||||
|
* ), nextScreen);
|
||||||
|
* }
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
public class BaseTutorialWidget extends PopupWidget implements Updatable {
|
||||||
|
|
||||||
private TState state;
|
private final Text tutorialText;
|
||||||
private Text tutorialText;
|
private final ImageView imagery;
|
||||||
private Button previousButton;
|
private final Button previousButton;
|
||||||
private Button nextButton;
|
private final Button nextButton;
|
||||||
private Button noButton;
|
private final List<ImmutablePair<String, ImageAsset>> pages;
|
||||||
private Button yesButton;
|
private final Runnable nextScreen;
|
||||||
private Button neverButton;
|
|
||||||
private ImageView imagery;
|
|
||||||
|
|
||||||
public BaseTutorialWidget(String key, Runnable onNo, Runnable onYes, Runnable onNever) {
|
private int pageIndex = 0;
|
||||||
System.out.println("Trying to initialize...");
|
|
||||||
this.tutorialText = Primitive.text(key);
|
|
||||||
this.yesButton = Primitive.button("ok", () -> onYes.run());
|
|
||||||
this.noButton = Primitive.button("no", () -> onNo.run());
|
|
||||||
this.neverButton = Primitive.button("never", () -> onNever.run());
|
|
||||||
var a = Primitive.hbox(yesButton, noButton, neverButton);
|
|
||||||
add(Pos.CENTER, Primitive.vbox(tutorialText, a));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseTutorialWidget(TState state, String key, Runnable onPrevious, Runnable onNext) {
|
public BaseTutorialWidget(List<ImmutablePair<String, ImageAsset>> pages, Runnable nextScreen) {
|
||||||
this.state = state;
|
this.tutorialText = Primitive.text(pages.getFirst().getKey());
|
||||||
this.tutorialText = Primitive.text(key);
|
this.imagery = Primitive.image(pages.getFirst().getValue());
|
||||||
this.previousButton = Primitive.button("<", () -> onPrevious.run());
|
|
||||||
this.nextButton = Primitive.button(">", () -> onNext.run());
|
this.pages = pages;
|
||||||
var w = Primitive.hbox(previousButton, nextButton);
|
this.nextScreen = nextScreen;
|
||||||
add(Pos.CENTER, Primitive.vbox(tutorialText, w));
|
|
||||||
}
|
previousButton = Primitive.button("goback", () -> { update(false); this.hide(); });
|
||||||
|
nextButton = Primitive.button(">", () -> update(true));
|
||||||
|
|
||||||
|
var w = Primitive.hbox(
|
||||||
|
previousButton,
|
||||||
|
nextButton
|
||||||
|
);
|
||||||
|
|
||||||
|
var x = Primitive.vbox(imagery, tutorialText);
|
||||||
|
|
||||||
public BaseTutorialWidget(TState state, String key, File image, Runnable onPrevious, Runnable onNext) {
|
|
||||||
this.state = state;
|
|
||||||
this.imagery = Primitive.image(image);
|
|
||||||
this.tutorialText = Primitive.text(key);
|
|
||||||
this.previousButton = Primitive.button("<", () -> onPrevious.run());
|
|
||||||
this.nextButton = Primitive.button(">", () -> onNext.run());
|
|
||||||
var w = Primitive.hbox(previousButton, nextButton);
|
|
||||||
var x = Primitive.vbox(imagery, tutorialText);
|
|
||||||
add(Pos.CENTER, Primitive.vbox(x, w));
|
add(Pos.CENTER, Primitive.vbox(x, w));
|
||||||
|
|
||||||
|
WidgetContainer.add(Pos.CENTER, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(String key, File image) {
|
@Override
|
||||||
|
public void update() {
|
||||||
|
update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Refactor if statements to make code easier to read.
|
||||||
|
public void update(boolean next) {
|
||||||
|
pageIndex = next ? pageIndex + 1 : pageIndex - 1;
|
||||||
|
|
||||||
|
if (pageIndex >= pages.size()) {
|
||||||
|
pageIndex--;
|
||||||
|
return;
|
||||||
|
} else if (pageIndex < 0) {
|
||||||
|
pageIndex++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageIndex == pages.size()-1) {
|
||||||
|
nextButton.textProperty().unbind();
|
||||||
|
nextButton.setText(AppContext.getString("startgame"));
|
||||||
|
nextButton.setOnAction((_) -> {
|
||||||
|
this.hide();
|
||||||
|
nextScreen.run();
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nextButton.textProperty().unbind();
|
||||||
|
nextButton.setText(AppContext.getString(">"));
|
||||||
|
nextButton.setOnAction((_) -> this.update(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageIndex == 0) {
|
||||||
|
previousButton.textProperty().unbind();
|
||||||
|
previousButton.setText(AppContext.getString("goback"));
|
||||||
|
previousButton.setOnAction((_) -> this.hide());
|
||||||
|
} else {
|
||||||
|
previousButton.textProperty().unbind();
|
||||||
|
previousButton.setText(AppContext.getString("<"));
|
||||||
|
previousButton.setOnAction((_) -> this.update(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentPage = pages.get(pageIndex);
|
||||||
|
|
||||||
|
var text = currentPage.getKey();
|
||||||
|
var image = currentPage.getValue();
|
||||||
|
|
||||||
tutorialText.textProperty().unbind();
|
tutorialText.textProperty().unbind();
|
||||||
tutorialText.setText(AppContext.getString(key));
|
tutorialText.setText(AppContext.getString(text));
|
||||||
imagery.setImage(Primitive.image(image).getImage());
|
imagery.setImage(Primitive.image(image).getImage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,15 @@
|
|||||||
package org.toop.app.widget.tutorial;
|
package org.toop.app.widget.tutorial;
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
import org.apache.maven.surefire.shared.lang3.tuple.ImmutablePair;
|
||||||
import org.toop.app.widget.complex.ViewWidget;
|
import org.toop.framework.resource.ResourceManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.util.List;
|
||||||
|
|
||||||
public class Connect4TutorialWidget extends ViewWidget {
|
public class Connect4TutorialWidget extends BaseTutorialWidget {
|
||||||
private TState state;
|
public Connect4TutorialWidget(Runnable nextScreen) {
|
||||||
private String[] keys = {"connect4.1", "connect4.2"};
|
super(List.of(
|
||||||
private File[] images = {new File("app/src/main/resources/assets/images/connect41.png"), new File("app/src/main/resources/assets/images/connect42.png")};
|
new ImmutablePair<>("connect4.1", ResourceManager.get("connect41.png")),
|
||||||
private BaseTutorialWidget tutorialWidget;
|
new ImmutablePair<>("connect4.2", ResourceManager.get("connect42.png"))
|
||||||
|
), nextScreen);
|
||||||
public Connect4TutorialWidget() {
|
|
||||||
this.state = new TState(keys.length);
|
|
||||||
tutorialWidget = new BaseTutorialWidget(
|
|
||||||
state,
|
|
||||||
keys[state.getCurrent()],
|
|
||||||
images[state.getCurrent()],
|
|
||||||
() -> {
|
|
||||||
if (state.hasPrevious()) {
|
|
||||||
state.previous();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
if (state.hasNext()) {
|
|
||||||
state.next();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
add(Pos.CENTER, tutorialWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update() {
|
|
||||||
tutorialWidget.update(keys[state.getCurrent()], images[state.getCurrent()]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,17 @@
|
|||||||
package org.toop.app.widget.tutorial;
|
package org.toop.app.widget.tutorial;
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
import org.apache.maven.surefire.shared.lang3.tuple.ImmutablePair;
|
||||||
import org.toop.app.widget.complex.ViewWidget;
|
import org.toop.framework.resource.ResourceManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.util.List;
|
||||||
|
|
||||||
public class ReversiTutorialWidget extends ViewWidget {
|
public class ReversiTutorialWidget extends BaseTutorialWidget {
|
||||||
private TState state;
|
public ReversiTutorialWidget(Runnable nextScreen) {
|
||||||
private String[] keys = {"reversi1", "reversi2", "reversi3", "reversi4"};
|
super(List.of(
|
||||||
private File[] images = {new File("app/src/main/resources/assets/images/reversi1.png"), new File("app/src/main/resources/assets/images/reversi2.png"), new File("app/src/main/resources/assets/images/cat.jpg"), new File("app/src/main/resources/assets/images/cat.jpg")};
|
new ImmutablePair<>("reversi1", ResourceManager.get("reversi1.png")),
|
||||||
private BaseTutorialWidget tutorialWidget;
|
new ImmutablePair<>("reversi2", ResourceManager.get("reversi2.png")),
|
||||||
|
new ImmutablePair<>("reversi3", ResourceManager.get("cat.jpg")),
|
||||||
public ReversiTutorialWidget() {
|
new ImmutablePair<>("reversi4", ResourceManager.get("cat.jpg"))
|
||||||
this.state = new TState(keys.length);
|
), nextScreen);
|
||||||
tutorialWidget = new BaseTutorialWidget(
|
|
||||||
state,
|
|
||||||
keys[state.getCurrent()],
|
|
||||||
images[state.getCurrent()],
|
|
||||||
() -> {
|
|
||||||
if (state.hasPrevious()) {
|
|
||||||
state.previous();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
if (state.hasNext()) {
|
|
||||||
state.next();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
add(Pos.CENTER, tutorialWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update() {
|
|
||||||
tutorialWidget.update(keys[state.getCurrent()], images[state.getCurrent()]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.toop.app.widget.tutorial;
|
||||||
|
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import org.toop.app.widget.Primitive;
|
||||||
|
import org.toop.app.widget.WidgetContainer;
|
||||||
|
import org.toop.app.widget.complex.PopupWidget;
|
||||||
|
import org.toop.local.AppSettings;
|
||||||
|
|
||||||
|
public class ShowEnableTutorialWidget extends PopupWidget {
|
||||||
|
|
||||||
|
public ShowEnableTutorialWidget(Runnable tutorial, Runnable nextScreen, Runnable appSettingsSetter) {
|
||||||
|
var a = Primitive.hbox(
|
||||||
|
Primitive.button("ok", () -> { appSettingsSetter.run(); tutorial.run(); this.hide(); }),
|
||||||
|
Primitive.button("no", () -> { appSettingsSetter.run(); nextScreen.run(); this.hide(); }),
|
||||||
|
Primitive.button("never", () -> { AppSettings.getSettings().setTutorialFlag(false); nextScreen.run(); this.hide(); })
|
||||||
|
);
|
||||||
|
|
||||||
|
var txt = Primitive.text("tutorial");
|
||||||
|
add(Pos.CENTER, Primitive.vbox(txt, a));
|
||||||
|
WidgetContainer.add(Pos.CENTER, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package org.toop.app.widget.tutorial;
|
|
||||||
|
|
||||||
public class TState {
|
|
||||||
|
|
||||||
private int current;
|
|
||||||
private int total;
|
|
||||||
|
|
||||||
public TState(int total) {
|
|
||||||
this.total = total;
|
|
||||||
this.current = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrent() {
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrent(int current) {
|
|
||||||
this.current = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotal() {
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTotal(int total) {
|
|
||||||
this.total = total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void next() {
|
|
||||||
current = current + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void previous() {
|
|
||||||
current = current - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
|
||||||
return current < total - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasPrevious() {
|
|
||||||
return current > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +1,16 @@
|
|||||||
package org.toop.app.widget.tutorial;
|
package org.toop.app.widget.tutorial;
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
import org.apache.maven.surefire.shared.lang3.tuple.ImmutablePair;
|
||||||
import org.toop.app.widget.complex.ViewWidget;
|
import org.toop.framework.resource.ResourceManager;
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class TicTacToeTutorialWidget extends ViewWidget {
|
import java.util.List;
|
||||||
|
|
||||||
private TState state;
|
public class TicTacToeTutorialWidget extends BaseTutorialWidget {
|
||||||
private String[] keys = {"tictactoe1", "tictactoe2"};
|
public TicTacToeTutorialWidget(Runnable nextScreen) {
|
||||||
private File[] images = {
|
super(List.of(
|
||||||
new File("app/src/main/resources/assets/images/tictactoe1.png"),
|
new ImmutablePair<>("tictactoe1", ResourceManager.get("tictactoe1.png")),
|
||||||
new File("app/src/main/resources/assets/images/tictactoe2.png")
|
new ImmutablePair<>("tictactoe2", ResourceManager.get("tictactoe2.png"))
|
||||||
};
|
), nextScreen);
|
||||||
private BaseTutorialWidget tutorialWidget;
|
|
||||||
|
|
||||||
public TicTacToeTutorialWidget() {
|
|
||||||
this.state = new TState(keys.length);
|
|
||||||
tutorialWidget = new BaseTutorialWidget(
|
|
||||||
state,
|
|
||||||
keys[state.getCurrent()],
|
|
||||||
images[state.getCurrent()],
|
|
||||||
() -> {
|
|
||||||
if (state.hasPrevious()) {
|
|
||||||
state.previous();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
if (state.hasNext()) {
|
|
||||||
state.next();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
add(Pos.CENTER, tutorialWidget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update() {
|
|
||||||
tutorialWidget.update(keys[state.getCurrent()], images[state.getCurrent()]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,23 +53,13 @@ public final class GameView extends ViewWidget {
|
|||||||
|
|
||||||
switch(gameType) {
|
switch(gameType) {
|
||||||
case "TicTacToe":
|
case "TicTacToe":
|
||||||
this.tutorialButton = Primitive.button("tutorialstring", () -> {
|
this.tutorialButton = Primitive.button("tutorialstring", () -> new TicTacToeTutorialWidget(() -> {})); break;
|
||||||
transitionNext(new TicTacToeTutorialWidget());
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "Reversi":
|
case "Reversi":
|
||||||
this.tutorialButton = Primitive.button("tutorialstring", () -> {
|
this.tutorialButton = Primitive.button("tutorialstring", () -> new ReversiTutorialWidget(() -> {})); break;
|
||||||
transitionNext(new ReversiTutorialWidget());
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "Connect4":
|
case "Connect4":
|
||||||
this.tutorialButton = Primitive.button("tutorialstring", () -> {
|
this.tutorialButton = Primitive.button("tutorialstring", () -> new Connect4TutorialWidget(() -> {})); break;
|
||||||
transitionNext(new Connect4TutorialWidget());
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
this.tutorialButton = null;
|
this.tutorialButton = null; break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupLayout();
|
setupLayout();
|
||||||
|
|||||||
@@ -10,10 +10,7 @@ import org.toop.app.widget.WidgetContainer;
|
|||||||
import org.toop.app.widget.complex.PlayerInfoWidget;
|
import org.toop.app.widget.complex.PlayerInfoWidget;
|
||||||
import org.toop.app.widget.complex.ViewWidget;
|
import org.toop.app.widget.complex.ViewWidget;
|
||||||
import org.toop.app.widget.popup.ErrorPopup;
|
import org.toop.app.widget.popup.ErrorPopup;
|
||||||
import org.toop.app.widget.tutorial.BaseTutorialWidget;
|
import org.toop.app.widget.tutorial.*;
|
||||||
import org.toop.app.widget.tutorial.Connect4TutorialWidget;
|
|
||||||
import org.toop.app.widget.tutorial.ReversiTutorialWidget;
|
|
||||||
import org.toop.app.widget.tutorial.TicTacToeTutorialWidget;
|
|
||||||
import org.toop.local.AppContext;
|
import org.toop.local.AppContext;
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
@@ -40,91 +37,40 @@ public class LocalMultiplayerView extends ViewWidget {
|
|||||||
switch (information.type) {
|
switch (information.type) {
|
||||||
case TICTACTOE:
|
case TICTACTOE:
|
||||||
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstTTT()) {
|
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstTTT()) {
|
||||||
BaseTutorialWidget a = new BaseTutorialWidget(
|
new ShowEnableTutorialWidget(
|
||||||
"tutorial",
|
() -> new TicTacToeTutorialWidget(() -> new TicTacToeGameThread(information)),
|
||||||
() -> {
|
() -> Platform.runLater(() -> new TicTacToeGameThread(information)),
|
||||||
AppSettings.getSettings().setFirstTTT(false);
|
() -> AppSettings.getSettings().setFirstTTT(false)
|
||||||
Platform.runLater(() -> {
|
);
|
||||||
new TicTacToeGameThread(information);
|
} else {
|
||||||
});
|
new TicTacToeGameThread(information);
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
ViewWidget c = new TicTacToeTutorialWidget();
|
|
||||||
transitionNext(c);
|
|
||||||
WidgetContainer.setCurrentView(c);
|
|
||||||
AppSettings.getSettings().setFirstTTT(false);
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
AppSettings.getSettings().setTutorialFlag(false);
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
new TicTacToeGameThread(information);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
transitionNext(a);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
new TicTacToeGameThread(information);
|
|
||||||
break;
|
break;
|
||||||
case REVERSI:
|
case REVERSI:
|
||||||
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) {
|
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) {
|
||||||
BaseTutorialWidget a = new BaseTutorialWidget(
|
new ShowEnableTutorialWidget(
|
||||||
"tutorial",
|
() -> new ReversiTutorialWidget(() -> new ReversiGame(information)),
|
||||||
() -> { Platform.runLater(() -> {
|
() -> Platform.runLater(() -> new ReversiGame(information)),
|
||||||
AppSettings.getSettings().setFirstReversi(false);
|
() -> AppSettings.getSettings().setFirstReversi(false)
|
||||||
new ReversiGame(information);
|
);
|
||||||
});
|
} else {
|
||||||
},
|
new ReversiGame(information);
|
||||||
() -> {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
ViewWidget c = new ReversiTutorialWidget();
|
|
||||||
transitionNext(c);
|
|
||||||
WidgetContainer.setCurrentView(c);
|
|
||||||
AppSettings.getSettings().setFirstReversi(false);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
AppSettings.getSettings().setTutorialFlag(false);
|
|
||||||
new ReversiGame(information);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
transitionNext(a);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
new ReversiGame(information);
|
|
||||||
break;
|
break;
|
||||||
case CONNECT4:
|
case CONNECT4:
|
||||||
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstConnect4()) {
|
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstConnect4()) {
|
||||||
BaseTutorialWidget a = new BaseTutorialWidget(
|
new ShowEnableTutorialWidget(
|
||||||
"tutorial",
|
() -> new Connect4TutorialWidget(() -> new Connect4Game(information)),
|
||||||
() -> { Platform.runLater(() -> {
|
() -> Platform.runLater(() -> new Connect4Game(information)),
|
||||||
AppSettings.getSettings().setFirstConnect4(false);
|
() -> AppSettings.getSettings().setFirstConnect4(false)
|
||||||
new Connect4Game(information);
|
);
|
||||||
});
|
} else {
|
||||||
},
|
new Connect4Game(information);
|
||||||
() -> {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
ViewWidget c = new Connect4TutorialWidget();
|
|
||||||
transitionNext(c);
|
|
||||||
WidgetContainer.setCurrentView(c);
|
|
||||||
AppSettings.getSettings().setFirstConnect4(false);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
AppSettings.getSettings().setTutorialFlag(false);
|
|
||||||
new Connect4Game(information);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
transitionNext(a);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
new Connect4Game(information);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// case BATTLESHIP -> new BattleshipGame(information);
|
// case BATTLESHIP -> new BattleshipGame(information);
|
||||||
});
|
});
|
||||||
|
|
||||||
var playerSection = setupPlayerSections();
|
var playerSection = setupPlayerSections();
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ reversi2=Clicking on a dot will flip all the moves between where you place the d
|
|||||||
reversi3=Your turn may be skipped if there is no legal move. This will let your opponent play again until you get an opportunity at a legal move.
|
reversi3=Your turn may be skipped if there is no legal move. This will let your opponent play again until you get an opportunity at a legal move.
|
||||||
reversi4=The player who wins at the end of the game is the one who has the most pieces on the board.
|
reversi4=The player who wins at the end of the game is the one who has the most pieces on the board.
|
||||||
tutorialstring=Tutorial
|
tutorialstring=Tutorial
|
||||||
|
startgame=Start game!
|
||||||
|
goback=Go back
|
||||||
|
|
||||||
|
|
||||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabic)
|
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabic)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import org.toop.framework.resource.types.LoadableResource;
|
|||||||
|
|
||||||
@FileExtension({"png", "jpg", "jpeg"})
|
@FileExtension({"png", "jpg", "jpeg"})
|
||||||
public class ImageAsset extends BaseResource implements LoadableResource {
|
public class ImageAsset extends BaseResource implements LoadableResource {
|
||||||
private Image image;
|
private Image image = null;
|
||||||
|
|
||||||
public ImageAsset(final File file) {
|
public ImageAsset(final File file) {
|
||||||
super(file);
|
super(file);
|
||||||
@@ -40,8 +40,7 @@ public class ImageAsset extends BaseResource implements LoadableResource {
|
|||||||
public Image getImage() {
|
public Image getImage() {
|
||||||
if (!this.isLoaded) {
|
if (!this.isLoaded) {
|
||||||
this.load();
|
this.load();
|
||||||
return image;
|
|
||||||
}
|
}
|
||||||
return null;
|
return image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user