From e7d606f08e3f76bd437d87625f2eac816cab120d Mon Sep 17 00:00:00 2001 From: ramollia <@> Date: Sat, 4 Oct 2025 19:26:30 +0200 Subject: [PATCH] add: options layer --- .../java/org/toop/app/layer/Container.java | 69 +++++++++++++------ .../toop/app/layer/layers/OptionsLayer.java | 66 +++++++++++++++--- app/src/main/resources/assets/style/app.css | 34 ++++++++- 3 files changed, 136 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/org/toop/app/layer/Container.java b/app/src/main/java/org/toop/app/layer/Container.java index afcc1bc..54592b7 100644 --- a/app/src/main/java/org/toop/app/layer/Container.java +++ b/app/src/main/java/org/toop/app/layer/Container.java @@ -7,10 +7,7 @@ import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.geometry.Orientation; import javafx.scene.Node; -import javafx.scene.control.Label; -import javafx.scene.control.Separator; -import javafx.scene.control.Slider; -import javafx.scene.control.TextField; +import javafx.scene.control.*; import javafx.scene.layout.Region; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; @@ -21,9 +18,10 @@ public abstract class Container { public abstract Region getContainer(); public abstract void addNode(Node node); + public abstract void addContainer(Container container, boolean fill); - public void addText(String cssClass, String x, boolean wrap) { + public Text addText(String cssClass, String x, boolean wrap) { final Text element = new Text(x); element.getStyleClass().add(cssClass); @@ -32,13 +30,15 @@ public abstract class Container { } else { addNode(element); } + + return element; } - public void addText(String x, boolean wrap) { - addText("text", x, wrap); + public Text addText(String x, boolean wrap) { + return addText("text", x, wrap); } - public void addButton(String cssClass, String x, Runnable runnable) { + public Label addButton(String cssClass, String x, Runnable runnable) { final Label element = new Label(x); element.getStyleClass().add(cssClass); @@ -51,13 +51,14 @@ public abstract class Container { }); addNode(element); + return element; } - public void addButton(String x, Runnable runnable) { - addButton("button", x, runnable); + public Label addButton(String x, Runnable runnable) { + return addButton("button", x, runnable); } - public void addToggle(String cssClass, String x1, String x2, boolean toggled, Consumer consumer) { + public Label addToggle(String cssClass, String x1, String x2, boolean toggled, Consumer consumer) { final Label element = new Label(toggled ? x2 : x1); element.getStyleClass().add(cssClass); @@ -80,13 +81,14 @@ public abstract class Container { }); addNode(element); + return element; } - public void addToggle(String x1, String x2, boolean toggled, Consumer consumer) { - addToggle("toggle", x1, x2, toggled, consumer); + public Label addToggle(String x1, String x2, boolean toggled, Consumer consumer) { + return addToggle("toggle", x1, x2, toggled, consumer); } - public void addSlider(String cssClass, int max, int initial, Consumer consumer) { + public Slider addSlider(String cssClass, int max, int initial, Consumer consumer) { final Slider element = new Slider(0, max, initial); element.getStyleClass().add(cssClass); @@ -106,13 +108,14 @@ public abstract class Container { }); addNode(element); + return element; } - public void addSlider(int max, int initial, Consumer consumer) { - addSlider("slider", max, initial, consumer); + public Slider addSlider(int max, int initial, Consumer consumer) { + return addSlider("slider", max, initial, consumer); } - public void addInput(String cssClass, String input, Consumer consumer) { + public TextField addInput(String cssClass, String input, Consumer consumer) { final TextField element = new TextField(input); element.getStyleClass().add(cssClass); @@ -125,21 +128,43 @@ public abstract class Container { }); addNode(element); + return element; } - public void addInput(String input, Consumer consumer) { - addInput("input", input, consumer); + public TextField addInput(String input, Consumer consumer) { + return addInput("input", input, consumer); } - public void addSeparator(String cssClass, boolean horizontal) { + public ChoiceBox addChoiceBox(String cssClass, Consumer consumer) { + final ChoiceBox element = new ChoiceBox<>(); + element.getStyleClass().add(cssClass); + + element.setOnMouseEntered(_ -> { + GlobalEventBus.post(new AppEvents.OnNodeHover()); + }); + + element.valueProperty().addListener((_, _, newValue) -> { + consumer.accept(newValue); + }); + + addNode(element); + return element; + } + + public ChoiceBox addChoiceBox(Consumer consumer) { + return addChoiceBox("choicebox", consumer); + } + + public Separator addSeparator(String cssClass, boolean horizontal) { final Separator element = new Separator(horizontal ? Orientation.HORIZONTAL : Orientation.VERTICAL); element.getStyleClass().add(cssClass); element.setMinSize(50, 50); addNode(element); + return element; } - public void addSeparator(boolean horizontal) { - addSeparator("separator", horizontal); + public Separator addSeparator(boolean horizontal) { + return addSeparator("separator", horizontal); } } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/layers/OptionsLayer.java b/app/src/main/java/org/toop/app/layer/layers/OptionsLayer.java index e1c76b8..f617f66 100644 --- a/app/src/main/java/org/toop/app/layer/layers/OptionsLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/OptionsLayer.java @@ -4,10 +4,22 @@ import org.toop.app.App; import org.toop.app.layer.Container; import org.toop.app.layer.Layer; import org.toop.app.layer.containers.VerticalContainer; +import org.toop.framework.asset.ResourceManager; +import org.toop.framework.asset.resources.LocalizationAsset; +import org.toop.framework.audio.events.AudioEvents; +import org.toop.framework.eventbus.EventFlow; +import org.toop.local.AppContext; import javafx.geometry.Pos; +import javafx.scene.control.ChoiceBox; + +import java.util.Locale; public final class OptionsLayer extends Layer { + private Locale currentLocale = AppContext.getLocale(); + private LocalizationAsset locale = ResourceManager.get("localization"); + + private static int currentVolume = 25; private static boolean isWindowed = true; OptionsLayer() { @@ -19,21 +31,20 @@ public final class OptionsLayer extends Layer { public void reload() { popAll(); - final Container mainContainer = new VerticalContainer(50); - - mainContainer.addText("Options", false); - final Container optionsContainer = new VerticalContainer(5); + optionsContainer.addText("Language", false); + addLanguageBox(optionsContainer); + optionsContainer.addSeparator(true); + optionsContainer.addText("Volume", false); + addVolumeSlider(optionsContainer); + optionsContainer.addSeparator(true); + addFullscreenToggle(optionsContainer); + final Container mainContainer = new VerticalContainer(50); + mainContainer.addText("Options", false); mainContainer.addContainer(optionsContainer, true); - optionsContainer.addToggle("Windowed", "Fullscreen", !isWindowed, (fullscreen) -> { - isWindowed = !fullscreen; - App.setFullscreen(fullscreen); - }); - final Container controlContainer = new VerticalContainer(5); - controlContainer.addButton("Back", () -> { App.activate(new MainLayer()); }); @@ -41,4 +52,39 @@ public final class OptionsLayer extends Layer { addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 60); addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0); } + + private void addLanguageBox(Container container) { + final ChoiceBox languageBox = container.addChoiceBox((locale) -> { + if (locale == currentLocale) { + return; + } + + AppContext.setLocale(locale); + + this.currentLocale = AppContext.getLocale(); + this.locale = ResourceManager.get("localization"); + + App.reloadAll(); + }); + + for (final Locale localeFile : locale.getAvailableLocales()) { + languageBox.getItems().add(localeFile); + } + + languageBox.setValue(currentLocale); + } + + private void addVolumeSlider(Container container) { + container.addSlider(100, currentVolume, (volume) -> { + currentVolume = volume; + new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(volume.doubleValue() / 100.0)).asyncPostEvent(); + }); + } + + private void addFullscreenToggle(Container container) { + container.addToggle("Windowed", "Fullscreen", !isWindowed, (fullscreen) -> { + isWindowed = !fullscreen; + App.setFullscreen(fullscreen); + }); + } } \ No newline at end of file diff --git a/app/src/main/resources/assets/style/app.css b/app/src/main/resources/assets/style/app.css index 6c2c859..1e67efb 100644 --- a/app/src/main/resources/assets/style/app.css +++ b/app/src/main/resources/assets/style/app.css @@ -14,7 +14,7 @@ } .text, .button, .toggle { - -fx-padding: 10; + -fx-padding: 5 10 5 10; -fx-fill: white; -fx-text-fill: white; @@ -75,6 +75,38 @@ -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; } +.choicebox { + -fx-alignment: center; + + -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; + -fx-background-insets: 0, 2; + -fx-background-radius: 8; + + -fx-border-color: transparent; +} + +.choicebox .label { + -fx-text-fill: white; + -fx-alignment: center; + -fx-padding: 5 10 5 10; +} + +.choicebox .arrow { + -fx-background-color: transparent; +} + +.choicebox .context-menu { + -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; + -fx-background-insets: 0, 2; + -fx-background-radius: 5; +} + +.choicebox .menu-item:hover { + -fx-cursor: hand; + + -fx-background-color: #ffffff11; +} + .separator { -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; } \ No newline at end of file