From 55d087841b419276087fa79fafe11100cefbf6ec Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Sat, 1 Apr 2023 14:08:31 +0200 Subject: [PATCH] feat: the detector now is a proper amount screen --- CHANGELOG.md | 5 + .../detector/DetectorContainerMenu.java | 4 +- .../common/screen/DetectorScreen.java | 101 ++++--------- .../screen/amount/AbstractAmountScreen.java | 142 ++++++++++-------- .../screen/amount/AmountOperations.java | 14 ++ .../amount/AmountScreenConfiguration.java | 134 +++++++++++++---- .../screen/amount/DoubleAmountOperations.java | 61 ++++++++ .../amount/IntegerAmountOperations.java | 49 ++++++ .../screen/amount/LongAmountOperations.java | 49 ++++++ .../common/screen/amount/PriorityScreen.java | 10 +- .../screen/amount/ResourceAmountScreen.java | 24 +-- .../refinedstorage2/textures/gui/detector.png | Bin 806 -> 815 bytes 12 files changed, 412 insertions(+), 181 deletions(-) create mode 100644 refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountOperations.java create mode 100644 refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/DoubleAmountOperations.java create mode 100644 refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/IntegerAmountOperations.java create mode 100644 refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/LongAmountOperations.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 60fbd74da..0d692722e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed + +- The Detector screen now is a proper amount screen by having increment/decrement buttons and scrollbar support. +- The amount in an amount screen is now colored red if the amount is invalid. + ## [2.0.0-milestone.2.9] - 2023-03-31 ### Fixed diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/containermenu/detector/DetectorContainerMenu.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/containermenu/detector/DetectorContainerMenu.java index dce807147..1ce391937 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/containermenu/detector/DetectorContainerMenu.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/containermenu/detector/DetectorContainerMenu.java @@ -56,8 +56,8 @@ public DetectorContainerMenu(final int syncId, } private void addSlots(final ResourceFilterContainer config) { - addSlot(new ResourceFilterSlot(config, 0, 107, 20)); - addPlayerInventory(player.getInventory(), 8, 55); + addSlot(new ResourceFilterSlot(config, 0, 116, 47)); + addPlayerInventory(player.getInventory(), 8, 106); transferManager.addFilterTransfer(player.getInventory()); } diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/DetectorScreen.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/DetectorScreen.java index d72cce0c3..d4fc0bd7a 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/DetectorScreen.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/DetectorScreen.java @@ -2,78 +2,51 @@ import com.refinedmods.refinedstorage2.platform.common.containermenu.detector.DetectorContainerMenu; import com.refinedmods.refinedstorage2.platform.common.containermenu.property.PropertyTypes; +import com.refinedmods.refinedstorage2.platform.common.screen.amount.AbstractAmountScreen; +import com.refinedmods.refinedstorage2.platform.common.screen.amount.AmountScreenConfiguration; +import com.refinedmods.refinedstorage2.platform.common.screen.amount.DoubleAmountOperations; import com.refinedmods.refinedstorage2.platform.common.screen.widget.DetectorModeSideButtonWidget; import com.refinedmods.refinedstorage2.platform.common.screen.widget.FuzzyModeSideButtonWidget; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.Locale; -import java.util.function.Predicate; -import java.util.regex.Pattern; -import javax.annotation.Nullable; - import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.gui.components.EditBox; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; +import org.joml.Vector3f; import static com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil.createIdentifier; -public class DetectorScreen extends AbstractBaseScreen { +public class DetectorScreen extends AbstractAmountScreen { private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/detector.png"); - private static final Predicate DECIMAL_PATTERN = Pattern.compile("\\d*\\.?\\d*").asMatchPredicate(); - private static final DecimalFormat DECIMAL_FORMAT; - - static { - final DecimalFormatSymbols initialAmountSymbols = new DecimalFormatSymbols(Locale.ROOT); - initialAmountSymbols.setDecimalSeparator('.'); - DECIMAL_FORMAT = new DecimalFormat("##.###", initialAmountSymbols); - DECIMAL_FORMAT.setGroupingUsed(false); - } - - @Nullable - private EditBox amountBox; public DetectorScreen(final DetectorContainerMenu menu, final Inventory playerInventory, final Component text) { - super(menu, playerInventory, text); - this.inventoryLabelY = 43; + super( + menu, + null, + playerInventory, + text, + AmountScreenConfiguration.AmountScreenConfigurationBuilder.create() + .withInitialAmount(menu.getAmount()) + .withIncrementsTop(1, 10, 64) + .withIncrementsBottom(-1, -10, -64) + .withIncrementsTopStartPosition(new Vector3f(40, 20, 0)) + .withIncrementsBottomStartPosition(new Vector3f(40, 70, 0)) + .withAmountFieldWidth(59) + .withAmountFieldPosition(new Vector3f(45, 51, 0)) + .withActionButtonsEnabled(false) + .withMinAmount(0D) + .withResetAmount(0D) + .build(), + DoubleAmountOperations.INSTANCE + ); + this.inventoryLabelY = 94; this.imageWidth = 176; - this.imageHeight = 137; + this.imageHeight = 188; } @Override protected void init() { super.init(); - if (amountBox == null) { - amountBox = new EditBox( - font, - leftPos + 41, - topPos + 24, - 50, - font.lineHeight, - Component.literal("") - ); - } else { - amountBox.setX(leftPos + 41); - amountBox.setY(topPos + 24); - } - amountBox.setFocus(false); - amountBox.setCanLoseFocus(true); - amountBox.setBordered(false); - amountBox.setFilter(DECIMAL_PATTERN); - amountBox.setValue(DECIMAL_FORMAT.format(menu.getAmount())); - amountBox.setResponder(value -> { - try { - final double amount = value.trim().isEmpty() - ? 0 - : Double.parseDouble(value); - menu.changeAmountOnClient(amount); - } catch (final NumberFormatException e) { - // do nothing - } - }); - addWidget(amountBox); addSideButton(new FuzzyModeSideButtonWidget( getMenu().getProperty(PropertyTypes.FUZZY_MODE), this::renderComponentTooltip @@ -85,26 +58,18 @@ protected void init() { } @Override - public void render(final PoseStack poseStack, final int mouseX, final int mouseY, final float partialTicks) { - super.render(poseStack, mouseX, mouseY, partialTicks); - if (amountBox != null) { - amountBox.render(poseStack, mouseX, mouseY, partialTicks); - } + protected void accept(final Double amount) { + getMenu().changeAmountOnClient(amount); } @Override - public boolean charTyped(final char unknown1, final int unknown2) { - return (amountBox != null && amountBox.charTyped(unknown1, unknown2)) || super.charTyped(unknown1, unknown2); - } - - @Override - public boolean keyPressed(final int key, final int scanCode, final int modifiers) { - return (amountBox != null && amountBox.keyPressed(key, scanCode, modifiers)) - || super.keyPressed(key, scanCode, modifiers); + protected ResourceLocation getTexture() { + return TEXTURE; } @Override - protected ResourceLocation getTexture() { - return TEXTURE; + protected void renderLabels(final PoseStack poseStack, final int mouseX, final int mouseY) { + super.renderLabels(poseStack, mouseX, mouseY); + font.draw(poseStack, this.playerInventoryTitle, inventoryLabelX, inventoryLabelY, 4210752); } } diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AbstractAmountScreen.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AbstractAmountScreen.java index 5f8e2a239..67f9d28f1 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AbstractAmountScreen.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AbstractAmountScreen.java @@ -2,17 +2,18 @@ import com.refinedmods.refinedstorage2.platform.common.screen.AbstractBaseScreen; +import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -22,58 +23,45 @@ import static com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil.createTranslation; -public abstract class AbstractAmountScreen extends AbstractBaseScreen { +public abstract class AbstractAmountScreen + extends AbstractBaseScreen { private static final MutableComponent SET_TEXT = createTranslation("gui", "amount.set"); private static final MutableComponent RESET_TEXT = createTranslation("gui", "amount.reset"); private static final MutableComponent CANCEL_TEXT = Component.translatable("gui.cancel"); private static final int INCREMENT_BUTTON_WIDTH = 30; - private static final int INCREMENT_BUTTON_X = 7; - private static final int INCREMENT_BUTTON_TOP_Y = 20; - private static final int ACTION_BUTTON_WIDTH = 50; + @Nullable private final Screen parent; + private final AmountScreenConfiguration configuration; + private final AmountOperations amountOperations; @Nullable private EditBox amountField; @Nullable private Button confirmButton; - private final AmountScreenConfiguration configuration; - - protected AbstractAmountScreen(final Screen parent, - final Inventory playerInventory, - final Component title, - final AmountScreenConfiguration configuration) { - this(new DefaultDummyContainerMenu(), parent, playerInventory, title, configuration); - } - - protected AbstractAmountScreen(final AbstractContainerMenu containerMenu, - final Screen parent, + protected AbstractAmountScreen(final T containerMenu, + @Nullable final Screen parent, final Inventory playerInventory, final Component title, - final AmountScreenConfiguration configuration) { + final AmountScreenConfiguration configuration, + final AmountOperations amountOperations) { super(containerMenu, playerInventory, title); this.parent = parent; this.configuration = configuration; + this.amountOperations = amountOperations; } @Override protected void init() { super.init(); - addActionButtons(); + if (configuration.isActionButtonsEnabled()) { + addActionButtons(); + } addAmountField(); - addIncrementButtons( - configuration.getIncrementsTop(), - leftPos + INCREMENT_BUTTON_X, - topPos + INCREMENT_BUTTON_TOP_Y - ); - addIncrementButtons( - configuration.getIncrementsBottom(), - leftPos + INCREMENT_BUTTON_X, - topPos + imageHeight - 27 - ); + addIncrementButtons(); } private void addActionButtons() { @@ -83,11 +71,11 @@ private void addActionButtons() { .pos(leftPos + (int) pos.x(), topPos + (int) pos.y()) .size(ACTION_BUTTON_WIDTH, 20) .build()); - confirmButton = addRenderableWidget(Button.builder(SET_TEXT, btn -> tryConfirm()) + confirmButton = addRenderableWidget(Button.builder(SET_TEXT, btn -> tryConfirmAndCloseToParent()) .pos(leftPos + (int) pos.x(), topPos + (int) pos.y() + 24) .size(ACTION_BUTTON_WIDTH, 20) .build()); - addRenderableWidget(Button.builder(CANCEL_TEXT, btn -> close()) + addRenderableWidget(Button.builder(CANCEL_TEXT, btn -> tryCloseToParent()) .pos(leftPos + (int) pos.x(), topPos + (int) pos.y() + 48) .size(ACTION_BUTTON_WIDTH, 20) .build()); @@ -95,30 +83,53 @@ private void addActionButtons() { private void addAmountField() { final Vector3f pos = configuration.getAmountFieldPosition(); - amountField = new EditBox( font, leftPos + (int) pos.x(), topPos + (int) pos.y(), - 69 - 6, + configuration.getAmountFieldWidth() - 6, font.lineHeight, Component.empty() ); amountField.setBordered(false); - amountField.setValue(String.valueOf(configuration.getInitialAmount())); + if (configuration.getInitialAmount() != null) { + amountField.setValue(amountOperations.format(configuration.getInitialAmount())); + } amountField.setVisible(true); amountField.setCanLoseFocus(false); amountField.setFocus(true); amountField.setResponder(value -> { + final boolean valid = getAndValidateAmount().isPresent(); if (confirmButton != null) { - confirmButton.active = getAndValidateAmount().isPresent(); + confirmButton.active = valid; + } else { + tryConfirm(); } + amountField.setTextColor(valid + ? Objects.requireNonNullElse(ChatFormatting.WHITE.getColor(), 15) + : Objects.requireNonNullElse(ChatFormatting.RED.getColor(), 15) + ); }); + amountField.setTextColor(Objects.requireNonNullElse(ChatFormatting.WHITE.getColor(), 15)); + setFocused(amountField); addRenderableWidget(amountField); } - protected abstract void accept(int amount); + private void addIncrementButtons() { + final Vector3f incrementsTopPos = configuration.getIncrementsTopStartPosition(); + addIncrementButtons( + configuration.getIncrementsTop(), + leftPos + (int) incrementsTopPos.x, + topPos + (int) incrementsTopPos.y + ); + final Vector3f incrementsBottomPos = configuration.getIncrementsBottomStartPosition(); + addIncrementButtons( + configuration.getIncrementsBottom(), + leftPos + (int) incrementsBottomPos.x, + topPos + (int) incrementsBottomPos.y + ); + } private void addIncrementButtons(final int[] increments, final int x, final int y) { for (int i = 0; i < increments.length; ++i) { @@ -128,6 +139,8 @@ private void addIncrementButtons(final int[] increments, final int x, final int } } + protected abstract void accept(N amount); + private Button createIncrementButton(final int x, final int y, final int increment) { final Component text = Component.literal((increment > 0 ? "+" : "") + increment); return Button.builder(text, btn -> changeAmount(increment)) @@ -141,13 +154,13 @@ private void changeAmount(final int delta) { return; } getAndValidateAmount().ifPresent(oldAmount -> { - final int newAmount = oldAmount + delta; - final int correctedNewAmount = Mth.clamp( - newAmount, + final N newAmount = amountOperations.changeAmount( + oldAmount, + delta, configuration.getMinAmount(), configuration.getMaxAmount() ); - amountField.setValue(String.valueOf(correctedNewAmount)); + amountField.setValue(amountOperations.format(newAmount)); }); } @@ -175,13 +188,15 @@ public boolean charTyped(final char unknown1, final int unknown2) { @Override public boolean keyPressed(final int key, final int scanCode, final int modifiers) { if (key == GLFW.GLFW_KEY_ESCAPE) { - close(); + if (!tryCloseToParent()) { + onClose(); + } return true; } if (amountField != null && (key == GLFW.GLFW_KEY_ENTER || key == GLFW.GLFW_KEY_KP_ENTER) && amountField.isFocused()) { - tryConfirm(); + tryConfirmAndCloseToParent(); return true; } if (amountField != null @@ -192,46 +207,43 @@ public boolean keyPressed(final int key, final int scanCode, final int modifiers } private void reset() { - if (amountField == null) { + if (amountField == null || configuration.getResetAmount() == null) { return; } - amountField.setValue(String.valueOf(configuration.getResetAmount())); + amountField.setValue(amountOperations.format(configuration.getResetAmount())); } private void tryConfirm() { - getAndValidateAmount().ifPresent(this::confirm); - } - - private void confirm(final int amount) { - accept(amount); - close(); + getAndValidateAmount().ifPresent(this::accept); } - private void close() { - Minecraft.getInstance().setScreen(parent); + private void tryConfirmAndCloseToParent() { + getAndValidateAmount().ifPresent(value -> { + accept(value); + tryCloseToParent(); + }); } - private Optional getAndValidateAmount() { - if (amountField == null) { - return Optional.empty(); - } - try { - final int amount = Integer.parseInt(amountField.getValue()); - return validateAmount(amount); - } catch (NumberFormatException e) { - return Optional.empty(); + private boolean tryCloseToParent() { + if (parent != null) { + Minecraft.getInstance().setScreen(parent); + return true; } + return false; } - private Optional validateAmount(final int amount) { - if (amount >= configuration.getMinAmount() && amount <= configuration.getMaxAmount()) { - return Optional.of(amount); - } else { + private Optional getAndValidateAmount() { + if (amountField == null) { return Optional.empty(); } + return amountOperations.parse(amountField.getValue()).flatMap(amount -> amountOperations.validate( + amount, + configuration.getMinAmount(), + configuration.getMaxAmount() + )); } - private static class DefaultDummyContainerMenu extends AbstractContainerMenu { + protected static class DefaultDummyContainerMenu extends AbstractContainerMenu { protected DefaultDummyContainerMenu() { super(null, 0); } diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountOperations.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountOperations.java new file mode 100644 index 000000000..0bad40ccf --- /dev/null +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountOperations.java @@ -0,0 +1,14 @@ +package com.refinedmods.refinedstorage2.platform.common.screen.amount; + +import java.util.Optional; +import javax.annotation.Nullable; + +public interface AmountOperations { + String format(N value); + + Optional parse(String value); + + Optional validate(N amount, @Nullable N minAmount, @Nullable N maxAmount); + + N changeAmount(N current, int delta, @Nullable N minAmount, @Nullable N maxAmount); +} diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountScreenConfiguration.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountScreenConfiguration.java index 3c72013d3..92fa4da4c 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountScreenConfiguration.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/AmountScreenConfiguration.java @@ -1,36 +1,55 @@ package com.refinedmods.refinedstorage2.platform.common.screen.amount; +import javax.annotation.Nullable; + import org.joml.Vector3f; -public final class AmountScreenConfiguration { - private final int initialAmount; +public final class AmountScreenConfiguration { + @Nullable + private final T initialAmount; private final int[] incrementsTop; + private final Vector3f incrementsTopStartPosition; private final int[] incrementsBottom; + private final Vector3f incrementsBottomStartPosition; + private final int amountFieldWidth; private final Vector3f amountFieldPosition; private final Vector3f actionButtonsStartPosition; - private final int minAmount; - private final int maxAmount; - private final int resetAmount; - - private AmountScreenConfiguration(final int initialAmount, + private final boolean actionButtonsEnabled; + @Nullable + private final T minAmount; + @Nullable + private final T maxAmount; + @Nullable + private final T resetAmount; + + private AmountScreenConfiguration(@Nullable final T initialAmount, final int[] incrementsTop, + final Vector3f incrementsTopStartPosition, final int[] incrementsBottom, + final Vector3f incrementsBottomStartPosition, + final int amountFieldWidth, final Vector3f amountFieldPosition, final Vector3f actionButtonsStartPosition, - final int minAmount, - final int maxAmount, - final int resetAmount) { + final boolean actionButtonsEnabled, + @Nullable final T minAmount, + @Nullable final T maxAmount, + @Nullable final T resetAmount) { this.initialAmount = initialAmount; this.incrementsTop = incrementsTop; + this.incrementsTopStartPosition = incrementsTopStartPosition; this.incrementsBottom = incrementsBottom; + this.incrementsBottomStartPosition = incrementsBottomStartPosition; + this.amountFieldWidth = amountFieldWidth; this.amountFieldPosition = amountFieldPosition; this.actionButtonsStartPosition = actionButtonsStartPosition; + this.actionButtonsEnabled = actionButtonsEnabled; this.minAmount = minAmount; this.maxAmount = maxAmount; this.resetAmount = resetAmount; } - public int getInitialAmount() { + @Nullable + public T getInitialAmount() { return initialAmount; } @@ -38,10 +57,22 @@ public int[] getIncrementsTop() { return incrementsTop; } + public Vector3f getIncrementsTopStartPosition() { + return incrementsTopStartPosition; + } + public int[] getIncrementsBottom() { return incrementsBottom; } + public Vector3f getIncrementsBottomStartPosition() { + return incrementsBottomStartPosition; + } + + public int getAmountFieldWidth() { + return amountFieldWidth; + } + public Vector3f getAmountFieldPosition() { return amountFieldPosition; } @@ -50,84 +81,125 @@ public Vector3f getActionButtonsStartPosition() { return actionButtonsStartPosition; } - public int getMinAmount() { + public boolean isActionButtonsEnabled() { + return actionButtonsEnabled; + } + + @Nullable + public T getMinAmount() { return minAmount; } - public int getMaxAmount() { + @Nullable + public T getMaxAmount() { return maxAmount; } - public int getResetAmount() { + @Nullable + public T getResetAmount() { return resetAmount; } - public static final class AmountScreenConfigurationBuilder { - private int initialAmount; + public static final class AmountScreenConfigurationBuilder { + @Nullable + private T initialAmount; private int[] incrementsTop = new int[] {}; + private Vector3f incrementsTopStartPosition = new Vector3f(7, 20, 0); private int[] incrementsBottom = new int[] {}; + private Vector3f incrementsBottomStartPosition = new Vector3f(7, 20 + 47, 0); + private int amountFieldWidth = 68; private Vector3f amountFieldPosition = new Vector3f(0, 0, 0); private Vector3f actionButtonsStartPosition = new Vector3f(0, 0, 0); - private int minAmount; - private int maxAmount; - private int resetAmount; + private boolean actionButtonsEnabled = true; + @Nullable + private T minAmount; + @Nullable + private T maxAmount; + @Nullable + private T resetAmount; private AmountScreenConfigurationBuilder() { } - public static AmountScreenConfigurationBuilder create() { - return new AmountScreenConfigurationBuilder(); + public static AmountScreenConfigurationBuilder create() { + return new AmountScreenConfigurationBuilder<>(); } - public AmountScreenConfigurationBuilder withInitialAmount(final int newInitialAmount) { + public AmountScreenConfigurationBuilder withInitialAmount(final T newInitialAmount) { this.initialAmount = newInitialAmount; return this; } - public AmountScreenConfigurationBuilder withIncrementsTop(final int... newIncrementsTop) { + public AmountScreenConfigurationBuilder withIncrementsTop(final int... newIncrementsTop) { this.incrementsTop = newIncrementsTop; return this; } - public AmountScreenConfigurationBuilder withIncrementsBottom(final int... newIncrementsBottom) { + public AmountScreenConfigurationBuilder withIncrementsTopStartPosition(final Vector3f newPos) { + this.incrementsTopStartPosition = newPos; + return this; + } + + public AmountScreenConfigurationBuilder withIncrementsBottom(final int... newIncrementsBottom) { this.incrementsBottom = newIncrementsBottom; return this; } - public AmountScreenConfigurationBuilder withAmountFieldPosition(final Vector3f newAmountFieldPosition) { + public AmountScreenConfigurationBuilder withIncrementsBottomStartPosition(final Vector3f newPos) { + this.incrementsBottomStartPosition = newPos; + return this; + } + + public AmountScreenConfigurationBuilder withAmountFieldWidth(final int newAmountFieldWidth) { + this.amountFieldWidth = newAmountFieldWidth; + return this; + } + + public AmountScreenConfigurationBuilder withAmountFieldPosition(final Vector3f newAmountFieldPosition) { this.amountFieldPosition = newAmountFieldPosition; return this; } - public AmountScreenConfigurationBuilder withActionButtonsStartPosition( + public AmountScreenConfigurationBuilder withActionButtonsStartPosition( final Vector3f newActionButtonsStartPosition ) { this.actionButtonsStartPosition = newActionButtonsStartPosition; return this; } - public AmountScreenConfigurationBuilder withMinAmount(final int newMinAmount) { + public AmountScreenConfigurationBuilder withActionButtonsEnabled( + final boolean newActionButtonsEnabled + ) { + this.actionButtonsEnabled = newActionButtonsEnabled; + return this; + } + + public AmountScreenConfigurationBuilder withMinAmount(final T newMinAmount) { this.minAmount = newMinAmount; return this; } - public AmountScreenConfigurationBuilder withMaxAmount(final int newMaxAmount) { + public AmountScreenConfigurationBuilder withMaxAmount(final T newMaxAmount) { this.maxAmount = newMaxAmount; return this; } - public AmountScreenConfigurationBuilder withResetAmount(final int newResetAmount) { + public AmountScreenConfigurationBuilder withResetAmount(final T newResetAmount) { this.resetAmount = newResetAmount; return this; } - public AmountScreenConfiguration build() { - return new AmountScreenConfiguration( + public AmountScreenConfiguration build() { + return new AmountScreenConfiguration( initialAmount, incrementsTop, + incrementsTopStartPosition, incrementsBottom, + incrementsBottomStartPosition, + amountFieldWidth, amountFieldPosition, actionButtonsStartPosition, + actionButtonsEnabled, minAmount, maxAmount, resetAmount diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/DoubleAmountOperations.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/DoubleAmountOperations.java new file mode 100644 index 000000000..962f8185a --- /dev/null +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/DoubleAmountOperations.java @@ -0,0 +1,61 @@ +package com.refinedmods.refinedstorage2.platform.common.screen.amount; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; + +import net.minecraft.util.Mth; + +public class DoubleAmountOperations implements AmountOperations { + public static final AmountOperations INSTANCE = new DoubleAmountOperations(); + + private static final DecimalFormat DECIMAL_FORMAT; + + static { + final DecimalFormatSymbols initialAmountSymbols = new DecimalFormatSymbols(Locale.ROOT); + initialAmountSymbols.setDecimalSeparator('.'); + DECIMAL_FORMAT = new DecimalFormat("##.###", initialAmountSymbols); + DECIMAL_FORMAT.setGroupingUsed(false); + } + + private DoubleAmountOperations() { + } + + @Override + public String format(final Double value) { + return DECIMAL_FORMAT.format(value); + } + + @Override + public Optional parse(final String value) { + try { + return Optional.of(Double.parseDouble(value)); + } catch (final NumberFormatException e) { + return Optional.empty(); + } + } + + @Override + public Optional validate(final Double amount, + @Nullable final Double minAmount, + @Nullable final Double maxAmount) { + final boolean minBoundOk = minAmount == null || amount >= minAmount; + final boolean maxBoundOk = maxAmount == null || amount <= maxAmount; + return minBoundOk && maxBoundOk ? Optional.of(amount) : Optional.empty(); + } + + @Override + public Double changeAmount(final Double current, + final int delta, + @Nullable final Double minAmount, + @Nullable final Double maxAmount) { + return Mth.clamp( + current + delta, + Objects.requireNonNullElse(minAmount, Double.MIN_VALUE), + Objects.requireNonNullElse(maxAmount, Double.MAX_VALUE) + ); + } +} diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/IntegerAmountOperations.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/IntegerAmountOperations.java new file mode 100644 index 000000000..8630bbabb --- /dev/null +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/IntegerAmountOperations.java @@ -0,0 +1,49 @@ +package com.refinedmods.refinedstorage2.platform.common.screen.amount; + +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; + +import net.minecraft.util.Mth; + +public class IntegerAmountOperations implements AmountOperations { + public static final AmountOperations INSTANCE = new IntegerAmountOperations(); + + private IntegerAmountOperations() { + } + + @Override + public String format(final Integer value) { + return String.valueOf(value); + } + + @Override + public Optional parse(final String value) { + try { + return Optional.of(Integer.parseInt(value, 10)); + } catch (final NumberFormatException e) { + return Optional.empty(); + } + } + + @Override + public Optional validate(final Integer amount, + @Nullable final Integer minAmount, + @Nullable final Integer maxAmount) { + final boolean minBoundOk = minAmount == null || amount >= minAmount; + final boolean maxBoundOk = maxAmount == null || amount <= maxAmount; + return minBoundOk && maxBoundOk ? Optional.of(amount) : Optional.empty(); + } + + @Override + public Integer changeAmount(final Integer current, + final int delta, + @Nullable final Integer minAmount, + @Nullable final Integer maxAmount) { + return Mth.clamp( + current + delta, + Objects.requireNonNullElse(minAmount, Integer.MIN_VALUE), + Objects.requireNonNullElse(maxAmount, Integer.MAX_VALUE) + ); + } +} diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/LongAmountOperations.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/LongAmountOperations.java new file mode 100644 index 000000000..a933ec811 --- /dev/null +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/LongAmountOperations.java @@ -0,0 +1,49 @@ +package com.refinedmods.refinedstorage2.platform.common.screen.amount; + +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; + +import net.minecraft.util.Mth; + +public class LongAmountOperations implements AmountOperations { + public static final AmountOperations INSTANCE = new LongAmountOperations(); + + private LongAmountOperations() { + } + + @Override + public String format(final Long value) { + return String.valueOf(value); + } + + @Override + public Optional parse(final String value) { + try { + return Optional.of(Long.parseLong(value)); + } catch (final NumberFormatException e) { + return Optional.empty(); + } + } + + @Override + public Optional validate(final Long amount, + @Nullable final Long minAmount, + @Nullable final Long maxAmount) { + final boolean minBoundOk = minAmount == null || amount >= minAmount; + final boolean maxBoundOk = maxAmount == null || amount <= maxAmount; + return minBoundOk && maxBoundOk ? Optional.of(amount) : Optional.empty(); + } + + @Override + public Long changeAmount(final Long current, + final int delta, + @Nullable final Long minAmount, + @Nullable final Long maxAmount) { + return Mth.clamp( + current + delta, + Objects.requireNonNullElse(minAmount, Long.MIN_VALUE), + Objects.requireNonNullElse(maxAmount, Long.MAX_VALUE) + ); + } +} diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/PriorityScreen.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/PriorityScreen.java index 02c02a37a..9c9f6cf6d 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/PriorityScreen.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/PriorityScreen.java @@ -11,7 +11,7 @@ import static com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil.createTranslation; -public class PriorityScreen extends AbstractAmountScreen { +public class PriorityScreen extends AbstractAmountScreen { private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/priority.png"); private static final MutableComponent PRIORITY_TEXT = createTranslation("gui", "priority"); @@ -21,10 +21,11 @@ public PriorityScreen(final ClientProperty property, final Screen parent, final Inventory playerInventory) { super( + new DefaultDummyContainerMenu(), parent, playerInventory, PRIORITY_TEXT, - AmountScreenConfiguration.AmountScreenConfigurationBuilder.create() + AmountScreenConfiguration.AmountScreenConfigurationBuilder.create() .withInitialAmount(property.get()) .withIncrementsTop(1, 5, 10) .withIncrementsBottom(-1, -5, -10) @@ -33,7 +34,8 @@ public PriorityScreen(final ClientProperty property, .withMinAmount(Integer.MIN_VALUE) .withMaxAmount(Integer.MAX_VALUE) .withResetAmount(0) - .build() + .build(), + IntegerAmountOperations.INSTANCE ); this.property = property; this.imageWidth = 164; @@ -41,7 +43,7 @@ public PriorityScreen(final ClientProperty property, } @Override - protected void accept(final int amount) { + protected void accept(final Integer amount) { property.setValue(amount); } diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/ResourceAmountScreen.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/ResourceAmountScreen.java index 8b2b583a5..8b15dfb67 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/ResourceAmountScreen.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/screen/amount/ResourceAmountScreen.java @@ -17,7 +17,7 @@ import static com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil.createTranslation; -public class ResourceAmountScreen extends AbstractAmountScreen { +public class ResourceAmountScreen extends AbstractAmountScreen { private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/resource_amount.png"); private static final MutableComponent TITLE = createTranslation("gui", "amount"); @@ -31,32 +31,34 @@ public ResourceAmountScreen(final Screen parent, parent, playerInventory, TITLE, - AmountScreenConfiguration.AmountScreenConfigurationBuilder.create() + AmountScreenConfiguration.AmountScreenConfigurationBuilder.create() .withInitialAmount(getInitialAmount(slot)) .withIncrementsTop(1, 10, 64) .withIncrementsBottom(-1, -10, -64) + .withIncrementsBottomStartPosition(new Vector3f(7, 20 + 52, 0)) .withAmountFieldPosition(new Vector3f(9, 51, 0)) .withActionButtonsStartPosition(new Vector3f(114, 22, 0)) - .withMinAmount(1) + .withMinAmount(1L) .withMaxAmount(getMaxAmount(slot)) - .withResetAmount(1) - .build() + .withResetAmount(1L) + .build(), + LongAmountOperations.INSTANCE ); this.slot = slot; this.imageWidth = 172; this.imageHeight = 99; } - private static int getInitialAmount(final ResourceFilterSlot slot) { - return slot.getFilteredResource() == null ? 0 : (int) slot.getFilteredResource().getAmount(); + private static long getInitialAmount(final ResourceFilterSlot slot) { + return slot.getFilteredResource() == null ? 0 : slot.getFilteredResource().getAmount(); } - private static int getMaxAmount(final ResourceFilterSlot slot) { - return slot.getFilteredResource() == null ? 0 : (int) slot.getFilteredResource().getMaxAmount(); + private static long getMaxAmount(final ResourceFilterSlot slot) { + return slot.getFilteredResource() == null ? 0 : slot.getFilteredResource().getMaxAmount(); } @Override - protected void accept(final int amount) { + protected void accept(final Long amount) { slot.changeAmountOnClient(amount); } @@ -78,7 +80,7 @@ protected void renderResourceFilterSlotAmount(final PoseStack poseStack, // should not render amount here } - private static class DummyContainerMenu extends AbstractContainerMenu { + public static class DummyContainerMenu extends AbstractContainerMenu { protected DummyContainerMenu(final ResourceFilterSlot slot) { super(null, 0); addSlot(slot.atPosition(89, 48)); diff --git a/refinedstorage2-platform-common/src/main/resources/assets/refinedstorage2/textures/gui/detector.png b/refinedstorage2-platform-common/src/main/resources/assets/refinedstorage2/textures/gui/detector.png index 4c0c15500e020d80bc2bfbccfcdbccbe333be5dd..0c7e3f7fd4c627bfd980da2cf972d6e32c9c0537 100644 GIT binary patch literal 815 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5D>38$lZxy-8q?;Kn_c~qpu?a z!^VE@KZ&eBzG#3?h%1o(|NsB7W5+^6L(R?2ySuxABB`6FO9LtPk|4iepeztDNO?26 z0fjgVJR*x382I*sFrx))unGeM(*#c!$B>G+x3?c=-F6UY4YXYM^}| zd6_%`q78rU^e^E+^}XC>^;o{Wimv3 zS6lun#n9p2ZW-O0?UO6NTsoQ6V3XM|W_RYfA578B-8wL4Lur1|Dxd{lIDjHIcdw~u zsQg~F<-^~+XBWNIS2KRP{p{kQ_zYZHi&sOmHr!;muF7!x?>)1t%zu7P-fg{QEyE6b w*4V1}U7J|Lzi~M{yTOps$4gJDjrq;*{At?@w|KdR%mVq=)78&qol`;+0J7RDzW@LL literal 806 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5D>38$lZxy-8q?;Kn_c~qpu?a z!^VE@KZ&eBzG#3?h%1o(|NsB7W5+^6L(R?2ySuxABB`6FO9LtPk|4iepeztDNO?26 z0fjgVJR*x382Ao=Fk{xWPEG~}rgl#k$B>G+x3?O-?gWUqUhH}N%zllY_q2WL4hhIC{<1OwNG#p>P@4qs@Oe)@)|v5^`W*+)*CM z#G%l@U{mV=q#3^Jc{70YFXvw&*l<58()Pwx{`n=$ALhM#@$I%B&=nwA2ZndC(}2zc zY6B7nuHTRUnX7)5VNZFa>Au^E;miGYG5%O0Yg#vB{amP;28KJkb-+47M8iIF%TRJO z7(-oL&sgz&S60pb)9d`^0v&hx*@}QfZ@jorC TAG*hZ>6F3K)z4*}Q$iB}=dCb(