From 0d50a6397c9e8e70abd88e455f5c2cc0400a24e7 Mon Sep 17 00:00:00 2001 From: Almas Baimagambetov Date: Thu, 25 Nov 2021 20:16:07 +0000 Subject: [PATCH] added showChoiceBox, closes #1094 --- .../main/java/intermediate/DialogsSample.java | 5 +++ .../almasb/fxgl/ui/DialogFactoryService.java | 2 + .../com/almasb/fxgl/ui/DialogService.java | 12 ++++++ .../ui/FXGLDialogFactoryServiceProvider.kt | 41 +++++++++++++++++++ .../fxgl/app/services/FXGLDialogService.kt | 9 ++++ .../com/almasb/fxgl/app/MockDialogService.kt | 3 ++ 6 files changed, 72 insertions(+) diff --git a/fxgl-samples/src/main/java/intermediate/DialogsSample.java b/fxgl-samples/src/main/java/intermediate/DialogsSample.java index e0474a1b3a..4ab51651b9 100644 --- a/fxgl-samples/src/main/java/intermediate/DialogsSample.java +++ b/fxgl-samples/src/main/java/intermediate/DialogsSample.java @@ -37,6 +37,11 @@ protected void initUI() { dialogs.put("Error", () -> getDialogService().showErrorBox("This is a scary error box!", () -> {})); + dialogs.put("Choice with 1", () -> getDialogService().showChoiceBox("Choose wisely!", answer -> System.out.println("Chosen: " + answer), "Hello")); + dialogs.put("Choice with 2", () -> getDialogService().showChoiceBox("Choose wisely!", answer -> System.out.println("Chosen: " + answer), "Hello", "World")); + dialogs.put("Choice with 3", () -> getDialogService().showChoiceBox("Choose wisely!", answer -> System.out.println("Chosen: " + answer), "Hello", "World", "FXGL")); + dialogs.put("Choice with 4", () -> getDialogService().showChoiceBox("Choose wisely!", answer -> System.out.println("Chosen: " + answer), "Hello", "World", "FXGL", "JavaFX")); + dialogs.put("Confirmation", () -> getDialogService().showConfirmationBox("This is a confirmation box. Agree?", answer -> System.out.println("You pressed yes? " + answer))); dialogs.put("Input", () -> getDialogService().showInputBox("This is an input box. You can type stuff...", answer -> System.out.println("You typed: "+ answer))); diff --git a/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogFactoryService.java b/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogFactoryService.java index c04197e11b..1f68de0954 100644 --- a/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogFactoryService.java +++ b/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogFactoryService.java @@ -26,6 +26,8 @@ public abstract class DialogFactoryService extends EngineService { public abstract Pane confirmationDialog(String message, Consumer callback); + public abstract Pane choiceDialog(String message, Consumer resultCallback, T firstOption, T... options); + public abstract Pane inputDialog(String message, Consumer callback); public abstract Pane inputDialog(String message, Predicate filter, Consumer callback); diff --git a/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogService.java b/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogService.java index 42bd6a69da..30a9fda147 100644 --- a/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogService.java +++ b/fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogService.java @@ -47,6 +47,18 @@ public abstract class DialogService extends EngineService { */ public abstract void showConfirmationBox(String message, Consumer resultCallback); + /** + * Shows a blocking message box with given choices. + * The callback is invoked with the user answer as parameter. + * + * @param message message to show + * @param resultCallback the function to be called + * @param firstOption the first option + * @param options any other options + * @param type of options + */ + public abstract void showChoiceBox(String message, Consumer resultCallback, T firstOption, T... options); + /** * Shows a blocking (stops game execution, method returns normally) message box with OK button and input field. The callback * is invoked with the field text as parameter. diff --git a/fxgl-scene/src/main/kotlin/com/almasb/fxgl/ui/FXGLDialogFactoryServiceProvider.kt b/fxgl-scene/src/main/kotlin/com/almasb/fxgl/ui/FXGLDialogFactoryServiceProvider.kt index 84dc5fb4fb..e8eb6e51e9 100644 --- a/fxgl-scene/src/main/kotlin/com/almasb/fxgl/ui/FXGLDialogFactoryServiceProvider.kt +++ b/fxgl-scene/src/main/kotlin/com/almasb/fxgl/ui/FXGLDialogFactoryServiceProvider.kt @@ -11,6 +11,7 @@ import com.almasb.fxgl.localization.LocalizationService import javafx.beans.binding.StringBinding import javafx.beans.property.ReadOnlyDoubleProperty import javafx.beans.value.ChangeListener +import javafx.collections.FXCollections import javafx.geometry.Insets import javafx.geometry.Pos import javafx.scene.Node @@ -89,6 +90,46 @@ class FXGLDialogFactoryServiceProvider : DialogFactoryService() { return wrap(vbox) } + override fun choiceDialog(message: String, resultCallback: Consumer, firstOption: T, vararg options: T): Pane { + val text = createMessage(message) + + val choices = options.toMutableList() + choices.add(0, firstOption) + + val hbox = HBox() + + if (choices.size > 3) { + + val choiceBox = uiFactory.newChoiceBox(FXCollections.observableArrayList(choices)) + choiceBox.selectionModel.selectFirst() + + val btn = uiFactory.newButton("Select") + btn.setOnAction { + resultCallback.accept(choiceBox.value) + } + + hbox.children += choiceBox + hbox.children += btn + + } else { + choices.forEach { option -> + val btn = uiFactory.newButton(option.toString()) + btn.setOnAction { + resultCallback.accept(option) + } + + hbox.children += btn + } + } + + hbox.alignment = Pos.CENTER + + val vbox = VBox(50.0, text, hbox) + vbox.setAlignment(Pos.CENTER) + + return wrap(vbox) + } + override fun inputDialog(message: String, callback: Consumer): Pane { return inputDialog(message, Predicate { true }, callback) } diff --git a/fxgl/src/main/kotlin/com/almasb/fxgl/app/services/FXGLDialogService.kt b/fxgl/src/main/kotlin/com/almasb/fxgl/app/services/FXGLDialogService.kt index 925e53120d..41b44aefc7 100644 --- a/fxgl/src/main/kotlin/com/almasb/fxgl/app/services/FXGLDialogService.kt +++ b/fxgl/src/main/kotlin/com/almasb/fxgl/app/services/FXGLDialogService.kt @@ -133,6 +133,15 @@ class FXGLDialogService : DialogService() { show("Confirm", dialog) } + override fun showChoiceBox(message: String, callback: Consumer, firstOption: T, vararg options: T) { + val dialog = dialogFactory.choiceDialog(message, { result -> + close() + callback.accept(result) + }, firstOption, *options) + + show("Choice", dialog) + } + override fun showInputBox(message: String, resultCallback: Consumer) { showInputBox(message, Predicate { true }, resultCallback) } diff --git a/fxgl/src/test/kotlin/com/almasb/fxgl/app/MockDialogService.kt b/fxgl/src/test/kotlin/com/almasb/fxgl/app/MockDialogService.kt index 89cb093f4e..bcd8bf7709 100644 --- a/fxgl/src/test/kotlin/com/almasb/fxgl/app/MockDialogService.kt +++ b/fxgl/src/test/kotlin/com/almasb/fxgl/app/MockDialogService.kt @@ -28,6 +28,9 @@ object MockDialogService : DialogService() { override fun showConfirmationBox(message: String?, resultCallback: Consumer?) { } + override fun showChoiceBox(message: String?, resultCallback: Consumer?, firstOption: T, vararg options: T) { + } + override fun showInputBoxWithCancel(message: String?, filter: Predicate?, resultCallback: Consumer?) { }