diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IO.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IO.java index 40a905e48e0..e1ffe4dbb08 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IO.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IO.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.api.capability.recipe; import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.gregtechceu.gtceu.api.mui.drawable.UITexture; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; @@ -21,10 +22,13 @@ public enum IO implements EnumSelectorWidget.SelectableEnum { public final String tooltip; @Getter public final IGuiTexture icon; + @Getter + public final UITexture uiTexture; IO(String tooltip, String textureName) { this.tooltip = tooltip; this.icon = new ResourceTexture("gtceu:textures/gui/icon/io_mode/" + textureName + ".png"); + this.uiTexture = UITexture.fullImage("gtceu:textures/gui/icon/io_mode/" + textureName + ".png"); } public boolean support(IO io) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/IMuiCover.java b/src/main/java/com/gregtechceu/gtceu/api/cover/IMuiCover.java index db6d8c84d99..97c41713dc0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/IMuiCover.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/IMuiCover.java @@ -1,28 +1,24 @@ package com.gregtechceu.gtceu.api.cover; import com.gregtechceu.gtceu.api.mui.base.IUIHolder; -import com.gregtechceu.gtceu.api.mui.base.drawable.IDrawable; import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; -import com.gregtechceu.gtceu.api.mui.base.widget.IWidget; import com.gregtechceu.gtceu.api.mui.drawable.ItemDrawable; import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; -import com.gregtechceu.gtceu.api.mui.utils.Alignment; -import com.gregtechceu.gtceu.api.mui.utils.Color; import com.gregtechceu.gtceu.api.mui.utils.MouseData; import com.gregtechceu.gtceu.api.mui.value.BoolValue; import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue; import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; -import com.gregtechceu.gtceu.api.mui.widgets.ToggleButton; +import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget; import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; import com.gregtechceu.gtceu.client.mui.screen.UISettings; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.common.mui.GTGuiTheme; import com.gregtechceu.gtceu.common.mui.GTGuis; -import net.minecraft.util.StringRepresentable; import net.minecraft.world.item.ItemStack; public interface IMuiCover extends IUIHolder { @@ -45,11 +41,12 @@ default GTGuiTheme getUITheme() { @Override default ModularPanel buildUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { - IWidget widget = createCoverUI(data, syncManager, settings); - return GTGuis.createPanel(this.self(), 176, 166) - .background(GTGuiTextures.BACKGROUND) - .child(widget) - .bindPlayerInventory(); + ModularPanel panel = GTGuis.createPanel(this.self(), 176, 192 + 18); + + panel.child(GTMuiWidgets.createTitleBar(this.self().getAttachItem(), 176, GTGuiTextures.BACKGROUND)); + + return panel.child(createCoverUI(data, syncManager, settings)) + .child(SlotGroupWidget.playerInventory(false).left(7).bottom(7)); } ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings); @@ -97,24 +94,6 @@ default int getIncrementValue(MouseData data) { return adjust; } - default IKey createAdjustOverlay(boolean increment) { - final StringBuilder builder = new StringBuilder(); - builder.append(increment ? '+' : '-'); - builder.append(getIncrementValue(MouseData.create(-1))); - - float scale = 1f; - if (builder.length() == 3) { - scale = 0.8f; - } else if (builder.length() == 4) { - scale = 0.6f; - } else if (builder.length() > 4) { - scale = 0.5f; - } - return IKey.str(builder.toString()) - .color(Color.WHITE.main) - .scale(scale); - } - /** * Get a BoolValue for use with toggle buttons which are "linked together," * meaning only one of them can be pressed at a time. @@ -130,88 +109,4 @@ default > BoolValue.Dynamic boolValueOf(EnumSyncValue syncV default BoolValue.Dynamic boolValueOf(IntSyncValue syncValue, int value) { return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); } - - class EnumRowBuilder> { - - private EnumSyncValue syncValue; - private final Class enumValue; - private IKey lang; - private IDrawable[] background; - private IDrawable selectedBackground; - private IDrawable[] overlay; - - public EnumRowBuilder(Class enumValue) { - this.enumValue = enumValue; - } - - public EnumRowBuilder value(EnumSyncValue syncValue) { - this.syncValue = syncValue; - return this; - } - - public EnumRowBuilder lang(IKey lang) { - this.lang = lang; - return this; - } - - public EnumRowBuilder background(IDrawable... background) { - this.background = background; - return this; - } - - public EnumRowBuilder selectedBackground(IDrawable selectedBackground) { - this.selectedBackground = selectedBackground; - return this; - } - - public EnumRowBuilder overlay(IDrawable... overlay) { - this.overlay = overlay; - return this; - } - - public EnumRowBuilder overlay(int size, IDrawable... overlay) { - this.overlay = new IDrawable[overlay.length]; - for (int i = 0; i < overlay.length; i++) { - this.overlay[i] = overlay[i].asIcon().size(size); - } - return this; - } - - private BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { - return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); - } - - public Flow build() { - var row = Flow.row().marginBottom(2).coverChildrenHeight().widthRel(1f); - if (this.enumValue != null && this.syncValue != null) { - for (var enumVal : enumValue.getEnumConstants()) { - var button = new ToggleButton().size(18).marginRight(2) - .value(boolValueOf(this.syncValue, enumVal)); - - if (this.background != null && this.background.length > 0) - button.background(this.background); - else - button.background(GTGuiTextures.MC_BUTTON); - - if (this.selectedBackground != null) - button.selectedBackground(this.selectedBackground); - else - button.selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED); - - if (this.overlay != null) - button.overlay(this.overlay[enumVal.ordinal()]); - - if (enumVal instanceof StringRepresentable serializable) { - button.addTooltipLine(IKey.lang(serializable.getSerializedName())); - } - row.child(button); - } - } - - if (this.lang != null) - row.child(this.lang.asWidget().align(Alignment.CenterRight).height(18)); - - return row; - } - } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/Filter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/Filter.java index 53492004b49..ebfa18add97 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/Filter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/Filter.java @@ -14,7 +14,9 @@ public interface Filter> extends Predicate { - WidgetGroup openConfigurator(int x, int y); + default WidgetGroup openConfigurator(int x, int y) { + return null; + } /** * @return Filter panel when opened by itself (including the player inventory) diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FluidFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FluidFilter.java index 08c5be97c34..a5d3798d362 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FluidFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FluidFilter.java @@ -5,8 +5,6 @@ import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; import com.gregtechceu.gtceu.client.mui.screen.UISettings; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; - import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; @@ -58,11 +56,6 @@ public int testFluidAmount(FluidStack fluidStack) { return Integer.MAX_VALUE; } - @Override - public WidgetGroup openConfigurator(int x, int y) { - throw new NotImplementedException("Not available for empty fluid filter"); - } - @Override public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { return null; diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/ItemFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/ItemFilter.java index 8cc2ff991df..695bfa8bf22 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/ItemFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/ItemFilter.java @@ -5,8 +5,6 @@ import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; import com.gregtechceu.gtceu.client.mui.screen.UISettings; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; - import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; @@ -57,11 +55,6 @@ public boolean test(ItemStack itemStack) { return true; } - @Override - public WidgetGroup openConfigurator(int x, int y) { - throw new NotImplementedException("Not available for empty item filter"); - } - @Override public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { return null; diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleFluidFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleFluidFilter.java index 74e55b98537..0878f01e712 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleFluidFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleFluidFilter.java @@ -1,15 +1,21 @@ package com.gregtechceu.gtceu.api.cover.filter; -import com.gregtechceu.gtceu.api.gui.GuiTextures; -import com.gregtechceu.gtceu.api.gui.widget.ScrollablePhantomFluidWidget; -import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; import com.gregtechceu.gtceu.api.mui.factory.GuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.BooleanSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.FluidSlotSyncHandler; import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widgets.Dialog; +import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget; +import com.gregtechceu.gtceu.api.mui.widgets.ToggleButton; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Grid; +import com.gregtechceu.gtceu.api.mui.widgets.slot.FluidSlot; import com.gregtechceu.gtceu.api.transfer.fluid.CustomFluidTank; import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; import com.gregtechceu.gtceu.client.mui.screen.UISettings; - -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.gregtechceu.gtceu.common.data.GTItems; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.nbt.CompoundTag; @@ -42,9 +48,17 @@ public class SimpleFluidFilter implements FluidFilter { @Getter protected int maxStackSize = 1; - private CustomFluidTank[] fluidStorageSlots = new CustomFluidTank[9]; + private final CustomFluidTank[] fluidStorageSlots = new CustomFluidTank[9]; protected SimpleFluidFilter() { + for (int i = 0; i < 9; i++) { + int finalI = i; + fluidStorageSlots[i] = new CustomFluidTank(64000); + fluidStorageSlots[i].setOnContentsChanged(() -> { + matches[finalI] = fluidStorageSlots[finalI].getFluid(); + onUpdated.accept(this); + }); + } Arrays.fill(matches, FluidStack.EMPTY); } @@ -60,6 +74,7 @@ private static SimpleFluidFilter loadFilter(CompoundTag tag, Consumer fluidStorageSlots[index].getFluid(), - (fluid) -> fluidStorageSlots[index].setFluid(fluid)) { - - @Override - public void updateScreen() { - super.updateScreen(); - setShowAmount(maxStackSize > 1L); - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - setShowAmount(maxStackSize > 1L); - } - }; - - tank.setChangeListener(() -> { - matches[index] = fluidStorageSlots[index].getFluidInTank(0); - onUpdated.accept(this); - }).setBackground(GuiTextures.SLOT); - - group.addWidget(tank); - } - } - group.addWidget(new ToggleButtonWidget(18 * 3 + 5, 0, 20, 20, - GuiTextures.BUTTON_BLACKLIST, this::isBlackList, this::setBlackList)); - group.addWidget(new ToggleButtonWidget(18 * 3 + 5, 20, 20, 20, - GuiTextures.BUTTON_FILTER_NBT, this::isIgnoreNbt, this::setIgnoreNbt)); - return group; - } - @Override public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { - return null; + for (int i = 0; i < 9; i++) { + syncManager.syncValue("filter_slot_" + i, + new FluidSlotSyncHandler(fluidStorageSlots[i]).controlsAmount(true).phantom(true)); + } + + Grid filterGrid = new Grid() + .coverChildren() + .mapTo(3, 9, i -> new FluidSlot().syncHandler("filter_slot_" + i)); + + BooleanSyncValue blacklist = new BooleanSyncValue(this::isBlackList, this::setBlackList); + syncManager.syncValue("blacklist", blacklist); + + BooleanSyncValue ignoreNBT = new BooleanSyncValue(this::isIgnoreNbt, this::setIgnoreNbt); + syncManager.syncValue("ignoreNBT", ignoreNBT); + + Flow filterConfigButtons = Flow.col() + .coverChildren() + .child(new ToggleButton().stateBackground(GTGuiTextures.BUTTON_BLACKLIST).syncHandler("blacklist")) + .child(new ToggleButton().stateBackground(GTGuiTextures.BUTTON_IGNORE_NBT).syncHandler("ignoreNBT")); + + return new Dialog<>("simple_fluid_filter") + .setDisablePanelsBelow(false) + .setDraggable(true) + .setCloseOnOutOfBoundsClick(true) + .child(GTMuiWidgets.createTitleBar(GTItems.FLUID_FILTER.asStack(), 176, GTGuiTextures.BACKGROUND)) + .child(Flow.row() + .top(10) + .coverChildrenHeight() + .child(filterGrid.horizontalCenter()) + .child(filterConfigButtons.marginLeft(118))) + .child(SlotGroupWidget.playerInventory(false).left(7).bottom(7)); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java index 6377cbad8db..27cad35ac54 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java @@ -1,10 +1,12 @@ package com.gregtechceu.gtceu.api.cover.filter; import com.gregtechceu.gtceu.api.mui.factory.GuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.BooleanSyncValue; import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; import com.gregtechceu.gtceu.api.mui.value.sync.PhantomItemSlotSyncHandler; import com.gregtechceu.gtceu.api.mui.widgets.Dialog; import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget; +import com.gregtechceu.gtceu.api.mui.widgets.ToggleButton; import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; import com.gregtechceu.gtceu.api.mui.widgets.layout.Grid; import com.gregtechceu.gtceu.api.mui.widgets.slot.ModularSlot; @@ -17,8 +19,6 @@ import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.utils.GTUtil; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; - import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; @@ -109,11 +109,6 @@ public void setIgnoreNbt(boolean ingoreNbt) { onUpdated.accept(this); } - @Override - public WidgetGroup openConfigurator(int x, int y) { - return null; - } - @Override public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { FilterItemStackHandler handler = new FilterItemStackHandler(matches, this); @@ -127,6 +122,17 @@ public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISetti handler.setStackInSlot(i, stack); }).ignoreMaxStackSize(true).accessibility(true, false)))); + BooleanSyncValue blacklist = new BooleanSyncValue(this::isBlackList, this::setBlackList); + syncManager.syncValue("blacklist", blacklist); + + BooleanSyncValue ignoreNBT = new BooleanSyncValue(this::isIgnoreNbt, this::setIgnoreNbt); + syncManager.syncValue("ignoreNBT", ignoreNBT); + + Flow filterConfigButtons = Flow.col() + .coverChildren() + .child(new ToggleButton().stateBackground(GTGuiTextures.BUTTON_BLACKLIST).syncHandler("blacklist")) + .child(new ToggleButton().stateBackground(GTGuiTextures.BUTTON_IGNORE_NBT).syncHandler("ignoreNBT")); + return new Dialog<>("simple_item_filter") .setDisablePanelsBelow(false) .setDraggable(true) @@ -135,14 +141,19 @@ public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISetti .child(Flow.row() .top(10) .coverChildrenHeight() - .child(filterGrid.horizontalCenter())) + .child(filterGrid.horizontalCenter()) + .child(filterConfigButtons.marginLeft(118))) .child(SlotGroupWidget.playerInventory(false).left(7).bottom(7)); } - private static class FilterItemStackHandler extends CustomItemStackHandler { + public static class FilterItemStackHandler extends CustomItemStackHandler { - private ItemStack[] matches; - private SimpleItemFilter filter; + private final ItemStack[] matches; + private final SimpleItemFilter filter; + + public FilterItemStackHandler(SimpleItemFilter filter) { + this(filter.matches, filter); + } public FilterItemStackHandler(ItemStack[] matches, SimpleItemFilter simpleItemFilter) { super(matches.length); diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SmartItemFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SmartItemFilter.java index 6767166dd70..f8ad51ce5cc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SmartItemFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SmartItemFilter.java @@ -1,26 +1,38 @@ package com.gregtechceu.gtceu.api.cover.filter; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.drawable.ColorType; +import com.gregtechceu.gtceu.api.mui.drawable.UITexture; import com.gregtechceu.gtceu.api.mui.factory.GuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widgets.Dialog; +import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; import com.gregtechceu.gtceu.client.mui.screen.UISettings; +import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.common.data.GTRecipeTypes; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; +import lombok.Getter; +import java.util.Arrays; import java.util.Collections; import java.util.function.Consumer; @@ -29,6 +41,7 @@ public class SmartItemFilter implements ItemFilter { protected Consumer itemWriter = filter -> {}; protected Consumer onUpdated = filter -> itemWriter.accept(filter); + @Getter private SmartFilteringMode filterMode = SmartFilteringMode.ELECTROLYZER; protected SmartItemFilter() {} @@ -72,17 +85,24 @@ private void setFilterMode(SmartFilteringMode filterMode) { onUpdated.accept(this); } - @Override - public WidgetGroup openConfigurator(int x, int y) { - WidgetGroup group = new WidgetGroup(x, y, 18 * 3 + 25, 18 * 3); - group.addWidget(new EnumSelectorWidget<>(16, 8, 32, 32, - SmartFilteringMode.VALUES, filterMode, this::setFilterMode)); - return group; - } - @Override public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { - return null; + EnumSyncValue mode = new EnumSyncValue<>(SmartFilteringMode.class, + this::getFilterMode, this::setFilterMode); + + syncManager.syncValue("mode", mode); + + return new Dialog<>("smart_item_filter") + .setDisablePanelsBelow(false) + .setDraggable(true) + .setCloseOnOutOfBoundsClick(true) + .child(GTMuiWidgets.createTitleBar(GTItems.SMART_ITEM_FILTER.asStack(), 176, GTGuiTextures.BACKGROUND)) + .child(new GTMuiWidgets.EnumRowBuilder<>(SmartFilteringMode.class) + .value(mode) + .overlay(16, SmartFilteringMode.getTextures()) + .lang(IKey.dynamic(() -> Component.translatable(filterMode.localeName))) + .build().margin(7)) + .child(SlotGroupWidget.playerInventory(false).left(7).bottom(7)); } @Override @@ -143,6 +163,13 @@ public String getTooltip() { return "cover.item_smart_filter.filtering_mode." + localeName; } + public static UITexture[] getTextures() { + return Arrays.stream(VALUES) + .map(v -> UITexture.fullImage(GTCEu.MOD_ID, + "textures/block/machines/" + v.localeName + "/overlay_front.png", ColorType.DEFAULT)) + .toArray(UITexture[]::new); + } + @Override public IGuiTexture getIcon() { return new ResourceTexture("gtceu:textures/block/machines/" + localeName + "/overlay_front.png"); diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFilter.java index 712f8be4a57..2dce613ee5d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFilter.java @@ -1,32 +1,30 @@ package com.gregtechceu.gtceu.api.cover.filter; -import com.gregtechceu.gtceu.api.gui.GuiTextures; -import com.gregtechceu.gtceu.data.lang.LangHandler; +import com.gregtechceu.gtceu.api.mui.factory.GuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.value.sync.StringSyncValue; +import com.gregtechceu.gtceu.api.mui.widgets.Dialog; +import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; +import com.gregtechceu.gtceu.api.mui.widgets.textfield.TextFieldWidget; +import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; +import com.gregtechceu.gtceu.client.mui.screen.RichTooltip; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.utils.TagExprFilter; -import com.lowdragmc.lowdraglib.gui.widget.ImageWidget; -import com.lowdragmc.lowdraglib.gui.widget.TextFieldWidget; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; - import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.item.ItemStack; import lombok.Getter; import java.util.function.Consumer; -import java.util.regex.Pattern; public abstract class TagFilter> implements Filter { - private static final Pattern DOUBLE_WILDCARD = Pattern.compile("\\*{2,}"); - private static final Pattern DOUBLE_AND = Pattern.compile("&{2,}"); - private static final Pattern DOUBLE_OR = Pattern.compile("\\|{2,}"); - private static final Pattern DOUBLE_NOT = Pattern.compile("!{2,}"); - private static final Pattern DOUBLE_XOR = Pattern.compile("\\^{2,}"); - private static final Pattern DOUBLE_SPACE = Pattern.compile(" {2,}"); - @Getter - protected String oreDictFilterExpression = ""; + protected String filterString = ""; protected Consumer itemWriter = filter -> {}; protected Consumer onUpdated = filter -> itemWriter.accept(filter); @@ -37,7 +35,7 @@ protected TagFilter() {} @Override public boolean isBlank() { - return oreDictFilterExpression.isBlank(); + return filterString.isBlank(); } public CompoundTag saveFilter() { @@ -45,78 +43,34 @@ public CompoundTag saveFilter() { return null; } var tag = new CompoundTag(); - tag.putString("oreDict", oreDictFilterExpression); + tag.putString("oreDict", filterString); return tag; } - public void setOreDict(String oreDict) { - this.oreDictFilterExpression = oreDict; - matchExpr = TagExprFilter.parseExpression(oreDictFilterExpression); + public void setFilterString(String filterString) { + this.filterString = filterString; + matchExpr = TagExprFilter.parseExpression(filterString); onUpdated.accept((S) this); } - public WidgetGroup openConfigurator(int x, int y) { - WidgetGroup group = new WidgetGroup(x, y, 18 * 3 + 25, 18 * 3); // 80 55 - group.addWidget(new ImageWidget(0, 0, 20, 20, GuiTextures.INFO_ICON) - .setHoverTooltips( - LangHandler.getMultiLang("cover.tag_filter.info").toArray(new MutableComponent[0]))); - group.addWidget(new TextFieldWidget(0, 29, 18 * 3 + 25, 12, () -> oreDictFilterExpression, this::setOreDict) - .setMaxStringLength(64) - .setValidator(input -> { - // remove all operators that are double - input = DOUBLE_WILDCARD.matcher(input).replaceAll("*"); - input = DOUBLE_AND.matcher(input).replaceAll("&"); - input = DOUBLE_OR.matcher(input).replaceAll("|"); - input = DOUBLE_NOT.matcher(input).replaceAll("!"); - input = DOUBLE_XOR.matcher(input).replaceAll("^"); - input = DOUBLE_SPACE.matcher(input).replaceAll(" "); - // move ( and ) so it doesn't create invalid expressions f.e. xxx (& yyy) => xxx & (yyy) - // append or prepend ( and ) if the amount is not equal - StringBuilder builder = new StringBuilder(); - int unclosed = 0; - char last = ' '; - for (int i = 0; i < input.length(); i++) { - char c = input.charAt(i); - if (c == ' ') { - if (last != '(') - builder.append(" "); - continue; - } - if (c == '(') - unclosed++; - else if (c == ')') { - unclosed--; - if (last == '&' || last == '|' || last == '^') { - int l = builder.lastIndexOf(" " + last); - int l2 = builder.lastIndexOf(String.valueOf(last)); - builder.insert(l == l2 - 1 ? l : l2, ")"); - continue; - } - if (i > 0 && builder.charAt(builder.length() - 1) == ' ') { - builder.deleteCharAt(builder.length() - 1); - } - } else if ((c == '&' || c == '|' || c == '^') && last == '(') { - builder.deleteCharAt(builder.lastIndexOf("(")); - builder.append(c).append(" ("); - continue; - } - - builder.append(c); - last = c; - } - if (unclosed > 0) { - builder.append(")".repeat(unclosed)); - } else if (unclosed < 0) { - unclosed = -unclosed; - for (int i = 0; i < unclosed; i++) { - builder.insert(0, "("); - } - } - input = builder.toString(); - input = input.replaceAll(" {2,}", " "); - return input; - })); - return group; + protected abstract ItemStack getFilterItem(); + + @Override + public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { + StringSyncValue filterString = new StringSyncValue(this::getFilterString, this::setFilterString); + RichTooltip infoTooltip = new RichTooltip().addMultiLine("cover.tag_filter.info"); + + var inputRow = Flow.row().margin(7).coverChildren().horizontalCenter() + .child(new TextFieldWidget().width(140).value(filterString)) + .child(GTGuiTextures.INFO.asWidget().tooltip(infoTooltip)); + + return new Dialog<>("tag_filter") + .setDisablePanelsBelow(false) + .setDraggable(true) + .setCloseOnOutOfBoundsClick(true) + .child(GTMuiWidgets.createTitleBar(getFilterItem(), 176, GTGuiTextures.BACKGROUND)) + .child(inputRow) + .child(SlotGroupWidget.playerInventory(false).left(7).bottom(7)); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFluidFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFluidFilter.java index b1efbc4d2a4..014a14e0898 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFluidFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagFluidFilter.java @@ -1,9 +1,6 @@ package com.gregtechceu.gtceu.api.cover.filter; -import com.gregtechceu.gtceu.api.mui.factory.GuiData; -import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; -import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; -import com.gregtechceu.gtceu.client.mui.screen.UISettings; +import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.utils.TagExprFilter; import net.minecraft.nbt.CompoundTag; @@ -31,21 +28,26 @@ public static TagFluidFilter loadFilter(ItemStack itemStack) { private static TagFluidFilter loadFilter(CompoundTag tag, Consumer itemWriter) { var handler = new TagFluidFilter(); handler.itemWriter = itemWriter; - handler.oreDictFilterExpression = tag.getString("oreDict"); + handler.filterString = tag.getString("oreDict"); handler.matchExpr = null; handler.cache.clear(); - handler.matchExpr = TagExprFilter.parseExpression(handler.oreDictFilterExpression); + handler.matchExpr = TagExprFilter.parseExpression(handler.filterString); return handler; } - public void setOreDict(String oreDict) { + public void setFilterString(String oreDict) { cache.clear(); - super.setOreDict(oreDict); + super.setFilterString(oreDict); + } + + @Override + protected ItemStack getFilterItem() { + return GTItems.TAG_FLUID_FILTER.asStack(); } @Override public boolean test(FluidStack fluidStack) { - if (oreDictFilterExpression.isEmpty()) return false; + if (filterString.isEmpty()) return false; if (cache.containsKey(fluidStack.getFluid())) return cache.getOrDefault(fluidStack.getFluid(), false); if (TagExprFilter.tagsMatch(matchExpr, fluidStack)) { cache.put(fluidStack.getFluid(), true); @@ -64,9 +66,4 @@ public int testFluidAmount(FluidStack fluidStack) { public boolean supportsAmounts() { return false; } - - @Override - public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { - return null; - } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagItemFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagItemFilter.java index 5b97382b282..e33eca3e7df 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagItemFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/TagItemFilter.java @@ -1,9 +1,6 @@ package com.gregtechceu.gtceu.api.cover.filter; -import com.gregtechceu.gtceu.api.mui.factory.GuiData; -import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; -import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; -import com.gregtechceu.gtceu.client.mui.screen.UISettings; +import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.utils.TagExprFilter; import net.minecraft.nbt.CompoundTag; @@ -30,21 +27,26 @@ public static TagItemFilter loadFilter(ItemStack itemStack) { private static TagItemFilter loadFilter(CompoundTag tag, Consumer itemWriter) { var handler = new TagItemFilter(); handler.itemWriter = itemWriter; - handler.oreDictFilterExpression = tag.getString("oreDict"); + handler.filterString = tag.getString("oreDict"); handler.matchExpr = null; handler.cache.clear(); - handler.matchExpr = TagExprFilter.parseExpression(handler.oreDictFilterExpression); + handler.matchExpr = TagExprFilter.parseExpression(handler.filterString); return handler; } - public void setOreDict(String oreDict) { + public void setFilterString(String oreDict) { cache.clear(); - super.setOreDict(oreDict); + super.setFilterString(oreDict); + } + + @Override + protected ItemStack getFilterItem() { + return GTItems.TAG_FILTER.asStack(); } @Override public boolean test(ItemStack itemStack) { - if (oreDictFilterExpression.isEmpty()) return false; + if (filterString.isEmpty()) return false; if (cache.containsKey(itemStack.getItem())) return cache.getOrDefault(itemStack.getItem(), false); if (TagExprFilter.tagsMatch(matchExpr, itemStack)) { cache.put(itemStack.getItem(), true); @@ -63,9 +65,4 @@ public int testItemCount(ItemStack itemStack) { public boolean supportsAmounts() { return false; } - - @Override - public ModularPanel getPanel(GuiData data, PanelSyncManager syncManager, UISettings settings) { - return null; - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java index 937ef7f88a5..7378ff2660f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java @@ -11,31 +11,19 @@ import com.gregtechceu.gtceu.api.machine.ConditionalSubscriptionHandler; import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; -import com.gregtechceu.gtceu.api.mui.utils.Alignment; -import com.gregtechceu.gtceu.api.mui.utils.Color; -import com.gregtechceu.gtceu.api.mui.utils.MouseData; import com.gregtechceu.gtceu.api.mui.value.sync.*; -import com.gregtechceu.gtceu.api.mui.widget.EmptyWidget; import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; -import com.gregtechceu.gtceu.api.mui.widgets.ButtonWidget; -import com.gregtechceu.gtceu.api.mui.widgets.DynamicSyncedWidget; -import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget; import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; -import com.gregtechceu.gtceu.api.mui.widgets.slot.ItemSlot; -import com.gregtechceu.gtceu.api.mui.widgets.slot.ModularSlot; -import com.gregtechceu.gtceu.api.mui.widgets.textfield.TextFieldWidget; import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.item.ItemHandlerDelegate; -import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; import com.gregtechceu.gtceu.common.cover.data.DistributionMode; import com.gregtechceu.gtceu.common.cover.data.ManualIOMode; import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; import com.gregtechceu.gtceu.common.mui.GTGuiTextures; -import com.gregtechceu.gtceu.common.mui.GTGuis; import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.GTUtil; import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; @@ -49,7 +37,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.Mth; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraftforge.items.IItemHandler; @@ -435,18 +422,6 @@ public boolean shouldRespectDistributionMode() { // *********** GUI ***********// ////////////////////////////////////// - @Override - public ModularPanel buildUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { - ModularPanel panel = GTGuis.createPanel(this, 176, 192 + 18); - - panel.child(GTMuiWidgets.createTitleBar(this.self().getAttachItem(), 176, GTGuiTextures.BACKGROUND)); - - return panel.child(createCoverUI(data, syncManager, settings)) - .child(SlotGroupWidget.playerInventory(false).left(7).bottom(7)); - - // return IMuiCover.super.buildUI(data, syncManager, settings); - } - @Override public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { Flow column = Flow.column() @@ -460,86 +435,28 @@ public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager sync this::getDistributionMode, this::setDistributionMode); IntSyncValue transferRate = new IntSyncValue(this::getTransferRate, this::setTransferRate); - StringSyncValue formattedTransferRate = new StringSyncValue(transferRate::getStringValue, - transferRate::setStringValue); + EnumSyncValue ioSync = new EnumSyncValue<>(IO.class, this::getIo, this::setIo); syncManager.syncValue("manualMode", manualMode); syncManager.syncValue("distribution", distMode); syncManager.syncValue("throughput", transferRate); + syncManager.syncValue("io", ioSync); if (createThroughputRow()) { - column.child(Flow.row() - .coverChildrenHeight() - .marginBottom(2) - .widthRel(1.0f) - .child(new ButtonWidget<>() - .left(0).width(18) - .onMousePressed((x, y, button) -> { - int val = transferRate.getIntValue() - getIncrementValue(MouseData.create(button)); - val = Mth.clamp(val, 1, maxItemTransferRate); - transferRate.setIntValue(val, true, true); - return true; - }) - .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) - .child(new TextFieldWidget() - .left(18).right(18) - .setTextAlignment(Alignment.Center) - .setTextColor(Color.WHITE.darker(1)) - .setNumbers(1, maxItemTransferRate) - .onMouseScrolled((mouseX, mouseY, delta) -> { - int inc = (int) delta * getIncrementValue(MouseData.create(-1)); - int val = Mth.clamp(transferRate.getIntValue() + inc, 1, maxItemTransferRate); - transferRate.setIntValue(val, true, true); - return true; - }) - .value(formattedTransferRate) - .background(GTGuiTextures.DISPLAY)) - .child(new ButtonWidget<>() - .right(0).width(18) - .onMousePressed((x, y, button) -> { - int val = transferRate.getIntValue() + getIncrementValue(MouseData.create(button)); - val = Mth.clamp(val, 1, maxItemTransferRate); - transferRate.setIntValue(val, true, true); - return true; - }) - .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); + column.child(GTMuiWidgets.createIntInputWithButtons(transferRate, 1, maxItemTransferRate)); } if (createFilterRow()) { - var filterSlot = filterHandler.getFilterSlot(); - // TODO get the panel to use the right sync handler when swapping from one item filter to the next - var panelHandler = syncManager.syncedPanel("filterPanel", true, - (sm, sh) -> ItemFilter.loadFilter(filterSlot.getStackInSlot(0)).getPanel(data, sm, settings)); - - DynamicSyncHandler filterButton = new DynamicSyncHandler() - .widgetProvider((sm, buf) -> { - ItemStack stack = buf.readItem(); - if (stack.isEmpty()) return new EmptyWidget(); - stack = filterSlot.getStackInSlot(0); - ItemFilter filter = ItemFilter.loadFilter(stack); - - return new ButtonWidget<>() - .onMousePressed((x, y, b) -> { - panelHandler.openPanel(); - return true; - }); - }); - - column.child(Flow.row() - .coverChildrenHeight() - .child(new ItemSlot() - .slot(new ModularSlot(filterSlot, 0) - .changeListener((stack, amount, client, init) -> { - filterButton.notifyUpdate(packet -> packet.writeItem(stack)); - })) - .marginRight(4)) - .child(new DynamicSyncedWidget<>().syncHandler(filterButton))); + column.child( + GTMuiWidgets.createFilterRow(filterHandler, ItemFilter::loadFilter, data, syncManager, settings) + .child(0, GTMuiWidgets.createIOCycleButton(ioSync, false).marginRight(2)) + .marginBottom(2)); } if (createConveyorIORow()) {} if (createDistributionModeRow()) { - column.child(new EnumRowBuilder<>(DistributionMode.class) + column.child(new GTMuiWidgets.EnumRowBuilder<>(DistributionMode.class) .value(distMode) .overlay(16, GTGuiTextures.DISTRIBUTION_MODE_OVERLAY) .lang(IKey.dynamic(() -> Component.translatable(distributionMode.localeName))) @@ -547,7 +464,7 @@ public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager sync } if (createManualIOModeRow()) { - column.child(new EnumRowBuilder<>(ManualIOMode.class) + column.child(new GTMuiWidgets.EnumRowBuilder<>(ManualIOMode.class) .value(manualMode) .overlay(16, GTGuiTextures.MANUAL_IO_OVERLAY_IN) .lang(IKey.dynamic(() -> Component.translatable(manualIOMode.localeName))) @@ -578,49 +495,6 @@ protected boolean createManualIOModeRow() { return true; } - /* - * @Override - * public Widget createUIWidget() { - * final var group = new WidgetGroup(0, 0, 176, 137); - * group.addWidget(new LabelWidget(10, 5, Component.translatable(getUITitle(), GTValues.VN[tier]).getString())); - * - * group.addWidget(new IntInputWidget(10, 20, 156, 20, () -> this.transferRate, this::setTransferRate) - * .setMin(1).setMax(maxItemTransferRate)); - * - * final EnumSelectorWidget distributionSelector = new EnumSelectorWidget<>(146, 67, 20, 20, - * DistributionMode.values(), distributionMode, this::setDistributionMode); - * - * distributionSelector.setVisible(shouldRespectDistributionMode()); - * group.addWidget(distributionSelector); - * - * ioModeSwitch = new SwitchWidget(10, 45, 20, 20, - * (clickData, value) -> { - * setIo(value ? IO.IN : IO.OUT); - * distributionSelector.setVisible(shouldRespectDistributionMode()); - * ioModeSwitch.setHoverTooltips( - * LocalizationUtils.format("cover.conveyor.mode", LocalizationUtils.format(io.tooltip))); - * }) - * .setTexture( - * new GuiTextureGroup(GuiTextures.VANILLA_BUTTON, IO.OUT.icon), - * new GuiTextureGroup(GuiTextures.VANILLA_BUTTON, IO.IN.icon)) - * .setPressed(io == IO.IN) - * .setHoverTooltips( - * LocalizationUtils.format("cover.conveyor.mode", LocalizationUtils.format(io.tooltip))); - * group.addWidget(ioModeSwitch); - * - * group.addWidget(new EnumSelectorWidget<>(146, 107, 20, 20, - * ManualIOMode.VALUES, manualIOMode, this::setManualIOMode) - * .setHoverTooltips("cover.universal.manual_import_export.mode.description")); - * - * group.addWidget(filterHandler.createFilterSlotUI(125, 108)); - * group.addWidget(filterHandler.createFilterConfigUI(10, 72, 156, 60)); - * - * buildAdditionalUI(group); - * - * return group; - * } - */ - @NotNull protected String getUITitle() { return "cover.conveyor.title"; diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java index 1c75ae521c8..cf4f77e9e3e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java @@ -3,23 +3,31 @@ import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.cover.CoverBehavior; import com.gregtechceu.gtceu.api.cover.CoverDefinition; -import com.gregtechceu.gtceu.api.cover.IUICover; +import com.gregtechceu.gtceu.api.cover.IMuiCover; import com.gregtechceu.gtceu.api.cover.filter.FluidFilter; -import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.DynamicSyncHandler; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; +import com.gregtechceu.gtceu.api.mui.widgets.ButtonWidget; +import com.gregtechceu.gtceu.api.mui.widgets.DynamicSyncedWidget; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.fluid.FluidHandlerDelegate; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.data.FilterMode; import com.gregtechceu.gtceu.common.cover.data.ManualIOMode; - -import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; -import com.lowdragmc.lowdraglib.gui.widget.Widget; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; @@ -32,7 +40,7 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class FluidFilterCover extends CoverBehavior implements IUICover { +public class FluidFilterCover extends CoverBehavior implements IMuiCover { protected FluidFilter fluidFilter; @SaveField @@ -80,14 +88,47 @@ public FluidFilter getFluidFilter() { } @Override - public Widget createUIWidget() { - final var group = new WidgetGroup(0, 0, 178, 85); - group.addWidget(new LabelWidget(60, 5, attachItem.getDescriptionId())); - group.addWidget(new EnumSelectorWidget<>(35, 25, 18, 18, - FilterMode.VALUES, filterMode, this::setFilterMode)); - group.addWidget(new EnumSelectorWidget<>(35, 45, 18, 18, ManualIOMode.VALUES, allowFlow, this::setAllowFlow)); - group.addWidget(getFluidFilter().openConfigurator(62, 25)); - return group; + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + Flow column = Flow.column() + .top(7).margin(7, 0) + .widthRel(1.0f).coverChildrenHeight(); + + EnumSyncValue filterMode = new EnumSyncValue<>(FilterMode.class, + this::getFilterMode, this::setFilterMode); + + EnumSyncValue ioMode = new EnumSyncValue<>(ManualIOMode.class, + this::getAllowFlow, this::setAllowFlow); + + syncManager.syncValue("filterMode", filterMode); + syncManager.syncValue("ioMode", ioMode); + + var panelHandler = syncManager.syncedPanel("filterPanel", true, + (sm, sh) -> fluidFilter.getPanel(data, sm, settings)); + + DynamicSyncHandler filterButton = new DynamicSyncHandler() + .widgetProvider((sm, buf) -> new ButtonWidget<>() + .onMousePressed((x, y, b) -> { + panelHandler.openPanel(); + return true; + })); + + column.child(Flow.row() + .coverChildrenHeight() + .child(new DynamicSyncedWidget<>().syncHandler(filterButton))); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(FilterMode.class) + .value(filterMode) + .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) + .lang(IKey.dynamic(() -> Component.translatable(getFilterMode().getTooltip()))) + .build()); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(ManualIOMode.class) + .value(ioMode) + .overlay(16, GTGuiTextures.MANUAL_IO_OVERLAY_IN) + .lang(IKey.dynamic(() -> Component.translatable(getAllowFlow().getTooltip()))) + .build()); + + return column; } private class FilteredFluidHandlerWrapper extends FluidHandlerDelegate { diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/FluidRegulatorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/FluidRegulatorCover.java index 0e63eb3cd2a..3675a70ba35 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/FluidRegulatorCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/FluidRegulatorCover.java @@ -4,26 +4,32 @@ import com.gregtechceu.gtceu.api.cover.CoverDefinition; import com.gregtechceu.gtceu.api.cover.filter.FluidFilter; import com.gregtechceu.gtceu.api.cover.filter.SimpleFluidFilter; -import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; -import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; -import com.gregtechceu.gtceu.api.gui.widget.NumberInputWidget; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.data.BucketMode; import com.gregtechceu.gtceu.common.cover.data.TransferMode; - -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.NotNull; import javax.annotation.ParametersAreNonnullByDefault; @@ -46,12 +52,10 @@ public class FluidRegulatorCover extends PumpCover { @SaveField @SyncToClient @Getter + @Setter protected int globalTransferLimit; protected int fluidTransferBuffered = 0; - private NumberInputWidget transferSizeInput; - private EnumSelectorWidget transferBucketModeInput; - public FluidRegulatorCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide, int tier, int maxTransferRate) { super(definition, coverHolder, attachedSide, tier, maxTransferRate); @@ -154,27 +158,13 @@ private int keepExact(IFluidHandlerModifiable source, IFluidHandlerModifiable de } private void setTransferBucketMode(BucketMode transferBucketMode) { - var oldMultiplier = this.transferBucketMode.multiplier; - var newMultiplier = transferBucketMode.multiplier; - this.transferBucketMode = transferBucketMode; syncDataHolder.markClientSyncFieldDirty("transferBucketMode"); - if (transferSizeInput == null) return; - - if (oldMultiplier > newMultiplier) { - transferSizeInput.setValue(getCurrentBucketModeTransferSize()); - } - this.transferSizeInput.setMax(MAX_STACK_SIZE / this.transferBucketMode.multiplier); - if (newMultiplier > oldMultiplier) { - transferSizeInput.setValue(getCurrentBucketModeTransferSize()); - } } private void setTransferMode(TransferMode transferMode) { this.transferMode = transferMode; - configureTransferSizeInput(); - if (!this.isRemote()) { syncDataHolder.markClientSyncFieldDirty("transferMode"); configureFilter(); @@ -186,8 +176,6 @@ protected void configureFilter() { if (filterHandler.getFilter() instanceof SimpleFluidFilter filter) { filter.setMaxStackSize(transferMode == TransferMode.TRANSFER_ANY ? 1 : MAX_STACK_SIZE); } - - configureTransferSizeInput(); } private int getFilteredFluidAmount(FluidStack fluidStack) { @@ -208,37 +196,29 @@ private int getFilteredFluidAmount(FluidStack fluidStack) { } @Override - protected void buildAdditionalUI(WidgetGroup group) { - group.addWidget( - new EnumSelectorWidget<>(146, 45, 20, 20, TransferMode.values(), transferMode, this::setTransferMode)); - - this.transferSizeInput = new IntInputWidget(35, 45, 84, 20, - this::getCurrentBucketModeTransferSize, this::setCurrentBucketModeTransferSize).setMin(0) - .setMax(Integer.MAX_VALUE); - configureTransferSizeInput(); - group.addWidget(this.transferSizeInput); - - this.transferBucketModeInput = new EnumSelectorWidget<>(121, 45, 20, 20, BucketMode.values(), - transferBucketMode, this::setTransferBucketMode); - group.addWidget(this.transferBucketModeInput); - } + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + var column = super.createCoverUI(data, syncManager, settings); - private int getCurrentBucketModeTransferSize() { - return this.globalTransferLimit / this.transferBucketMode.multiplier; - } + var transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); + var transferSize = new IntSyncValue(this::getGlobalTransferLimit, this::setGlobalTransferLimit); + var transferBucketMode = new EnumSyncValue<>(BucketMode.class, this::getTransferBucketMode, + this::setTransferBucketMode); - private void setCurrentBucketModeTransferSize(int transferSize) { - this.globalTransferLimit = Math.min(Math.max(transferSize * this.transferBucketMode.multiplier, 0), - MAX_STACK_SIZE); - syncDataHolder.markClientSyncFieldDirty("globalTransferLimit"); - } + syncManager.syncValue("transferMode", transferMode); + syncManager.syncValue("transferSize", transferSize); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(TransferMode.class) + .value(transferMode) + .overlay(16, GTGuiTextures.TRANSFER_MODE_OVERLAY) + .lang(IKey.dynamic(() -> Component.translatable(getTransferMode().tooltip))) + .build()); + + column.child(GTMuiWidgets.createIntInputWithBucketMode(transferSize, transferBucketMode, maxFluidTransferRate)); - private void configureTransferSizeInput() { - if (this.transferSizeInput == null || transferBucketModeInput == null) - return; + column.child(GTMuiWidgets.createIntInputWithButtons(transferSize, 1, MAX_STACK_SIZE) + .setEnabledIf($ -> shouldShowTransferSize())); - this.transferSizeInput.setVisible(shouldShowTransferSize()); - this.transferBucketModeInput.setVisible(shouldShowTransferSize()); + return column; } private boolean shouldShowTransferSize() { diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java index 06e6e200e06..89e311cc256 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java @@ -3,25 +3,33 @@ import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.cover.CoverBehavior; import com.gregtechceu.gtceu.api.cover.CoverDefinition; -import com.gregtechceu.gtceu.api.cover.IUICover; +import com.gregtechceu.gtceu.api.cover.IMuiCover; import com.gregtechceu.gtceu.api.cover.filter.ItemFilter; import com.gregtechceu.gtceu.api.cover.filter.SmartItemFilter; -import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; import com.gregtechceu.gtceu.api.machine.MachineCoverContainer; import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.DynamicSyncHandler; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; +import com.gregtechceu.gtceu.api.mui.widgets.ButtonWidget; +import com.gregtechceu.gtceu.api.mui.widgets.DynamicSyncedWidget; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.item.ItemHandlerDelegate; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.data.FilterMode; import com.gregtechceu.gtceu.common.cover.data.ManualIOMode; - -import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; -import com.lowdragmc.lowdraglib.gui.widget.Widget; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; import net.minecraftforge.items.IItemHandlerModifiable; @@ -35,7 +43,7 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class ItemFilterCover extends CoverBehavior implements IUICover { +public class ItemFilterCover extends CoverBehavior implements IMuiCover { protected ItemFilter itemFilter; @SaveField @@ -90,14 +98,47 @@ public void onAttached(ItemStack itemStack, @Nullable ServerPlayer player) { } @Override - public Widget createUIWidget() { - final var group = new WidgetGroup(0, 0, 178, 85); - group.addWidget(new LabelWidget(60, 5, attachItem.getDescriptionId())); - group.addWidget(new EnumSelectorWidget<>(35, 25, 18, 18, - FilterMode.VALUES, filterMode, this::setFilterMode)); - group.addWidget(new EnumSelectorWidget<>(35, 45, 18, 18, ManualIOMode.VALUES, allowFlow, this::setAllowFlow)); - group.addWidget(getItemFilter().openConfigurator(62, 25)); - return group; + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + Flow column = Flow.column() + .top(7).margin(7, 0) + .widthRel(1.0f).coverChildrenHeight(); + + EnumSyncValue filterMode = new EnumSyncValue<>(FilterMode.class, + this::getFilterMode, this::setFilterMode); + + EnumSyncValue ioMode = new EnumSyncValue<>(ManualIOMode.class, + this::getAllowFlow, this::setAllowFlow); + + syncManager.syncValue("filterMode", filterMode); + syncManager.syncValue("ioMode", ioMode); + + var panelHandler = syncManager.syncedPanel("filterPanel", true, + (sm, sh) -> itemFilter.getPanel(data, sm, settings)); + + DynamicSyncHandler filterButton = new DynamicSyncHandler() + .widgetProvider((sm, buf) -> new ButtonWidget<>() + .onMousePressed((x, y, b) -> { + panelHandler.openPanel(); + return true; + })); + + column.child(Flow.row() + .coverChildrenHeight() + .child(new DynamicSyncedWidget<>().syncHandler(filterButton))); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(FilterMode.class) + .value(filterMode) + .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) + .lang(IKey.dynamic(() -> Component.translatable(getFilterMode().getTooltip()))) + .build()); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(ManualIOMode.class) + .value(ioMode) + .overlay(16, GTGuiTextures.MANUAL_IO_OVERLAY_IN) + .lang(IKey.dynamic(() -> Component.translatable(getAllowFlow().name()))) + .build()); + + return column; } private class FilteredItemHandlerWrapper extends ItemHandlerDelegate { diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java index 0ebbe5b88cb..02ff7d57492 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java @@ -4,29 +4,32 @@ import com.gregtechceu.gtceu.api.capability.IControllable; import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.cover.CoverBehavior; -import com.gregtechceu.gtceu.api.cover.CoverDefinition; -import com.gregtechceu.gtceu.api.cover.IIOCover; -import com.gregtechceu.gtceu.api.cover.IUICover; +import com.gregtechceu.gtceu.api.cover.*; import com.gregtechceu.gtceu.api.cover.filter.FilterHandler; import com.gregtechceu.gtceu.api.cover.filter.FilterHandlers; import com.gregtechceu.gtceu.api.cover.filter.FluidFilter; -import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; -import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; import com.gregtechceu.gtceu.api.gui.widget.NumberInputWidget; import com.gregtechceu.gtceu.api.machine.ConditionalSubscriptionHandler; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.fluid.FluidHandlerDelegate; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.api.transfer.fluid.ModifiableFluidHandlerWrapper; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.data.BucketMode; import com.gregtechceu.gtceu.common.cover.data.ManualIOMode; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.utils.GTTransferUtils; -import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; -import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import net.minecraft.MethodsReturnNonnullByDefault; @@ -47,14 +50,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.List; import javax.annotation.ParametersAreNonnullByDefault; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class PumpCover extends CoverBehavior implements IIOCover, IUICover, IControllable { +public class PumpCover extends CoverBehavior implements IIOCover, IMuiCover, IControllable { // .5b 2b 8b public static final Int2IntFunction PUMP_SCALING = tier -> 64 * (int) Math.pow(4, Math.min(tier - 1, GTValues.IV)); @@ -184,22 +186,8 @@ public void setTransferRate(int milliBucketsPerTick) { } public void setBucketMode(BucketMode bucketMode) { - var oldMultiplier = this.bucketMode.multiplier; - var newMultiplier = bucketMode.multiplier; - this.bucketMode = bucketMode; syncDataHolder.markClientSyncFieldDirty("bucketMode"); - if (transferRateWidget == null) return; - - if (oldMultiplier > newMultiplier) { - transferRateWidget.setValue(getCurrentBucketModeTransferRate()); - } - - transferRateWidget.setMax(maxFluidTransferRate / bucketMode.multiplier); - - if (newMultiplier > oldMultiplier) { - transferRateWidget.setValue(getCurrentBucketModeTransferRate()); - } } protected void setManualIOMode(ManualIOMode manualIOMode) { @@ -284,45 +272,34 @@ private static boolean canTransfer(IFluidHandlerModifiable fluidHandler, Transfe ////////////////////////////////////// @Override - public Widget createUIWidget() { - final var group = new WidgetGroup(0, 0, 176, 137); - group.addWidget(new LabelWidget(10, 5, Component.translatable(getUITitle(), GTValues.VN[tier]).getString())); - - transferRateWidget = new IntInputWidget(10, 20, 134, 20, - this::getCurrentBucketModeTransferRate, this::setCurrentBucketModeTransferRate).setMin(0); - setBucketMode(this.bucketMode); // initial input widget config happens here - group.addWidget(transferRateWidget); - - group.addWidget(new EnumSelectorWidget<>( - 146, 20, 20, 20, - Arrays.stream(BucketMode.values()).filter(m -> m.multiplier <= maxFluidTransferRate).toList(), - bucketMode, this::setBucketMode).setTooltipSupplier(this::getBucketModeTooltip)); - - group.addWidget(new EnumSelectorWidget<>(10, 45, 20, 20, List.of(IO.IN, IO.OUT), io, this::setIo)); - - group.addWidget(new EnumSelectorWidget<>(146, 107, 20, 20, - ManualIOMode.VALUES, manualIOMode, this::setManualIOMode) - .setHoverTooltips("cover.universal.manual_import_export.mode.description")); - - group.addWidget(filterHandler.createFilterSlotUI(125, 108)); - group.addWidget(filterHandler.createFilterConfigUI(10, 72, 156, 60)); - - buildAdditionalUI(group); - - return group; - } - - private List getBucketModeTooltip(BucketMode mode, String langKey) { - return List.of( - Component.translatable(langKey).append(Component.translatable("gtceu.gui.content.units.per_tick"))); - } - - private int getCurrentBucketModeTransferRate() { - return this.transferRate / this.bucketMode.multiplier; - } - - private void setCurrentBucketModeTransferRate(int transferRate) { - this.setTransferRate(transferRate * this.bucketMode.multiplier); + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + Flow column = Flow.column() + .top(7).margin(7, 0) + .widthRel(1.0f).coverChildrenHeight(); + + IntSyncValue transferRateSync = new IntSyncValue(this::getTransferRate, this::setTransferRate); + EnumSyncValue bucketModeSync = new EnumSyncValue<>(BucketMode.class, this::getBucketMode, + this::setBucketMode); + EnumSyncValue ioSync = new EnumSyncValue<>(IO.class, this::getIo, this::setIo); + EnumSyncValue manualIOModeSync = new EnumSyncValue<>(ManualIOMode.class, this::getManualIOMode, + this::setManualIOMode); + + syncManager.syncValue("transferRate", transferRateSync); + syncManager.syncValue("io", ioSync); + syncManager.syncValue("manualIO", manualIOModeSync); + + column.child(GTMuiWidgets.createIntInputWithBucketMode(transferRateSync, bucketModeSync, maxFluidTransferRate)); + + column.child(GTMuiWidgets.createFilterRow(filterHandler, FluidFilter::loadFilter, data, syncManager, settings) + .child(0, GTMuiWidgets.createIOCycleButton(ioSync, false).marginRight(2)).marginBottom(2)); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(ManualIOMode.class) + .value(manualIOModeSync) + .overlay(16, GTGuiTextures.MANUAL_IO_OVERLAY_IN) + .lang(IKey.dynamic(() -> Component.translatable(manualIOMode.localeName))) + .build()); + + return column; } @NotNull diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java index 911438c8d0f..8ae5f665e5b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java @@ -7,9 +7,18 @@ import com.gregtechceu.gtceu.api.cover.filter.SimpleItemFilter; import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.data.TransferMode; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.common.pipelike.item.ItemNetHandler; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; @@ -17,6 +26,7 @@ import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; import net.minecraftforge.items.IItemHandler; @@ -165,6 +175,28 @@ protected String getUITitle() { return "cover.robotic_arm.title"; } + @Override + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + var column = super.createCoverUI(data, syncManager, settings); + + var transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); + var transferSize = new IntSyncValue(this::getGlobalTransferLimit, this::setGlobalTransferLimit); + + syncManager.syncValue("transferMode", transferMode); + syncManager.syncValue("transferSize", transferSize); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(TransferMode.class) + .value(transferMode) + .overlay(16, GTGuiTextures.TRANSFER_MODE_OVERLAY) + .lang(IKey.dynamic(() -> Component.translatable(getTransferMode().tooltip))) + .build()); + + column.child(GTMuiWidgets.createIntInputWithButtons(transferSize, 1, getTransferMode().maxStackSize) + .setEnabledIf($ -> shouldShowStackSize())); + + return column; + } + @Override protected void buildAdditionalUI(WidgetGroup group) { group.addWidget( diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/data/BucketMode.java b/src/main/java/com/gregtechceu/gtceu/common/cover/data/BucketMode.java index 1768c4e28ff..4fefeac804c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/data/BucketMode.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/data/BucketMode.java @@ -1,27 +1,27 @@ package com.gregtechceu.gtceu.common.cover.data; -import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.mui.drawable.UITexture; -import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; +import net.minecraft.resources.ResourceLocation; import lombok.Getter; -public enum BucketMode implements EnumSelectorWidget.SelectableEnum { +public enum BucketMode { - BUCKET("cover.bucket.mode.bucket", "minecraft:textures/item/water_bucket", 1000), - MILLI_BUCKET("cover.bucket.mode.milli_bucket", "gtceu:textures/gui/icon/bucket_mode/water_drop", 1); + BUCKET("cover.bucket.mode.bucket", new ResourceLocation("minecraft", "textures/item/water_bucket"), 1000), + MILLI_BUCKET("cover.bucket.mode.milli_bucket", GTCEu.id("textures/gui/icon/bucket_mode/water_drop"), 1); @Getter public final String tooltip; @Getter - public final IGuiTexture icon; + public final UITexture icon; public final int multiplier; - BucketMode(String tooltip, String textureName, int multiplier) { + BucketMode(String tooltip, ResourceLocation texture, int multiplier) { this.tooltip = tooltip; - this.icon = new ResourceTexture(textureName + ".png").scale(16F / 20F); + this.icon = UITexture.fullImage(texture); this.multiplier = multiplier; } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedFluidVoidingCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedFluidVoidingCover.java index ffbf5b60de0..2bd46895958 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedFluidVoidingCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedFluidVoidingCover.java @@ -4,27 +4,33 @@ import com.gregtechceu.gtceu.api.cover.CoverDefinition; import com.gregtechceu.gtceu.api.cover.filter.FluidFilter; import com.gregtechceu.gtceu.api.cover.filter.SimpleFluidFilter; -import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; -import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; -import com.gregtechceu.gtceu.api.gui.widget.NumberInputWidget; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.data.BucketMode; import com.gregtechceu.gtceu.common.cover.data.VoidingMode; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.utils.GTMath; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; - import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import it.unimi.dsi.fastutil.objects.Object2LongMaps; import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.NotNull; import javax.annotation.ParametersAreNonnullByDefault; @@ -41,15 +47,13 @@ public class AdvancedFluidVoidingCover extends FluidVoidingCover { @SaveField @SyncToClient @Getter + @Setter protected int globalTransferSizeMillibuckets = 1; @SaveField @SyncToClient @Getter private BucketMode transferBucketMode = BucketMode.MILLI_BUCKET; - private NumberInputWidget stackSizeInput; - private EnumSelectorWidget stackSizeBucketModeInput; - public AdvancedFluidVoidingCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) { super(definition, coverHolder, attachedSide); } @@ -99,7 +103,6 @@ private int getFilteredFluidAmount(FluidStack fluidStack) { public void setVoidingMode(VoidingMode voidingMode) { this.voidingMode = voidingMode; syncDataHolder.markClientSyncFieldDirty("voidingMode"); - configureStackSizeInput(); if (!this.isRemote()) { configureFilter(); @@ -109,9 +112,6 @@ public void setVoidingMode(VoidingMode voidingMode) { private void setTransferBucketMode(BucketMode transferBucketMode) { this.transferBucketMode = transferBucketMode; syncDataHolder.markClientSyncFieldDirty("transferBucketMode"); - - if (stackSizeInput == null) return; - stackSizeInput.setValue(getCurrentBucketModeTransferSize()); } ////////////////////////////////////// @@ -124,19 +124,31 @@ private void setTransferBucketMode(BucketMode transferBucketMode) { } @Override - protected void buildAdditionalUI(WidgetGroup group) { - group.addWidget( - new EnumSelectorWidget<>(146, 20, 20, 20, VoidingMode.values(), voidingMode, this::setVoidingMode)); - - this.stackSizeInput = new IntInputWidget(35, 20, 84, 20, - this::getCurrentBucketModeTransferSize, this::setCurrentBucketModeTransferSize).setMin(1) - .setMax(Integer.MAX_VALUE); - configureStackSizeInput(); - group.addWidget(this.stackSizeInput); - - this.stackSizeBucketModeInput = new EnumSelectorWidget<>(121, 20, 20, 20, BucketMode.values(), - transferBucketMode, this::setTransferBucketMode); - group.addWidget(this.stackSizeBucketModeInput); + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + var column = super.createCoverUI(data, syncManager, settings); + + EnumSyncValue voidingMode = new EnumSyncValue<>(VoidingMode.class, + this::getVoidingMode, this::setVoidingMode); + IntSyncValue voidingLimit = new IntSyncValue(this::getGlobalTransferSizeMillibuckets, + this::setGlobalTransferSizeMillibuckets); + EnumSyncValue bucketModeSync = new EnumSyncValue<>(BucketMode.class, this::getBucketMode, + this::setBucketMode); + + syncManager.syncValue("voidingMode", voidingMode); + syncManager.syncValue("voidingLimit", voidingLimit); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(VoidingMode.class) + .value(voidingMode) + .overlay(16, GTGuiTextures.VOIDING_MODES) + .lang(IKey.dynamic(() -> Component.translatable(getVoidingMode().tooltip))) + .build() + .marginTop(2)); + + column.child( + GTMuiWidgets.createIntInputWithBucketMode(voidingLimit, bucketModeSync, getVoidingMode().maxStackSize) + .setEnabledIf($ -> shouldShowStackSize())); + + return column; } private int getCurrentBucketModeTransferSize() { @@ -153,16 +165,6 @@ protected void configureFilter() { if (filterHandler.getFilter() instanceof SimpleFluidFilter filter) { filter.setMaxStackSize(voidingMode == VoidingMode.VOID_ANY ? 1 : Integer.MAX_VALUE); } - - configureStackSizeInput(); - } - - private void configureStackSizeInput() { - if (this.stackSizeInput == null || stackSizeBucketModeInput == null) - return; - - this.stackSizeInput.setVisible(shouldShowStackSize()); - this.stackSizeBucketModeInput.setVisible(shouldShowStackSize()); } private boolean shouldShowStackSize() { diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java index a8ae17034bf..3af7bea982a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java @@ -6,9 +6,18 @@ import com.gregtechceu.gtceu.api.cover.filter.SimpleItemFilter; import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; +import com.gregtechceu.gtceu.api.mui.base.drawable.IKey; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.EnumSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.data.VoidingMode; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; +import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; @@ -16,11 +25,13 @@ import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; import net.minecraftforge.items.IItemHandler; import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.NotNull; import java.util.Map; @@ -38,6 +49,7 @@ public class AdvancedItemVoidingCover extends ItemVoidingCover { @SaveField @Getter + @Setter protected int globalVoidingLimit = 1; private IntInputWidget stackSizeInput; @@ -112,6 +124,30 @@ public void setVoidingMode(VoidingMode voidingMode) { // *********** GUI ***********// ////////////////////////////////////// + @Override + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + var column = super.createCoverUI(data, syncManager, settings); + + EnumSyncValue voidingMode = new EnumSyncValue<>(VoidingMode.class, + this::getVoidingMode, this::setVoidingMode); + IntSyncValue voidingLimit = new IntSyncValue(this::getGlobalVoidingLimit, this::setGlobalVoidingLimit); + + syncManager.syncValue("voidingMode", voidingMode); + syncManager.syncValue("voidingLimit", voidingLimit); + + column.child(new GTMuiWidgets.EnumRowBuilder<>(VoidingMode.class) + .value(voidingMode) + .overlay(16, GTGuiTextures.VOIDING_MODES) + .lang(IKey.dynamic(() -> Component.translatable(getVoidingMode().tooltip))) + .build() + .marginTop(2)); + + column.child(GTMuiWidgets.createIntInputWithButtons(voidingLimit, 1, getVoidingMode().maxStackSize) + .setEnabledIf($ -> shouldShowStackSize())); + + return column; + } + @Override protected @NotNull String getUITitle() { return "cover.item.voiding.advanced.title"; diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/FluidVoidingCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/FluidVoidingCover.java index bbd2d2732a1..555a3a32d1e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/FluidVoidingCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/FluidVoidingCover.java @@ -2,17 +2,20 @@ import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.api.cover.filter.FluidFilter; import com.gregtechceu.gtceu.api.gui.GuiTextures; -import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; import com.gregtechceu.gtceu.api.item.tool.GTToolType; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.PumpCover; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; import com.gregtechceu.gtceu.utils.GTMath; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; -import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; -import com.lowdragmc.lowdraglib.gui.widget.Widget; -import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; @@ -85,25 +88,18 @@ void voidAny(IFluidHandlerModifiable fluidHandler) { } } - ////////////////////////////////////// - // *********** GUI ***********// - ////////////////////////////////////// - @Override - public Widget createUIWidget() { - final var group = new WidgetGroup(0, 0, 176, 120); - group.addWidget(new LabelWidget(10, 5, getUITitle())); - - group.addWidget(new ToggleButtonWidget(10, 20, 20, 20, - GuiTextures.BUTTON_POWER, this::isWorkingEnabled, this::setWorkingEnabled)); - - // group.addWidget(filterHandler.createFilterSlotUI(36, 21)); - group.addWidget(filterHandler.createFilterSlotUI(148, 91)); - group.addWidget(filterHandler.createFilterConfigUI(10, 50, 126, 60)); + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + Flow column = Flow.column() + .top(7).margin(7, 0) + .widthRel(1.0f).coverChildrenHeight(); - buildAdditionalUI(group); + var filterRow = GTMuiWidgets.createFilterRow(filterHandler, FluidFilter::loadFilter, data, syncManager, + settings); + filterRow.child(0, GTMuiWidgets.createPowerButton(this::isWorkingEnabled, this::setWorkingEnabled, syncManager) + .marginRight(2)); - return group; + return column.child(filterRow); } @NotNull diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/ItemVoidingCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/ItemVoidingCover.java index 1eae40f9a91..1b737406742 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/ItemVoidingCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/ItemVoidingCover.java @@ -6,7 +6,13 @@ import com.gregtechceu.gtceu.api.cover.filter.ItemFilter; import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.item.tool.GTToolType; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; +import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; import com.gregtechceu.gtceu.common.cover.ConveyorCover; +import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; @@ -80,24 +86,19 @@ void voidAny(IItemHandler handler) { // *********** GUI ***********// ////////////////////////////////////// - /* - * @Override - * public Widget createUIWidget() { - * final var group = new WidgetGroup(0, 0, 176, 120); - * group.addWidget(new LabelWidget(10, 5, getUITitle())); - * - * group.addWidget(new ToggleButtonWidget(10, 20, 20, 20, - * GuiTextures.BUTTON_POWER, this::isWorkingEnabled, this::setWorkingEnabled)); - * - * // group.addWidget(filterHandler.createFilterSlotUI(36, 21)); - * group.addWidget(filterHandler.createFilterSlotUI(148, 91)); - * group.addWidget(filterHandler.createFilterConfigUI(10, 50, 126, 60)); - * - * buildAdditionalUI(group); - * - * return group; - * } - */ + @Override + public ParentWidget createCoverUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + Flow column = Flow.column() + .top(7).margin(7, 0) + .widthRel(1.0f).coverChildrenHeight(); + + var filterRow = GTMuiWidgets.createFilterRow(filterHandler, ItemFilter::loadFilter, data, syncManager, + settings); + filterRow.child(0, GTMuiWidgets.createPowerButton(this::isWorkingEnabled, this::setWorkingEnabled, syncManager) + .marginRight(2)); + + return column.child(filterRow); + } @NotNull protected String getUITitle() { diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/mui/GTMuiWidgets.java b/src/main/java/com/gregtechceu/gtceu/common/data/mui/GTMuiWidgets.java index 4a2cce66a74..063f45bad44 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/mui/GTMuiWidgets.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/mui/GTMuiWidgets.java @@ -1,6 +1,9 @@ package com.gregtechceu.gtceu.common.data.mui; import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.cover.filter.Filter; +import com.gregtechceu.gtceu.api.cover.filter.FilterHandler; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; @@ -15,10 +18,14 @@ import com.gregtechceu.gtceu.api.mui.drawable.ItemDrawable; import com.gregtechceu.gtceu.api.mui.drawable.UITexture; import com.gregtechceu.gtceu.api.mui.drawable.text.TextRenderer; +import com.gregtechceu.gtceu.api.mui.factory.SidedPosGuiData; import com.gregtechceu.gtceu.api.mui.theme.ThemeAPI; import com.gregtechceu.gtceu.api.mui.utils.Alignment; +import com.gregtechceu.gtceu.api.mui.utils.Color; +import com.gregtechceu.gtceu.api.mui.utils.MouseData; import com.gregtechceu.gtceu.api.mui.value.BoolValue; import com.gregtechceu.gtceu.api.mui.value.sync.*; +import com.gregtechceu.gtceu.api.mui.widget.EmptyWidget; import com.gregtechceu.gtceu.api.mui.widget.ParentWidget; import com.gregtechceu.gtceu.api.mui.widgets.*; import com.gregtechceu.gtceu.api.mui.widgets.layout.Column; @@ -28,13 +35,18 @@ import com.gregtechceu.gtceu.api.mui.widgets.slot.FluidSlot; import com.gregtechceu.gtceu.api.mui.widgets.slot.ItemSlot; import com.gregtechceu.gtceu.api.mui.widgets.slot.ModularSlot; +import com.gregtechceu.gtceu.api.mui.widgets.textfield.TextFieldWidget; import com.gregtechceu.gtceu.api.recipe.gui.GTRecipeTypeUILayout; import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; +import com.gregtechceu.gtceu.common.cover.data.BucketMode; import com.gregtechceu.gtceu.common.item.IntCircuitBehaviour; import com.gregtechceu.gtceu.common.mui.GTGuiTextures; import com.gregtechceu.gtceu.config.ConfigHolder; import net.minecraft.network.chat.Component; +import net.minecraft.util.Mth; +import net.minecraft.util.StringRepresentable; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraftforge.items.IItemHandler; @@ -42,9 +54,7 @@ import com.mojang.blaze3d.platform.InputConstants; import it.unimi.dsi.fastutil.booleans.BooleanConsumer; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Supplier; +import java.util.function.*; public class GTMuiWidgets { @@ -354,4 +364,260 @@ public static String[] createGrid(int amount, int rowSize, boolean output, char public static ParentWidget createXEIWidget(GTRecipeTypeUILayout layout) { return new ParentWidget<>(); } + + public static CycleButtonWidget createIOCycleButton(EnumSyncValue syncValue, boolean allowExtendedIO) { + var cycleButton = new CycleButtonWidget() + .stateCount(allowExtendedIO ? 4 : 2) + .stateOverlay(IO.IN, IO.IN.getUiTexture()) + .stateOverlay(IO.OUT, IO.OUT.getUiTexture()) + .tooltipBuilder( + r -> r.addLine(IKey.dynamic(() -> Component.translatable(syncValue.getValue().getTooltip())))); + + if (allowExtendedIO) { + cycleButton.stateOverlay(IO.BOTH, IO.BOTH.getUiTexture()); + cycleButton.stateOverlay(IO.NONE, IO.NONE.getUiTexture()); + } + + return cycleButton; + } + + public static > ParentWidget createFilterRow(FilterHandler filterHandler, + Function filterLoader, + SidedPosGuiData data, + PanelSyncManager syncManager, + UISettings settings) { + var filterSlot = filterHandler.getFilterSlot(); + // TODO get the panel to use the right sync handler when swapping from one item filter to the next + var panelHandler = syncManager.syncedPanel("filterPanel", true, + (sm, sh) -> filterLoader.apply(filterSlot.getStackInSlot(0)).getPanel(data, sm, settings)); + + DynamicSyncHandler filterButton = new DynamicSyncHandler() + .widgetProvider((sm, buf) -> { + ItemStack stack = buf.readItem(); + if (stack.isEmpty()) return new EmptyWidget(); + stack = filterSlot.getStackInSlot(0); + S filter = filterLoader.apply(stack); + + return new ButtonWidget<>() + .onMousePressed((x, y, b) -> { + panelHandler.openPanel(); + return true; + }); + }); + + return Flow.row() + .coverChildrenHeight() + .child(new ItemSlot() + .slot(new ModularSlot(filterSlot, 0) + .changeListener((stack, amount, client, init) -> { + filterButton.notifyUpdate(packet -> packet.writeItem(stack)); + })) + .marginLeft(2)) + .child(new DynamicSyncedWidget<>().syncHandler(filterButton)); + } + + private static int getIncrementValue(MouseData data) { + int adjust = 1; + if (data.shift()) adjust *= 4; + if (data.ctrl()) adjust *= 16; + if (data.alt()) adjust *= 64; + return adjust; + } + + private static IKey createAdjustOverlay(boolean increment) { + final StringBuilder builder = new StringBuilder(); + builder.append(increment ? '+' : '-'); + builder.append(getIncrementValue(MouseData.create(-1))); + + float scale = 1f; + if (builder.length() == 3) { + scale = 0.8f; + } else if (builder.length() == 4) { + scale = 0.6f; + } else if (builder.length() > 4) { + scale = 0.5f; + } + return IKey.str(builder.toString()) + .color(Color.WHITE.main) + .scale(scale); + } + + public static ParentWidget createIntInputWithButtons(IntSyncValue syncValue, int minValue, int maxValue) { + StringSyncValue formattedValue = new StringSyncValue(syncValue::getStringValue, + syncValue::setStringValue); + + return Flow.row() + .coverChildrenHeight() + .marginBottom(2) + .widthRel(1.0f) + .child(new ButtonWidget<>() + .left(0).width(18) + .onMousePressed((x, y, button) -> { + int val = syncValue.getIntValue() - getIncrementValue(MouseData.create(button)); + val = Mth.clamp(val, minValue, maxValue); + syncValue.setIntValue(val, true, true); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) + .child(new TextFieldWidget() + .left(18).right(18) + .setTextAlignment(Alignment.Center) + .setTextColor(Color.WHITE.darker(1)) + .setNumbers(minValue, maxValue) + .onMouseScrolled((mouseX, mouseY, delta) -> { + int inc = (int) delta * getIncrementValue(MouseData.create(-1)); + int val = Mth.clamp(syncValue.getIntValue() + inc, minValue, maxValue); + syncValue.setIntValue(val, true, true); + return true; + }) + .value(formattedValue) + .background(GTGuiTextures.DISPLAY)) + .child(new ButtonWidget<>() + .right(0).width(18) + .onMousePressed((x, y, button) -> { + int val = syncValue.getIntValue() + getIncrementValue(MouseData.create(button)); + val = Mth.clamp(val, minValue, maxValue); + syncValue.setIntValue(val, true, true); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(true)))); + } + + public static ParentWidget createIntInputWithBucketMode(IntSyncValue intSyncValue, + EnumSyncValue bucketModeSyncValue, + int maxMB) { + StringSyncValue formattedValue = new StringSyncValue( + () -> String.valueOf((intSyncValue.getValue() / bucketModeSyncValue.getValue().multiplier)), + (v) -> intSyncValue.setValue(Integer.parseInt(v) * bucketModeSyncValue.getValue().multiplier, true, + true)); + + return Flow.row() + .coverChildrenHeight() + .marginBottom(2) + .widthRel(1.0f) + .child(new ButtonWidget<>() + .width(18) + .onMousePressed((x, y, button) -> { + int val = intSyncValue.getIntValue() - (getIncrementValue(MouseData.create(button)) * + bucketModeSyncValue.getValue().multiplier); + val = Mth.clamp(val, 0, maxMB); + intSyncValue.setIntValue(val, true, true); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) + .child(new TextFieldWidget() + .left(18).right(36) + .setTextAlignment(Alignment.Center) + .setTextColor(Color.WHITE.darker(1)) + .setNumbers(0, maxMB) + .onMouseScrolled((mouseX, mouseY, delta) -> { + int inc = (int) delta * (getIncrementValue(MouseData.create(-1)) * + bucketModeSyncValue.getValue().multiplier); + int val = Mth.clamp(intSyncValue.getIntValue() + inc, 0, maxMB); + intSyncValue.setIntValue(val, true, true); + return true; + }) + .value(formattedValue) + .background(GTGuiTextures.DISPLAY)) + .child(new ButtonWidget<>() + .right(18) + .width(18) + .onMousePressed((x, y, button) -> { + int val = intSyncValue.getIntValue() + (getIncrementValue(MouseData.create(button)) * + bucketModeSyncValue.getValue().multiplier); + val = Mth.clamp(val, 0, maxMB); + intSyncValue.setIntValue(val, true, true); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(true)))) + .child(new CycleButtonWidget() + .right(0) + .width(18) + .value(bucketModeSyncValue) + .background(BucketMode.BUCKET.getIcon(), BucketMode.MILLI_BUCKET.getIcon())); + } + + public static class EnumRowBuilder> { + + private EnumSyncValue syncValue; + private final Class enumValue; + private IKey lang; + private IDrawable[] background; + private IDrawable selectedBackground; + private IDrawable[] overlay; + + public EnumRowBuilder(Class enumValue) { + this.enumValue = enumValue; + } + + public EnumRowBuilder value(EnumSyncValue syncValue) { + this.syncValue = syncValue; + return this; + } + + public EnumRowBuilder lang(IKey lang) { + this.lang = lang; + return this; + } + + public EnumRowBuilder background(IDrawable... background) { + this.background = background; + return this; + } + + public EnumRowBuilder selectedBackground(IDrawable selectedBackground) { + this.selectedBackground = selectedBackground; + return this; + } + + public EnumRowBuilder overlay(IDrawable... overlay) { + this.overlay = overlay; + return this; + } + + public EnumRowBuilder overlay(int size, IDrawable... overlay) { + this.overlay = new IDrawable[overlay.length]; + for (int i = 0; i < overlay.length; i++) { + this.overlay[i] = overlay[i].asIcon().size(size); + } + return this; + } + + private BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); + } + + public Flow build() { + var row = Flow.row().marginBottom(2).coverChildrenHeight().widthRel(1f); + if (this.enumValue != null && this.syncValue != null) { + for (var enumVal : enumValue.getEnumConstants()) { + var button = new ToggleButton().size(18).marginRight(2) + .value(boolValueOf(this.syncValue, enumVal)); + + if (this.background != null && this.background.length > 0) + button.background(this.background); + else + button.background(GTGuiTextures.MC_BUTTON); + + if (this.selectedBackground != null) + button.selectedBackground(this.selectedBackground); + else + button.selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED); + + if (this.overlay != null) + button.overlay(this.overlay[enumVal.ordinal()]); + + if (enumVal instanceof StringRepresentable serializable) { + button.addTooltipLine(IKey.lang(serializable.getSerializedName())); + } + row.child(button); + } + } + + if (this.lang != null) + row.child(this.lang.asWidget().align(Alignment.CenterRight).height(18)); + + return row; + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/FluidFilterBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/FluidFilterBehaviour.java index e816afb4ccf..5f93c136ba0 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/FluidFilterBehaviour.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/FluidFilterBehaviour.java @@ -1,35 +1,42 @@ package com.gregtechceu.gtceu.common.item; import com.gregtechceu.gtceu.api.cover.filter.FluidFilter; -import com.gregtechceu.gtceu.api.gui.GuiTextures; -import com.gregtechceu.gtceu.api.gui.UITemplate; -import com.gregtechceu.gtceu.api.item.component.IItemUIFactory; - -import com.lowdragmc.lowdraglib.gui.factory.HeldItemUIFactory; -import com.lowdragmc.lowdraglib.gui.modular.ModularUI; -import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; +import com.gregtechceu.gtceu.api.mui.base.IItemUIHolder; +import com.gregtechceu.gtceu.api.mui.factory.PlayerInventoryGuiData; +import com.gregtechceu.gtceu.api.mui.factory.UIFactories; +import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager; +import com.gregtechceu.gtceu.client.mui.screen.ModularPanel; +import com.gregtechceu.gtceu.client.mui.screen.UISettings; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; import java.util.function.Function; -public record FluidFilterBehaviour(Function filterCreator) implements IItemUIFactory { +public record FluidFilterBehaviour(Function filterCreator) implements IItemUIHolder { @Override public void onAttached(Item item) { - IItemUIFactory.super.onAttached(item); FluidFilter.FILTERS.put(item, filterCreator); } @Override - public ModularUI createUI(HeldItemUIFactory.HeldItemHolder holder, Player entityPlayer) { - var held = holder.getHeld(); - return new ModularUI(176, 157, holder, entityPlayer) - .background(GuiTextures.BACKGROUND) - .widget(new LabelWidget(5, 5, held.getDescriptionId())) - .widget(FluidFilter.loadFilter(held).openConfigurator((176 - 80) / 2, (60 - 55) / 2 + 15)) - .widget(UITemplate.bindPlayerInventory(entityPlayer.getInventory(), GuiTextures.SLOT, 7, 75, true)); + public InteractionResultHolder use(Item item, Level level, Player player, InteractionHand usedHand) { + if (!level.isClientSide) { + if (player.isCrouching()) { + UIFactories.playerInventory().openFromHand(player, usedHand); + return InteractionResultHolder.success(player.getItemInHand(usedHand)); + } + } + return InteractionResultHolder.fail(player.getItemInHand(usedHand)); + } + + @Override + public ModularPanel buildUI(PlayerInventoryGuiData data, PanelSyncManager syncManager, UISettings settings) { + return FluidFilter.loadFilter(data.getUsedItemStack()).getPanel(data, syncManager, settings); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/GTGuiTextures.java b/src/main/java/com/gregtechceu/gtceu/common/mui/GTGuiTextures.java index 1570d72a83d..36588fefcf2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/mui/GTGuiTextures.java +++ b/src/main/java/com/gregtechceu/gtceu/common/mui/GTGuiTextures.java @@ -184,15 +184,18 @@ public static class IDs { // public static final IDrawable PLUS = IKey.str("+").asIcon().marginLeft(1); // public static final IDrawable MINUS = IKey.str("-").asIcon().marginLeft(1); - public static final UITexture[] MANUAL_IO_OVERLAY_IN = slice("textures/gui/overlay/manual_io_overlay_in.png", - 18, 18 * 3, 18, 18, ColorType.DEFAULT); + public static final UITexture INFO = fullImage("textures/gui/widget/information.png"); + + public static final UITexture[] MANUAL_IO_OVERLAY_IN = { fullImage("textures/gui/icon/manual_io_mode/disabled.png"), + fullImage("textures/gui/icon/manual_io_mode/filtered.png"), + fullImage("textures/gui/icon/manual_io_mode/unfiltered.png") }; public static final UITexture[] MANUAL_IO_OVERLAY_OUT = slice("textures/gui/overlay/manual_io_overlay_out.png", 18, 18 * 3, 18, 18, ColorType.DEFAULT); public static final UITexture[] CONVEYOR_MODE_OVERLAY = slice("textures/gui/overlay/conveyor_mode_overlay.png", 18, 18 * 2, 18, 18, ColorType.DEFAULT); public static final UITexture[] TRANSFER_MODE_OVERLAY = slice("textures/gui/overlay/transfer_mode_overlay.png", - 18, 18 * 3, 18, 18, ColorType.DEFAULT); + 40, 40 * 3, 40, 40, ColorType.DEFAULT); public static final UITexture[] FLUID_TRANSFER_MODE_OVERLAY = slice( "textures/gui/overlay/fluid_transfer_mode_overlay.png", @@ -202,6 +205,9 @@ public static class IDs { "textures/gui/widget/button_distribution_mode.png", 16, 48, 16, 16, ColorType.DEFAULT); + public static final UITexture[] VOIDING_MODES = { fullImage("textures/gui/icon/voiding_mode/void_any.png"), + fullImage("textures/gui/icon/voiding_mode/void_overflow.png") }; + public static final UITexture BUTTON_VOID = fullImage("textures/gui/widget/button_void.png"); public static final UITexture BUTTON_VOID_PARTIAL = fullImage("textures/gui/widget/button_void_partial.png"); @@ -431,6 +437,8 @@ public static class IDs { public static final UITexture BUTTON_CLEAR_GRID = fullImage("textures/gui/widget/button_clear_grid.png", null); public static final UITexture BUTTON_CROSS = fullImage("textures/gui/widget/button_clear_grid.png"); + public static final UITexture BUTTON_DETECTOR_INVERT = fullImage( + "textures/gui/widget/button_detector_cover_inverted.png"); public static final UITexture BUTTON_REDSTONE_ON = fullImage("textures/gui/widget/button_redstone_on.png"); public static final UITexture BUTTON_REDSTONE_OFF = fullImage("textures/gui/widget/button_redstone_off.png"); public static final UITexture BUTTON_THROTTLE_PLUS = fullImage("textures/gui/widget/button_throttle_plus.png"); diff --git a/src/main/java/com/gregtechceu/gtceu/utils/TagExprFilter.java b/src/main/java/com/gregtechceu/gtceu/utils/TagExprFilter.java index 8897801b1e6..e17b1183762 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/TagExprFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/TagExprFilter.java @@ -13,6 +13,13 @@ public class TagExprFilter { + private static final Pattern DOUBLE_WILDCARD = Pattern.compile("\\*{2,}"); + private static final Pattern DOUBLE_AND = Pattern.compile("&{2,}"); + private static final Pattern DOUBLE_OR = Pattern.compile("\\|{2,}"); + private static final Pattern DOUBLE_NOT = Pattern.compile("!{2,}"); + private static final Pattern DOUBLE_XOR = Pattern.compile("\\^{2,}"); + private static final Pattern DOUBLE_SPACE = Pattern.compile(" {2,}"); + public static class TagExprParser { public enum TokenType { @@ -292,4 +299,59 @@ public static boolean tagsMatch(TagExprParser.MatchExpr expr, FluidStack stack) return expr != null && expr.matches(tags); } + + public static String tagInputValidator(String input) { + // remove all operators that are double + input = DOUBLE_WILDCARD.matcher(input).replaceAll("*"); + input = DOUBLE_AND.matcher(input).replaceAll("&"); + input = DOUBLE_OR.matcher(input).replaceAll("|"); + input = DOUBLE_NOT.matcher(input).replaceAll("!"); + input = DOUBLE_XOR.matcher(input).replaceAll("^"); + input = DOUBLE_SPACE.matcher(input).replaceAll(" "); + // move ( and ) so it doesn't create invalid expressions f.e. xxx (& yyy) => xxx & (yyy) + // append or prepend ( and ) if the amount is not equal + StringBuilder builder = new StringBuilder(); + int unclosed = 0; + char last = ' '; + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (c == ' ') { + if (last != '(') + builder.append(" "); + continue; + } + if (c == '(') + unclosed++; + else if (c == ')') { + unclosed--; + if (last == '&' || last == '|' || last == '^') { + int l = builder.lastIndexOf(" " + last); + int l2 = builder.lastIndexOf(String.valueOf(last)); + builder.insert(l == l2 - 1 ? l : l2, ")"); + continue; + } + if (i > 0 && builder.charAt(builder.length() - 1) == ' ') { + builder.deleteCharAt(builder.length() - 1); + } + } else if ((c == '&' || c == '|' || c == '^') && last == '(') { + builder.deleteCharAt(builder.lastIndexOf("(")); + builder.append(c).append(" ("); + continue; + } + + builder.append(c); + last = c; + } + if (unclosed > 0) { + builder.append(")".repeat(unclosed)); + } else if (unclosed < 0) { + unclosed = -unclosed; + for (int i = 0; i < unclosed; i++) { + builder.insert(0, "("); + } + } + input = builder.toString(); + input = input.replaceAll(" {2,}", " "); + return input; + } } diff --git a/src/main/resources/assets/gtceu/textures/gui/overlay/transfer_mode_overlay.png b/src/main/resources/assets/gtceu/textures/gui/overlay/transfer_mode_overlay.png new file mode 100644 index 00000000000..5d25ec7dfa4 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/gui/overlay/transfer_mode_overlay.png differ