You have no choice
This commit is contained in:
@@ -8,7 +8,9 @@ import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaginatedList extends MinionsGui {
|
||||
private int page = 0;
|
||||
@@ -16,6 +18,7 @@ public class PaginatedList extends MinionsGui {
|
||||
private final Component title;
|
||||
private final int size;
|
||||
private final BiFunction<Integer, PaginatedList, GuiElementBuilder> display;
|
||||
private Runnable onClose = null;
|
||||
|
||||
public PaginatedList(MinionsGui parent, Component title, int size, BiFunction<Integer, PaginatedList, GuiElementBuilder> display) {
|
||||
super(parent);
|
||||
@@ -25,12 +28,20 @@ public class PaginatedList extends MinionsGui {
|
||||
open();
|
||||
}
|
||||
|
||||
public PaginatedList(MinionsGui parent, Component title, int size, BiFunction<Integer, PaginatedList, GuiElementBuilder> display, Runnable onClose) {
|
||||
this(parent, title, size, display);
|
||||
this.onClose = onClose;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void open() {
|
||||
gui = new SimpleGui(MenuType.GENERIC_9x6, viewer, false) {
|
||||
@Override
|
||||
public void onPlayerClose(boolean success) {
|
||||
onBackingClosed();
|
||||
if(onClose != null) {
|
||||
onClose.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
gui.setTitle(title);
|
||||
@@ -53,6 +64,17 @@ public class PaginatedList extends MinionsGui {
|
||||
new PaginatedList(parent, title, list.size(), (i, gui) -> display.apply(list.byId(i), gui));
|
||||
}
|
||||
|
||||
public static <T> CompletableFuture<T> createListFuture(MinionsGui parent, Component title, List<T> list, Function<T, GuiElementBuilder> display) {
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
new PaginatedList(parent, title, list.size(), (i, me) -> display.apply(list.get(i))
|
||||
.setCallback(() -> {
|
||||
future.complete(list.get(i));
|
||||
me.goBack();
|
||||
})
|
||||
);
|
||||
return future;
|
||||
}
|
||||
|
||||
private void addItems() {
|
||||
int slot = 9;
|
||||
for(int i = 36 * page; i < Math.min(36 * (page + 1), size); i++) {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package io.github.skippyall.minions.gui.input
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder
|
||||
import eu.pb4.sgui.api.gui.SimpleGui
|
||||
import io.github.skippyall.minions.gui.MinionsGui
|
||||
import io.github.skippyall.minions.gui.minion.SimpleMinionsGui
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.future.asCompletableFuture
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.inventory.MenuType
|
||||
import net.minecraft.world.item.Items
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
object BooleanInput {
|
||||
fun confirm(
|
||||
parent: MinionsGui,
|
||||
title: Component,
|
||||
falseText: Component = Component.translatable("minions.gui.abort"),
|
||||
trueText: Component = Component.translatable("minions.gui.confirm")
|
||||
): CompletableDeferred<Boolean> {
|
||||
val deferred = CompletableDeferred<Boolean>()
|
||||
|
||||
SimpleMinionsGui(parent) { onClose: Runnable, me: SimpleMinionsGui ->
|
||||
val gui: SimpleGui = object : SimpleGui(MenuType.GENERIC_3x3, parent.viewer, false) {
|
||||
override fun onPlayerClose(success: Boolean) {
|
||||
deferred.complete(false)
|
||||
onClose.run()
|
||||
}
|
||||
}
|
||||
gui.setTitle(title)
|
||||
|
||||
gui.setSlot(
|
||||
3, GuiElementBuilder(Items.REDSTONE_BLOCK)
|
||||
.setName(falseText)
|
||||
.setCallback(Runnable {
|
||||
deferred.complete(false)
|
||||
me.goBack()
|
||||
})
|
||||
)
|
||||
|
||||
gui.setSlot(
|
||||
5, GuiElementBuilder(Items.EMERALD_BLOCK)
|
||||
.setName(trueText)
|
||||
.setCallback(Runnable {
|
||||
deferred.complete(true)
|
||||
me.goBack()
|
||||
})
|
||||
)
|
||||
|
||||
gui.open()
|
||||
gui
|
||||
}
|
||||
return deferred
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun confirmFuture(
|
||||
parent: MinionsGui,
|
||||
title: Component,
|
||||
falseText: Component = Component.translatable("minions.gui.abort"),
|
||||
trueText: Component = Component.translatable("minions.gui.confirm")
|
||||
): CompletableFuture<Boolean> {
|
||||
return confirm(
|
||||
parent,
|
||||
title,
|
||||
falseText,
|
||||
trueText
|
||||
).asCompletableFuture()
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
package io.github.skippyall.minions.gui.input;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.gui.Displayable;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.gui.MinionsGui;
|
||||
import io.github.skippyall.minions.gui.minion.SimpleMinionsGui;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ChoiceInput {
|
||||
public static <T> BiFunction<ServerPlayer, T, CompletableFuture<T>> createDialogOpener(MenuType<?> screen, Component title, Function<T, GuiDisplay> displayFunction, T[] values, @Nullable T fallback) {
|
||||
return (player, object) -> {
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
|
||||
SimpleGui gui = new SimpleGui(screen, player, false) {
|
||||
@Override
|
||||
public void onPlayerClose(boolean success) {
|
||||
if(fallback == null) {
|
||||
future.cancel(false);
|
||||
} else {
|
||||
future.complete(fallback);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gui.setTitle(title);
|
||||
|
||||
for(T value : values) {
|
||||
gui.addSlot(new GuiElementBuilder(displayFunction.apply(value).createItemStack())
|
||||
.setCallback(() -> future.complete(value))
|
||||
);
|
||||
}
|
||||
gui.open();
|
||||
return future;
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends Displayable> BiFunction<ServerPlayer, T, CompletableFuture<T>> createDialogOpener(T[] values) {
|
||||
return createDialogOpener(MenuType.GENERIC_9x3, Component.empty(), t -> t != null ? t.getDisplay() : null, values, null);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> confirm(ServerPlayer player, Component title) {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, player, false) {
|
||||
@Override
|
||||
public void onPlayerClose(boolean success) {
|
||||
future.cancel(false);
|
||||
}
|
||||
};
|
||||
|
||||
gui.setTitle(title);
|
||||
|
||||
gui.setSlot(3, new GuiElementBuilder(Items.REDSTONE_BLOCK)
|
||||
.setName(Component.translatable("minions.gui.abort"))
|
||||
.setCallback(() -> future.cancel(false))
|
||||
);
|
||||
|
||||
gui.setSlot(5, new GuiElementBuilder(Items.EMERALD_BLOCK)
|
||||
.setName(Component.translatable("minions.gui.confirm"))
|
||||
.setCallback(() -> future.complete(null))
|
||||
);
|
||||
|
||||
gui.open();
|
||||
return future;
|
||||
}
|
||||
|
||||
public static CompletableFuture<Boolean> confirm(MinionsGui parent, Component title) {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
|
||||
new SimpleMinionsGui(parent, (onClose, me) -> {
|
||||
SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, parent.viewer, false) {
|
||||
@Override
|
||||
public void onPlayerClose(boolean success) {
|
||||
future.complete(false);
|
||||
onClose.run();
|
||||
}
|
||||
};
|
||||
|
||||
gui.setTitle(title);
|
||||
|
||||
gui.setSlot(3, new GuiElementBuilder(Items.REDSTONE_BLOCK)
|
||||
.setName(Component.translatable("minions.gui.abort"))
|
||||
.setCallback(() -> {
|
||||
future.complete(false);
|
||||
me.goBack();
|
||||
})
|
||||
);
|
||||
|
||||
gui.setSlot(5, new GuiElementBuilder(Items.EMERALD_BLOCK)
|
||||
.setName(Component.translatable("minions.gui.confirm"))
|
||||
.setCallback(() -> {
|
||||
future.complete(true);
|
||||
me.goBack();
|
||||
})
|
||||
);
|
||||
|
||||
gui.open();
|
||||
return gui;
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
public static BiFunction<ServerPlayer, Boolean, CompletableFuture<Boolean>> inputBoolean(Component title) {
|
||||
return createDialogOpener(MenuType.GENERIC_3x3, title, value -> {
|
||||
if(value) {
|
||||
return new GuiDisplay.ItemBased(Items.EMERALD_BLOCK);
|
||||
} else {
|
||||
return new GuiDisplay.ItemBased(Items.REDSTONE_BLOCK);
|
||||
}
|
||||
}, new Boolean[]{false, true}, false);
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package io.github.skippyall.minions.gui.input
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder
|
||||
import eu.pb4.sgui.api.gui.AnvilInputGui
|
||||
import io.github.skippyall.minions.gui.MinionsGui
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.future.asCompletableFuture
|
||||
import kotlinx.coroutines.launch
|
||||
import net.minecraft.network.chat.Component
|
||||
@@ -29,9 +29,7 @@ class TextInput<T>(
|
||||
private lateinit var gui: AnvilInputGui
|
||||
|
||||
private var result: Result<T, Component>? = null
|
||||
private var isConfirm = false
|
||||
|
||||
val job = Job()
|
||||
val deferred = CompletableDeferred<T?>()
|
||||
|
||||
init {
|
||||
updateConfirmButton(defaultValue)
|
||||
@@ -46,8 +44,8 @@ class TextInput<T>(
|
||||
|
||||
override fun onPlayerClose(success: Boolean) {
|
||||
onBackingClosed()
|
||||
if (job.isActive && !isConfirm) {
|
||||
job.cancel()
|
||||
if (deferred.isActive) {
|
||||
deferred.complete(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,20 +73,19 @@ class TextInput<T>(
|
||||
}
|
||||
|
||||
fun onConfirm() {
|
||||
result?.ifSuccess { _: T? ->
|
||||
isConfirm = true
|
||||
result?.ifSuccess { success: T ->
|
||||
deferred.complete(success)
|
||||
}
|
||||
job.complete()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
suspend fun <T>input(
|
||||
fun <T>input(
|
||||
gui: MinionsGui,
|
||||
title: Component,
|
||||
defaultValue: String,
|
||||
parser: suspend (String) -> Result<T, Component>,
|
||||
): T? {
|
||||
): Deferred<T?> {
|
||||
val input = TextInput(
|
||||
parent = gui,
|
||||
title = title,
|
||||
@@ -96,9 +93,7 @@ class TextInput<T>(
|
||||
parser = parser,
|
||||
)
|
||||
|
||||
input.job.join()
|
||||
|
||||
return input.result?.getOrDefault(null)
|
||||
return input.deferred
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@@ -108,26 +103,20 @@ class TextInput<T>(
|
||||
defaultValue: String,
|
||||
parser: (String) -> Result<T, Component>,
|
||||
): CompletableFuture<T?> {
|
||||
return gui.scope.async {
|
||||
val input = TextInput(
|
||||
parent = gui,
|
||||
return input(
|
||||
gui = gui,
|
||||
title = title,
|
||||
defaultValue = defaultValue,
|
||||
parser = parser,
|
||||
)
|
||||
|
||||
input.job.join()
|
||||
|
||||
return@async input.result?.getOrDefault(null)
|
||||
}.asCompletableFuture()
|
||||
parser = parser
|
||||
).asCompletableFuture()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
suspend fun inputString(
|
||||
fun inputString(
|
||||
gui: MinionsGui,
|
||||
title: Component,
|
||||
defaultValue: String,
|
||||
): String? {
|
||||
): Deferred<String?> {
|
||||
return input<String>(
|
||||
gui = gui,
|
||||
title = title,
|
||||
@@ -142,21 +131,19 @@ class TextInput<T>(
|
||||
title: Component,
|
||||
defaultValue: String,
|
||||
): CompletableFuture<String?> {
|
||||
return gui.scope.async {
|
||||
inputString(
|
||||
gui,
|
||||
title,
|
||||
defaultValue
|
||||
)
|
||||
}.asCompletableFuture()
|
||||
return inputString(
|
||||
gui = gui,
|
||||
title = title,
|
||||
defaultValue = defaultValue,
|
||||
).asCompletableFuture()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
suspend fun inputLong(
|
||||
fun inputLong(
|
||||
gui: MinionsGui,
|
||||
title: Component,
|
||||
defaultValue: Long,
|
||||
): Long? {
|
||||
): Deferred<Long?> {
|
||||
return input<Long>(
|
||||
gui = gui,
|
||||
title = title,
|
||||
@@ -176,21 +163,19 @@ class TextInput<T>(
|
||||
title: Component,
|
||||
defaultValue: Long,
|
||||
): CompletableFuture<Long?> {
|
||||
return gui.scope.async {
|
||||
inputLong(
|
||||
gui,
|
||||
title,
|
||||
defaultValue
|
||||
)
|
||||
}.asCompletableFuture()
|
||||
return inputLong(
|
||||
gui = gui,
|
||||
title = title,
|
||||
defaultValue = defaultValue,
|
||||
).asCompletableFuture()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
suspend fun inputDouble(
|
||||
fun inputDouble(
|
||||
gui: MinionsGui,
|
||||
title: Component,
|
||||
defaultValue: Double,
|
||||
): Double? {
|
||||
): Deferred<Double?> {
|
||||
return input<Double>(
|
||||
gui = gui,
|
||||
title = title,
|
||||
@@ -210,13 +195,11 @@ class TextInput<T>(
|
||||
title: Component,
|
||||
defaultValue: Double,
|
||||
): CompletableFuture<Double?> {
|
||||
return gui.scope.async {
|
||||
inputDouble(
|
||||
gui,
|
||||
title,
|
||||
defaultValue
|
||||
)
|
||||
}.asCompletableFuture()
|
||||
return inputDouble(
|
||||
gui = gui,
|
||||
title = title,
|
||||
defaultValue = defaultValue,
|
||||
).asCompletableFuture()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.clipboard.ClipboardItem;
|
||||
import io.github.skippyall.minions.gui.MinionsGui;
|
||||
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
||||
import io.github.skippyall.minions.gui.input.BooleanInput;
|
||||
import io.github.skippyall.minions.gui.minion.GuiContext;
|
||||
import io.github.skippyall.minions.minion.MinionListener;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
@@ -60,7 +60,7 @@ public class ConfigureInstructionGui extends MinionsGui implements ConfiguredIns
|
||||
|
||||
gui.setSlot(7, new GuiElementBuilder(Items.LAVA_BUCKET)
|
||||
.setName(Component.translatable("minions.gui.instruction.configure.delete"))
|
||||
.setCallback(() -> ChoiceInput.confirm(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name))
|
||||
.setCallback(() -> BooleanInput.confirmFuture(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name))
|
||||
.thenAccept((confirmed) -> {
|
||||
if(confirmed) {
|
||||
minion.getInstructionManager().removeInstruction(name);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package io.github.skippyall.minions.registration;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.gui.PaginatedList;
|
||||
import io.github.skippyall.minions.gui.input.BooleanInput;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.program.instruction.move.TurnDirection;
|
||||
import io.github.skippyall.minions.program.value.SimpleValueType;
|
||||
@@ -10,7 +13,7 @@ import net.minecraft.core.Registry;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.List;
|
||||
|
||||
public class ValueTypes {
|
||||
public static ValueType<Long> LONG = register(
|
||||
@@ -49,8 +52,7 @@ public class ValueTypes {
|
||||
Codec.BOOL,
|
||||
false,
|
||||
o -> o instanceof Boolean b ? b : null,
|
||||
//TODO Properly implement ChoiceInput
|
||||
(gui, value) -> CompletableFuture.completedFuture(value),//ChoiceInput.inputBoolean(Text.literal("")),
|
||||
(parent, value) -> BooleanInput.confirmFuture(parent, Component.literal(""), Component.translatable("value_type.minions.boolean.false"), Component.translatable("value_type.minions.boolean.true")),
|
||||
value -> Component.literal(value.toString())
|
||||
)
|
||||
);
|
||||
@@ -76,8 +78,12 @@ public class ValueTypes {
|
||||
TurnDirection.CODEC,
|
||||
TurnDirection.RIGHT,
|
||||
o -> o instanceof TurnDirection d ? d : null,
|
||||
//TODO Properly implement ChoiceInput
|
||||
(parent, oldValue) -> CompletableFuture.completedFuture(oldValue), // ChoiceInput.createDialogOpener(TurnDirection.values()),
|
||||
(parent, oldValue) -> PaginatedList.createListFuture(
|
||||
parent,
|
||||
Component.translatable("value_type.minions.turn_direction"),
|
||||
List.of(TurnDirection.values()),
|
||||
value -> new GuiElementBuilder(value.getDisplay().createItemStack())
|
||||
),
|
||||
value -> Component.literal(value.name)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
"value_type.minions.long": "Integer",
|
||||
"value_type.minions.double": "Decimal",
|
||||
"value_type.minions.boolean": "Boolean",
|
||||
"value_type.minions.boolean.true": "True",
|
||||
"value_type.minions.boolean.false": "False",
|
||||
"value_type.minions.string": "Text",
|
||||
"value_type.minions.turn_direction": "Turn Direction",
|
||||
|
||||
|
||||
Reference in New Issue
Block a user