diff --git a/dependencies.gradle b/dependencies.gradle index 9ccd17cb2c0..91d6a5d5c7e 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -40,7 +40,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") - api("com.cleanroommc:modularui:2.5.0-rc1") { transitive = false } + api("com.cleanroommc:modularui:2.5.0-rc2") { transitive = false } api("com.cleanroommc:groovyscript:1.2.0-hotfix1") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.700") api("appeng:ae2-uel:v0.56.4") { transitive = false } diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java index d1c6fa0d0c8..6c288e08137 100644 --- a/src/main/java/gregtech/api/cover/CoverWithUI.java +++ b/src/main/java/gregtech/api/cover/CoverWithUI.java @@ -22,6 +22,7 @@ import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.sync.EnumSyncValue; @@ -29,7 +30,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.ApiStatus; public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder { @@ -98,12 +99,14 @@ default void markAsDirty() { /** * Create the Title bar widget for a Cover. */ - static Row createTitleRow(ItemStack stack) { - return new Row() + static Flow createTitleRow(ItemStack stack) { + return Flow.row() .pos(4, 4) .height(16).coverChildrenWidth() .child(new ItemDrawable(stack).asWidget().size(16).marginRight(4)) - .child(IKey.str(stack.getDisplayName()).color(UI_TITLE_COLOR).asWidget().heightRel(1.0f)); + .child(IKey.str(stack.getDisplayName()) + .color(UI_TITLE_COLOR) + .asWidget().heightRel(1.0f)); } /** @@ -135,6 +138,7 @@ default IKey createAdjustOverlay(boolean increment) { scale = 0.5f; } return IKey.str(builder.toString()) + .color(Color.WHITE.main) .scale(scale); } @@ -204,8 +208,8 @@ private BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); } - public Row build() { - var row = new Row().marginBottom(2).coverChildrenHeight().widthRel(1f); + 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) diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index 4f0345f49fc..2fecf35642e 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -167,6 +167,7 @@ public static class IDs { public static final UITexture[] BUTTON_MATCH_ALL = slice("textures/gui/widget/ore_filter/button_match_all.png", 16, 32, 16, 16, true); + public static final UITexture BUTTON_LOCK = fullImage("textures/gui/widget/button_lock.png"); public static final UITexture OREDICT_ERROR = fullImage("textures/gui/widget/ore_filter/error.png"); public static final UITexture OREDICT_INFO = fullImage("textures/gui/widget/ore_filter/info.png"); diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java index 3ed22931d18..4a6c2c2d4dd 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTheme.java +++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java @@ -9,7 +9,7 @@ import com.cleanroommc.modularui.api.ITheme; import com.cleanroommc.modularui.api.IThemeApi; import com.cleanroommc.modularui.drawable.UITexture; -import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.theme.ReloadThemeEvent; import com.cleanroommc.modularui.utils.JsonBuilder; import org.jetbrains.annotations.Nullable; @@ -108,7 +108,7 @@ public static void onReloadThemes(ReloadThemeEvent.Pre event) { public static Builder templateBuilder(String themeId) { Builder builder = new Builder(themeId); builder.openCloseAnimation(0); - builder.tooltipPos(Tooltip.Pos.NEXT_TO_MOUSE); + builder.tooltipPos(RichTooltip.Pos.NEXT_TO_MOUSE); builder.smoothProgressBar(true); return builder; } @@ -163,7 +163,7 @@ public Builder smoothProgressBar(boolean smoothBar) { } /** Set the tooltip pos for this theme. Overrides global cfg. */ - public Builder tooltipPos(Tooltip.Pos tooltipPos) { + public Builder tooltipPos(RichTooltip.Pos tooltipPos) { theme.elementBuilder.add(b -> b.add("tooltipPos", tooltipPos.name())); return this; } diff --git a/src/main/java/gregtech/api/mui/GTGuis.java b/src/main/java/gregtech/api/mui/GTGuis.java index 614f6a08f1b..9f9989b2601 100644 --- a/src/main/java/gregtech/api/mui/GTGuis.java +++ b/src/main/java/gregtech/api/mui/GTGuis.java @@ -9,7 +9,6 @@ import net.minecraft.item.ItemStack; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.factory.GuiManager; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; @@ -19,6 +18,8 @@ public class GTGuis { + public static final int DEFAULT_WIDTH = 176, DEFAULT_HIEGHT = 166; + @ApiStatus.Internal public static void registerFactories() { GuiManager.registerFactory(MetaTileEntityGuiFactory.INSTANCE); @@ -39,9 +40,35 @@ public static ModularPanel createPanel(Cover cover, int width, int height) { } public static ModularPanel createPanel(ItemStack stack, int width, int height) { - MetaItem.MetaValueItem valueItem = ((MetaItem) stack.getItem()).getItem(stack); - if (valueItem == null) throw new IllegalArgumentException("Item must be a meta item!"); - return createPanel(valueItem.unlocalizedName, width, height); + String locale; + if (stack.getItem() instanceof MetaItemmetaItem) { + var valueItem = metaItem.getItem(stack); + if (valueItem == null) throw new IllegalArgumentException("Item must be a meta item!"); + locale = valueItem.unlocalizedName; + } else { + locale = stack.getTranslationKey(); + } + return createPanel(locale, width, height); + } + + public static ModularPanel createPanel(String name) { + return ModularPanel.defaultPanel(name, DEFAULT_WIDTH, DEFAULT_HIEGHT); + } + + public static ModularPanel defaultPanel(MetaTileEntity mte) { + return createPanel(mte.metaTileEntityId.getPath()); + } + + public static ModularPanel defaultPanel(Cover cover) { + return createPanel(cover.getDefinition().getResourceLocation().getPath()); + } + + public static ModularPanel defaultPanel(ItemStack stack) { + return createPanel(stack, DEFAULT_WIDTH, DEFAULT_HIEGHT); + } + + public static ModularPanel defaultPanel(MetaItem.MetaValueItem valueItem) { + return createPanel(valueItem.unlocalizedName); } public static ModularPanel createPopupPanel(String name, int width, int height) { @@ -53,6 +80,15 @@ public static ModularPanel createPopupPanel(String name, int width, int height, return new PopupPanel(name, width, height, disableBelow, closeOnOutsideClick); } + public static ModularPanel defaultPopupPanel(String name) { + return defaultPopupPanel(name, false, false); + } + + public static ModularPanel defaultPopupPanel(String name, boolean disableBelow, + boolean closeOnOutsideClick) { + return new PopupPanel(name, DEFAULT_WIDTH, DEFAULT_HIEGHT, disableBelow, closeOnOutsideClick); + } + private static class PopupPanel extends ModularPanel { private final boolean disableBelow; @@ -67,7 +103,6 @@ public PopupPanel(@NotNull String name, int width, int height, boolean disableBe .onMousePressed(mouseButton -> { if (mouseButton == 0 || mouseButton == 1) { this.closeIfOpen(true); - Interactable.playButtonClickSound(); return true; } return false; diff --git a/src/main/java/gregtech/api/mui/StateOverlay.java b/src/main/java/gregtech/api/mui/StateOverlay.java new file mode 100644 index 00000000000..fefdc7fc477 --- /dev/null +++ b/src/main/java/gregtech/api/mui/StateOverlay.java @@ -0,0 +1,22 @@ +package gregtech.api.mui; + +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.widgets.ToggleButton; + +import java.util.function.Consumer; + +public interface StateOverlay { + + StateOverlay overlay(boolean selected, IDrawable... overlay); + + StateOverlay hoverOverlay(boolean selected, IDrawable... overlay); + + static ToggleButton cast(ToggleButton button, Consumer function) { + function.accept((StateOverlay) button); + return button; + } + + static ToggleButton create(Consumer function) { + return cast(new ToggleButton(), function); + } +} diff --git a/src/main/java/gregtech/api/mui/UnboxFix.java b/src/main/java/gregtech/api/mui/UnboxFix.java new file mode 100644 index 00000000000..48f1bda2f20 --- /dev/null +++ b/src/main/java/gregtech/api/mui/UnboxFix.java @@ -0,0 +1,8 @@ +package gregtech.api.mui; + +public interface UnboxFix { + + void gregTech$useDefaultTextColor(boolean b); + + void gregTech$useDefaultShadow(boolean b); +} diff --git a/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java b/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java deleted file mode 100644 index bf3c6c581d7..00000000000 --- a/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java +++ /dev/null @@ -1,150 +0,0 @@ -package gregtech.api.mui.sync; - -import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandlerItem; - -import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.value.sync.FluidSlotSyncHandler; -import org.jetbrains.annotations.Nullable; - -public class FixedFluidSlotSH extends FluidSlotSyncHandler { - - @Nullable - private FluidStack lastStoredPhantomFluid; - - public FixedFluidSlotSH(IFluidTank fluidTank) { - super(fluidTank); - if (this.updateCacheFromSource(true) && fluidTank.getFluid() != null) { - this.lastStoredPhantomFluid = fluidTank.getFluid().copy(); - } - } - - @Override - public void readOnServer(int id, PacketBuffer buf) { - super.readOnServer(id, buf); - if (id == 0) { - var fluid = getFluidTank().getFluid(); - if (this.lastStoredPhantomFluid == null && fluid != null || - (this.lastStoredPhantomFluid != null && !this.lastStoredPhantomFluid.isFluidEqual(fluid))) { - this.lastStoredPhantomFluid = fluid; - } - } - } - - @Override - public void setValue(@Nullable FluidStack value, boolean setSource, boolean sync) { - super.setValue(value, setSource, sync); - if (setSource) { - this.getFluidTank().drain(Integer.MAX_VALUE, true); - if (!isFluidEmpty(value)) { - this.getFluidTank().fill(value.copy(), true); - } - } - } - - @Override - public void tryClickPhantom(MouseData mouseData) { - EntityPlayer player = getSyncManager().getPlayer(); - ItemStack currentStack = player.inventory.getItemStack(); - FluidStack currentFluid = this.getFluidTank().getFluid(); - IFluidHandlerItem fluidHandlerItem = currentStack - .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); - - if (mouseData.mouseButton == 0) { - if (currentStack.isEmpty() || fluidHandlerItem == null) { - if (this.canDrainSlot()) { - this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); - } - } else { - FluidStack cellFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); - if ((this.controlsAmount() || currentFluid == null) && cellFluid != null) { - if (this.canFillSlot()) { - if (!this.controlsAmount()) { - cellFluid.amount = 1; - } - if (this.getFluidTank().fill(cellFluid, true) > 0) { - this.lastStoredPhantomFluid = cellFluid.copy(); - } - } - } else { - if (this.canDrainSlot()) { - this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); - } - } - } - } else if (mouseData.mouseButton == 1) { - if (this.canFillSlot()) { - if (currentFluid != null) { - if (this.controlsAmount()) { - FluidStack toFill = currentFluid.copy(); - toFill.amount = 1000; - this.getFluidTank().fill(toFill, true); - } - } else if (this.lastStoredPhantomFluid != null) { - FluidStack toFill = this.lastStoredPhantomFluid.copy(); - toFill.amount = this.controlsAmount() ? 1 : toFill.amount; - this.getFluidTank().fill(toFill, true); - } - } - } else if (mouseData.mouseButton == 2 && currentFluid != null && this.canDrainSlot()) { - this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); - } - this.setValue(this.getFluidTank().getFluid(), false, true); - } - - @Override - public void tryScrollPhantom(MouseData mouseData) { - FluidStack currentFluid = this.getFluidTank().getFluid(); - int amount = mouseData.mouseButton; - if (!this.controlsAmount()) { - var fluid = getFluidTank().getFluid(); - int newAmt = amount == 1 ? 1 : 0; - if (fluid != null && fluid.amount != newAmt) { - fluid.amount = newAmt; - setValue(fluid, true, true); - return; - } - } - if (mouseData.shift) { - amount *= 10; - } - if (mouseData.ctrl) { - amount *= 100; - } - if (mouseData.alt) { - amount *= 1000; - } - if (currentFluid == null) { - if (amount > 0 && this.lastStoredPhantomFluid != null) { - FluidStack toFill = this.lastStoredPhantomFluid.copy(); - toFill.amount = this.controlsAmount() ? amount : 1; - this.getFluidTank().fill(toFill, true); - } - this.setValue(this.getFluidTank().getFluid(), false, true); - return; - } - if (amount > 0) { - FluidStack toFill = currentFluid.copy(); - toFill.amount = amount; - this.getFluidTank().fill(toFill, true); - } else if (amount < 0) { - this.getFluidTank().drain(-amount, true); - } - this.setValue(this.getFluidTank().getFluid(), false, true); - } - - @Override - public boolean controlsAmount() { - if (getFluidTank() instanceof SimpleFluidFilterReader.WritableFluidTank writableFluidTank) { - return writableFluidTank.showAmount(); - } - return super.controlsAmount(); - } -} diff --git a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java index b5be013da18..1886be86d31 100644 --- a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java +++ b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java @@ -1,6 +1,7 @@ package gregtech.api.mui.sync; import gregtech.api.util.GTUtility; +import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; @@ -9,36 +10,117 @@ import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandlerItem; import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.utils.BooleanConsumer; +import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.SyncHandler; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Supplier; public class GTFluidSyncHandler extends SyncHandler { - private static final int TRY_CLICK_CONTAINER = 1; + public static final int TRY_CLICK_CONTAINER = 1; + public static final int UPDATE_TANK = 2; + public static final int UPDATE_AMOUNT = 3; + public static final int PHANTOM_SCROLL = 4; + public static final int LOCK_FLUID = 5; private final IFluidTank tank; + private Consumer jeiHandler; + private BooleanConsumer lockHandler; + private Supplier lockedFluid; + private FluidStack lastFluid; + private FluidStack phantomFluid; private boolean canDrainSlot = true; private boolean canFillSlot = true; + private boolean phantom; + private BooleanSupplier showAmount = () -> true; public GTFluidSyncHandler(IFluidTank tank) { this.tank = tank; } + @Override + public void detectAndSendChanges(boolean init) { + var current = getFluid(); + if (current == null && lastFluid == null) return; + if (current == null || lastFluid == null || lastFluid.getFluid() != current.getFluid()) { + lastFluid = current == null ? null : current.copy(); + syncToClient(UPDATE_TANK, buffer -> NetworkUtils.writeFluidStack(buffer, current)); + } else if (current.amount != lastFluid.amount) { + lastFluid.amount = current.amount; + syncToClient(UPDATE_AMOUNT, buffer -> buffer.writeInt(current.amount)); + } + } + + public void lockFluid(FluidStack stack, boolean sync) { + if (!canLockFluid()) return; + this.jeiHandler.accept(stack); + if (sync) sync(LOCK_FLUID, buffer -> { + buffer.writeBoolean(stack != null); + NetworkUtils.writeFluidStack(buffer, stack); + }); + } + + public void lockFluid(boolean locked, boolean sync) { + this.lockHandler.accept(locked); + if (sync) sync(LOCK_FLUID, buffer -> { + buffer.writeBoolean(locked); + NetworkUtils.writeFluidStack(buffer, null); + }); + } + + public GTFluidSyncHandler handleLocking(Supplier lockedFluid, Consumer jeiHandler, + BooleanConsumer lockHandler) { + this.lockedFluid = lockedFluid; + this.jeiHandler = jeiHandler; + this.lockHandler = lockHandler; + return this; + } + public FluidStack getFluid() { return this.tank.getFluid(); } + public void setFluid(FluidStack fluid) { + if (tank instanceof FluidTank fluidTank) { + fluidTank.setFluid(fluid); + } else { + tank.drain(Integer.MAX_VALUE, true); + tank.fill(fluid, true); + } + if (!isPhantom() || fluid == null) return; + if (this.phantomFluid == null || this.phantomFluid.getFluid() != fluid.getFluid()) { + this.phantomFluid = fluid; + } + } + + public void setAmount(int amount) { + if (this.tank instanceof SimpleFluidFilterReader.WritableFluidTank writableFluidTank) { + writableFluidTank.setFluidAmount(amount); + return; + } + FluidStack stack = getFluid(); + if (stack == null) return; + stack.amount = amount; + } + public int getCapacity() { return this.tank.getCapacity(); } - public GTFluidSyncHandler canDrainSlot(boolean canDrainSlot) { - this.canDrainSlot = canDrainSlot; + public GTFluidSyncHandler accessibility(boolean canDrain, boolean canFill) { + this.canDrainSlot = canDrain; + this.canFillSlot = canFill; return this; } @@ -46,28 +128,183 @@ public boolean canDrainSlot() { return this.canDrainSlot; } - public GTFluidSyncHandler canFillSlot(boolean canFillSlot) { - this.canFillSlot = canFillSlot; + public boolean canFillSlot() { + return this.canFillSlot; + } + + public GTFluidSyncHandler phantom(boolean phantom) { + this.phantom = phantom; + if (phantom && this.tank.getFluid() != null) + this.phantomFluid = this.tank.getFluid().copy(); return this; } - public boolean canFillSlot() { - return this.canFillSlot; + public boolean isPhantom() { + return phantom; + } + + public GTFluidSyncHandler showAmount(boolean showAmount) { + this.showAmount = () -> showAmount; + return this; + } + + public GTFluidSyncHandler showAmount(BooleanSupplier showAmount) { + this.showAmount = showAmount; + return this; + } + + public boolean showAmount() { + if (!isPhantom() && phantomFluid != null) + return false; + return this.showAmount.getAsBoolean(); + } + + public @NotNull String getFormattedFluidAmount() { + var tankFluid = this.tank.getFluid(); + return String.format("%,d", tankFluid == null ? 0 : tankFluid.amount); + } + + public @Nullable String getFluidLocalizedName() { + var tankFluid = this.tank.getFluid(); + if (tankFluid == null && canLockFluid()) + tankFluid = this.lockedFluid.get(); + + return tankFluid == null ? null : tankFluid.getLocalizedName(); } @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == TRY_CLICK_CONTAINER) { - replaceCursorItemStack(NetworkUtils.readItemStack(buf)); + switch (id) { + case TRY_CLICK_CONTAINER -> replaceCursorItemStack(NetworkUtils.readItemStack(buf)); + case UPDATE_TANK -> setFluid(NetworkUtils.readFluidStack(buf)); + case UPDATE_AMOUNT -> setAmount(buf.readInt()); + case LOCK_FLUID -> lockFluid(NetworkUtils.readFluidStack(buf), false); } } + public void handlePhantomScroll(MouseData data) { + syncToServer(PHANTOM_SCROLL, data::writeToPacket); + } + + public void handleClick(MouseData data) { + syncToServer(TRY_CLICK_CONTAINER, data::writeToPacket); + } + @Override public void readOnServer(int id, PacketBuffer buf) { if (id == TRY_CLICK_CONTAINER) { - var stack = tryClickContainer(buf.readBoolean()); - if (!stack.isEmpty()) - syncToClient(TRY_CLICK_CONTAINER, buffer -> NetworkUtils.writeItemStack(buffer, stack)); + var data = MouseData.readPacket(buf); + if (isPhantom()) { + tryClickPhantom(data); + } else { + var stack = tryClickContainer(data.mouseButton == 0); + if (!stack.isEmpty()) + syncToClient(TRY_CLICK_CONTAINER, buffer -> NetworkUtils.writeItemStack(buffer, stack)); + } + } else if (id == UPDATE_TANK) { + var fluid = NetworkUtils.readFluidStack(buf); + setFluid(fluid); + } else if (id == PHANTOM_SCROLL) { + tryScrollPhantom(MouseData.readPacket(buf)); + } else if (id == LOCK_FLUID) { + boolean locked = buf.readBoolean(); + var fluidStack = NetworkUtils.readFluidStack(buf); + if (fluidStack == null) { + this.lockHandler.accept(locked); + } else { + this.jeiHandler.accept(fluidStack); + } + } + } + + public void tryClickPhantom(MouseData data) { + EntityPlayer player = getSyncManager().getPlayer(); + ItemStack currentStack = player.inventory.getItemStack(); + FluidStack currentFluid = this.tank.getFluid(); + if (currentStack.getCount() > 1) currentStack = GTUtility.copy(1, currentStack); + var fluidHandlerItem = FluidUtil.getFluidHandler(currentStack); + + switch (data.mouseButton) { + case 0 -> { + if (currentStack.isEmpty() || fluidHandlerItem == null) { + if (this.canDrainSlot()) { + this.tank.drain(data.shift ? Integer.MAX_VALUE : 1000, true); + } + } else { + FluidStack cellFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); + if ((this.showAmount.getAsBoolean() || currentFluid == null) && cellFluid != null) { + if (this.canFillSlot()) { + if (!this.showAmount.getAsBoolean()) { + cellFluid.amount = 1; + } + if (this.tank.fill(cellFluid, true) > 0) { + this.phantomFluid = cellFluid.copy(); + } + } + } else { + if (this.canDrainSlot()) { + this.tank.drain(data.shift ? Integer.MAX_VALUE : 1000, true); + } + } + } + } + case 1 -> { + if (this.canFillSlot()) { + if (currentFluid != null) { + if (this.showAmount.getAsBoolean()) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = 1000; + this.tank.fill(toFill, true); + } + } else if (this.phantomFluid != null) { + FluidStack toFill = this.phantomFluid.copy(); + toFill.amount = this.showAmount.getAsBoolean() ? 1 : toFill.amount; + this.tank.fill(toFill, true); + } + } + } + case 2 -> { + if (currentFluid != null && canDrainSlot()) + this.tank.drain(data.shift ? Integer.MAX_VALUE : 1000, true); + } + } + } + + public void tryScrollPhantom(MouseData mouseData) { + FluidStack currentFluid = this.tank.getFluid(); + int amount = mouseData.mouseButton; + if (!this.showAmount()) { + int newAmt = amount == 1 ? 1 : 0; + if (newAmt == 0) { + setFluid(null); + } else if (currentFluid != null && currentFluid.amount != newAmt) { + setAmount(newAmt); + } + return; + } + if (mouseData.shift) { + amount *= 10; + } + if (mouseData.ctrl) { + amount *= 100; + } + if (mouseData.alt) { + amount *= 1000; + } + if (currentFluid == null) { + if (amount > 0 && this.phantomFluid != null) { + FluidStack toFill = this.phantomFluid.copy(); + toFill.amount = this.showAmount() ? amount : 1; + this.tank.fill(toFill, true); + } + return; + } + if (amount > 0) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = amount; + this.tank.fill(toFill, true); + } else if (amount < 0) { + this.tank.drain(-amount, true); } } @@ -77,8 +314,7 @@ public ItemStack tryClickContainer(boolean tryFillAll) { return ItemStack.EMPTY; ItemStack useStack = GTUtility.copy(1, playerHeldStack); - IFluidHandlerItem fluidHandlerItem = useStack - .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + var fluidHandlerItem = FluidUtil.getFluidHandler(useStack); if (fluidHandlerItem == null) return ItemStack.EMPTY; FluidStack tankFluid = tank.getFluid(); @@ -88,20 +324,24 @@ public ItemStack tryClickContainer(boolean tryFillAll) { if (tankFluid == null && heldFluid == null) return ItemStack.EMPTY; + ItemStack returnable = ItemStack.EMPTY; + // tank is empty, try to fill tank if (canFillSlot && tankFluid == null) { - return fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); + returnable = fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); // hand is empty, try to drain tank } else if (canDrainSlot && heldFluid == null) { - return drainTankFromStack(fluidHandlerItem, tankFluid, tryFillAll); + returnable = drainTankIntoStack(fluidHandlerItem, tankFluid, tryFillAll); // neither is empty but tank is not full, try to fill tank } else if (canFillSlot && tank.getFluidAmount() < tank.getCapacity() && heldFluid != null) { - return fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); + returnable = fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); } - return ItemStack.EMPTY; + syncToClient(UPDATE_TANK, buffer -> NetworkUtils.writeFluidStack(buffer, tank.getFluid())); + + return returnable; } private ItemStack fillTankFromStack(IFluidHandlerItem fluidHandler, @NotNull FluidStack heldFluid, @@ -141,30 +381,31 @@ private ItemStack fillTankFromStack(IFluidHandlerItem fluidHandler, @NotNull Flu return itemStackEmptied; } - private ItemStack drainTankFromStack(IFluidHandlerItem fluidHandler, FluidStack tankFluid, boolean tryFillAll) { + private ItemStack drainTankIntoStack(IFluidHandlerItem fluidHandler, FluidStack tankFluid, boolean tryFillAll) { ItemStack heldItem = getSyncManager().getCursorItem(); if (heldItem.isEmpty()) return ItemStack.EMPTY; - ItemStack fluidContainer = fluidHandler.getContainer(); + ItemStack fluidContainer = ItemStack.EMPTY; int filled = fluidHandler.fill(tankFluid, false); + int stored = tankFluid.amount; if (filled > 0) { - tank.drain(filled, true); fluidHandler.fill(tankFluid, true); + tank.drain(filled, true); + fluidContainer = fluidHandler.getContainer(); if (tryFillAll) { // Determine how many more items we can fill. One item is already filled. // Integer division means it will round down, so it will only fill equivalent fluid amounts. // For example: // Click with 3 cells, with 2500L of fluid in the tank. // 2 cells will be filled, and 500L will be left behind in the tank. - int additional = Math.min(heldItem.getCount(), tankFluid.amount / filled) - 1; + int additional = Math.min(heldItem.getCount(), stored / filled) - 1; tank.drain(filled * additional, true); fluidContainer.grow(additional); } replaceCursorItemStack(fluidContainer); playSound(tankFluid, false); - return fluidContainer; } - return ItemStack.EMPTY; + return fluidContainer; } /** @@ -221,4 +462,33 @@ private void playSound(FluidStack fluid, boolean fill) { player.world.playSound(null, player.posX, player.posY + 0.5, player.posZ, soundEvent, SoundCategory.PLAYERS, 1.0F, 1.0F); } + + public FluidStack getPhantomFluid() { + return isPhantom() ? phantomFluid : null; + } + + public FluidStack getLockedFluid() { + return !isPhantom() && canLockFluid() ? lockedFluid.get() : null; + } + + public boolean canLockFluid() { + return jeiHandler != null && lockHandler != null && lockedFluid != null; + } + + public void toggleLockFluid() { + var cursorItem = getSyncManager().getCursorItem(); + if (getLockedFluid() == null) { + if (cursorItem.isEmpty()) return; + if (cursorItem.getCount() > 1) cursorItem = GTUtility.copy(1, cursorItem); + + var fluidHandler = FluidUtil.getFluidHandler(cursorItem); + if (fluidHandler == null) return; + + var fluidStack = fluidHandler.getTankProperties()[0].getContents(); + if (fluidStack == null) return; + lockFluid(fluidStack.copy(), true); + } else if (cursorItem.isEmpty()) { + lockFluid(null, true); + } + } } diff --git a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java index 448740e7147..aa692fd8583 100644 --- a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java +++ b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java @@ -6,17 +6,16 @@ import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.client.utils.TooltipHelper; -import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.items.IItemHandler; import com.cleanroommc.modularui.api.IPanelHandler; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.screen.ModularScreen; -import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.ItemSlotSH; import com.cleanroommc.modularui.widgets.ButtonWidget; @@ -27,7 +26,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class GhostCircuitSlotWidget extends ItemSlot { @@ -35,6 +33,7 @@ public class GhostCircuitSlotWidget extends ItemSlot { private static final int SYNC_CIRCUIT_INDEX = 10; public GhostCircuitSlotWidget() { + super(); tooltipBuilder(this::getCircuitSlotTooltip); } @@ -67,21 +66,15 @@ public ItemSlot slot(ModularSlot slot) { return this; } - @Override - protected List getItemTooltip(ItemStack stack) { - // we don't want the item tooltip - return Collections.emptyList(); - } - - protected void getCircuitSlotTooltip(@NotNull Tooltip tooltip) { + protected void getCircuitSlotTooltip(@NotNull RichTooltip tooltip) { String configString; int value = getSyncHandler().getGhostCircuitHandler().getCircuitValue(); if (value == GhostCircuitItemStackHandler.NO_CONFIG) { - configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value").getFormattedText(); + configString = IKey.lang("gregtech.gui.configurator_slot.no_value").get(); } else { configString = String.valueOf(value); } - + tooltip.clearText(); tooltip.addLine(IKey.lang("gregtech.gui.configurator_slot.tooltip", configString)); } @@ -105,37 +98,38 @@ private boolean isSelectorPanelOpen() { private void createSelectorPanel() { ItemDrawable circuitPreview = new ItemDrawable(getSyncHandler().getSlot().getStack()); - List> options = new ArrayList<>(); - for (int i = 0; i < 4; i++) { - options.add(new ArrayList<>()); - for (int j = 0; j < 9; j++) { - int index = i * 9 + j; - if (index > 32) break; - options.get(i).add(new ButtonWidget<>() - .size(18) - .background(GTGuiTextures.SLOT, new ItemDrawable( - IntCircuitIngredient.getIntegratedCircuit(index)).asIcon()) - .disableHoverBackground() - .onMousePressed(mouseButton -> { - getSyncHandler().syncToServer(SYNC_CIRCUIT_INDEX, buf -> buf.writeShort(index)); - circuitPreview.setItem(IntCircuitIngredient.getIntegratedCircuit(index)); - return true; - })); + IPanelHandler.simple(getPanel(), (mainPanel, player) -> { + var panel = GTGuis.createPopupPanel("circuit_selector", 176, 120); + List> options = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + options.add(new ArrayList<>()); + for (int j = 0; j < 9; j++) { + int index = i * 9 + j; + if (index > 32) break; + options.get(i).add(new ButtonWidget<>() + .size(18) + .background(GTGuiTextures.SLOT, new ItemDrawable( + IntCircuitIngredient.getIntegratedCircuit(index)).asIcon()) + .disableHoverBackground() + .onMousePressed(mouseButton -> { + getSyncHandler().syncToServer(SYNC_CIRCUIT_INDEX, buf -> buf.writeShort(index)); + circuitPreview.setItem(IntCircuitIngredient.getIntegratedCircuit(index)); + if (Interactable.hasShiftDown()) panel.animateClose(); + return true; + })); + } } - } - - IPanelHandler.simple(getPanel(), (mainPanel, player) -> GTGuis.createPopupPanel("circuit_selector", 176, 120) - .child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) - .child(circuitPreview.asIcon().size(16).asWidget() - .size(18) - .top(19).alignX(0.5f) - .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) - .child(new Grid() - .left(7).right(7).top(41).height(4 * 18) - .matrix(options) - .minColWidth(18).minRowHeight(18) - .minElementMargin(0, 0))) - .openPanel(); + return panel.child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) + .child(circuitPreview.asIcon().size(16).asWidget() + .size(18) + .top(19).alignX(0.5f) + .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) + .child(new Grid() + .left(7).right(7).top(41).height(4 * 18) + .matrix(options) + .minColWidth(18).minRowHeight(18) + .minElementMargin(0, 0)); + }, true).openPanel(); } private static class GhostCircuitSyncHandler extends ItemSlotSH { diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 798c0000e8c..1fa4e43dffe 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -45,6 +45,7 @@ import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -55,8 +56,7 @@ import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ButtonWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; @@ -510,12 +510,12 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan getItemFilterContainer().setMaxTransferSize(getMaxStackSize()); return panel.child(CoverWithUI.createTitleRow(getPickItem())) - .child(createUI(panel, guiSyncManager)) + .child(createUI(guiData, guiSyncManager)) .bindPlayerInventory(); } - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { - var column = new Column().top(24).margin(7, 0) + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { + var column = Flow.column().top(24).margin(7, 0) .widthRel(1f).coverChildrenHeight(); EnumSyncValue manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, @@ -525,7 +525,6 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager this::getConveyorMode, this::setConveyorMode); IntSyncValue throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); - throughput.updateCacheFromSource(true); StringSyncValue formattedThroughput = new StringSyncValue(throughput::getStringValue, throughput::setStringValue); @@ -539,7 +538,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager.syncValue("throughput", throughput); if (createThroughputRow()) - column.child(new Row().coverChildrenHeight() + column.child(Flow.row().coverChildrenHeight() .marginBottom(2).widthRel(1f) .child(new ButtonWidget<>() .left(0).width(18) @@ -567,7 +566,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); if (createFilterRow()) - column.child(getItemFilterContainer().initUI(mainPanel, guiSyncManager)); + column.child(getItemFilterContainer().initUI(data, guiSyncManager)); if (createManualIOModeRow()) column.child(new EnumRowBuilder<>(ManualImportExportMode.class) diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index 85b39ca1a9d..a0b6585ebd7 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -43,8 +43,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -154,13 +153,13 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan return getFilter().createPanel(guiSyncManager) .size(176, 212).padding(7) .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack())) - .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(Flow.column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() .child(new EnumRowBuilder<>(FluidFilterMode.class) .value(filteringMode) .lang("cover.filter.mode.title") .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) .build()) - .child(new Row() + .child(Flow.row() .marginBottom(2) .widthRel(1f) .coverChildrenHeight() diff --git a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java index 27122cdfa7a..141b51e0552 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java +++ b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java @@ -20,6 +20,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -247,7 +248,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); transferMode.updateCacheFromSource(true); syncManager.syncValue("transfer_mode", transferMode); @@ -259,7 +260,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager sync var filterTransferSize = new StringSyncValue(this::getStringTransferRate, this::setStringTransferRate); filterTransferSize.updateCacheFromSource(true); - return super.createUI(mainPanel, syncManager) + return super.createUI(data, syncManager) .child(new EnumRowBuilder<>(TransferMode.class) .value(transferMode) .lang("cover.generic.transfer_mode") diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java index c6aa519660c..4bd8472b55f 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java @@ -25,6 +25,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -32,7 +33,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; public class CoverFluidVoiding extends CoverPump { @@ -76,11 +77,11 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); - return super.createUI(mainPanel, syncManager) - .child(new Row().height(18).widthRel(1f) + return super.createUI(data, syncManager) + .child(Flow.row().height(18).widthRel(1f) .marginBottom(2) .child(new ToggleButton() .value(isWorking) diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java index 80b7bb45564..b6a9e1cd1e5 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java @@ -20,6 +20,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -105,7 +106,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); syncManager.syncValue("voiding_mode", voidingMode); @@ -118,7 +119,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager sync transferTextField.setEnabled(this.fluidFilterContainer.showGlobalTransferLimitSlider() && this.voidingMode == VoidingMode.VOID_OVERFLOW); - return super.createUI(mainPanel, syncManager) + return super.createUI(data, syncManager) .child(new EnumRowBuilder<>(VoidingMode.class) .value(voidingMode) .lang("cover.voiding.voiding_mode") diff --git a/src/main/java/gregtech/common/covers/CoverItemFilter.java b/src/main/java/gregtech/common/covers/CoverItemFilter.java index 18e6432bc07..8c667ad8ce7 100644 --- a/src/main/java/gregtech/common/covers/CoverItemFilter.java +++ b/src/main/java/gregtech/common/covers/CoverItemFilter.java @@ -42,8 +42,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -156,13 +155,13 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan return getFilter().createPanel(guiSyncManager) .size(176, 212).padding(7) .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack()).left(4)) - .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(Flow.column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() .child(new EnumRowBuilder<>(ItemFilterMode.class) .value(filteringMode) .lang("cover.filter.mode.title") .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) .build()) - .child(new Row() + .child(Flow.row() .marginBottom(2) .widthRel(1f) .coverChildrenHeight() diff --git a/src/main/java/gregtech/common/covers/CoverItemVoiding.java b/src/main/java/gregtech/common/covers/CoverItemVoiding.java index 35a64252725..e8129ec11f3 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoiding.java @@ -22,6 +22,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -29,8 +30,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; public class CoverItemVoiding extends CoverConveyor { @@ -78,11 +78,11 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); - return super.createUI(mainPanel, guiSyncManager) - .child(new Row().height(18).widthRel(1f) + return super.createUI(data, guiSyncManager) + .child(Flow.row().height(18).widthRel(1f) .marginBottom(2) .child(new ToggleButton() .value(isWorking) diff --git a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java index 4a062735ae3..b739e7e6e1f 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java @@ -17,6 +17,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -24,8 +25,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; @@ -94,7 +94,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); guiSyncManager.syncValue("voiding_mode", voidingMode); @@ -106,13 +106,13 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager transferTextField.setEnabled(this.itemFilterContainer.showGlobalTransferLimitSlider() && this.voidingMode == VoidingMode.VOID_OVERFLOW); - return super.createUI(mainPanel, guiSyncManager) + return super.createUI(data, guiSyncManager) .child(new EnumRowBuilder<>(VoidingMode.class) .value(voidingMode) .lang("cover.voiding.voiding_mode") .overlay(16, GTGuiTextures.VOIDING_MODE_OVERLAY) .build()) - .child(new Row().right(0).coverChildrenHeight() + .child(Flow.row().right(0).coverChildrenHeight() .child(transferTextField .setEnabledIf(w -> this.itemFilterContainer.showGlobalTransferLimitSlider() && this.voidingMode == VoidingMode.VOID_OVERFLOW) diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java index 2626d8f3acd..545f3cde52e 100644 --- a/src/main/java/gregtech/common/covers/CoverMachineController.java +++ b/src/main/java/gregtech/common/covers/CoverMachineController.java @@ -32,7 +32,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -121,7 +121,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan return GTGuis.createPanel(this, 176, 112) .child(CoverWithUI.createTitleRow(getPickItem())) - .child(new Column() + .child(Flow.column() .widthRel(1.0f).margin(7, 0) .top(24).coverChildrenHeight() @@ -151,7 +151,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan // Controlling selector .child(createSettingsRow().height(16 + 2 + 16) - .child(new Column().heightRel(1.0f).coverChildrenWidth() + .child(Flow.column().heightRel(1.0f).coverChildrenWidth() .child(IKey.lang("cover.machine_controller.control").asWidget() .left(0).height(16).marginBottom(2)) .child(modeButton(controllerModeValue, ControllerMode.MACHINE).left(0))) @@ -169,8 +169,8 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan .right(0)))); } - private Column modeColumn(EnumSyncValue syncValue, ControllerMode mode, IKey title) { - return new Column().coverChildrenHeight().width(18) + private Flow modeColumn(EnumSyncValue syncValue, ControllerMode mode, IKey title) { + return Flow.column().coverChildrenHeight().width(18) .child(title.asWidget().size(16).marginBottom(2).alignment(Alignment.Center)) .child(modeButton(syncValue, mode)); } diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index 2fdb55e2cdd..b57e5a33545 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -43,6 +43,7 @@ import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -53,8 +54,7 @@ import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ButtonWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -196,41 +196,36 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan getFluidFilterContainer().setMaxTransferSize(getMaxTransferRate()); return panel.child(CoverWithUI.createTitleRow(getPickItem())) - .child(createUI(panel, guiSyncManager)) + .child(createUI(guiData, guiSyncManager)) .bindPlayerInventory(); } - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode); - manualIOmode.updateCacheFromSource(true); var throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); - throughput.updateCacheFromSource(true); var throughputString = new StringSyncValue( - throughput::getStringValue, - throughput::setStringValue); - throughputString.updateCacheFromSource(true); + throughput::getStringValue, throughput::setStringValue); var pumpMode = new EnumSyncValue<>(PumpMode.class, this::getPumpMode, this::setPumpMode); - pumpMode.updateCacheFromSource(true); syncManager.syncValue("manual_io", manualIOmode); syncManager.syncValue("pump_mode", pumpMode); syncManager.syncValue("throughput", throughput); - var column = new Column().top(24).margin(7, 0) + var column = Flow.column().top(24).margin(7, 0) .widthRel(1f).coverChildrenHeight(); if (createThroughputRow()) - column.child(new Row().coverChildrenHeight() + column.child(Flow.row().coverChildrenHeight() .marginBottom(2).widthRel(1f) .child(new ButtonWidget<>() .left(0).width(18) .onMousePressed(mouseButton -> { int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); - throughput.setValue(val, true, true); + throughput.setValue(val); Interactable.playButtonClickSound(); return true; }) @@ -245,15 +240,14 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager sync .right(0).width(18) .onMousePressed(mouseButton -> { int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); - throughput.setValue(val, true, true); + throughput.setValue(val); Interactable.playButtonClickSound(); return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); if (createFilterRow()) - column.child(getFluidFilterContainer() - .initUI(mainPanel, syncManager)); + column.child(getFluidFilterContainer().initUI(data, syncManager)); if (createManualIOModeRow()) column.child(new EnumRowBuilder<>(ManualImportExportMode.class) diff --git a/src/main/java/gregtech/common/covers/CoverRoboticArm.java b/src/main/java/gregtech/common/covers/CoverRoboticArm.java index 22047e6db2e..b1b99657adf 100644 --- a/src/main/java/gregtech/common/covers/CoverRoboticArm.java +++ b/src/main/java/gregtech/common/covers/CoverRoboticArm.java @@ -19,6 +19,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -26,8 +27,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; @@ -197,7 +197,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { EnumSyncValue transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); guiSyncManager.syncValue("transfer_mode", transferMode); @@ -207,13 +207,13 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager s -> this.itemFilterContainer.setTransferSize(Integer.parseInt(s))); filterTransferSize.updateCacheFromSource(true); - return super.createUI(mainPanel, guiSyncManager) + return super.createUI(data, guiSyncManager) .child(new EnumRowBuilder<>(TransferMode.class) .value(transferMode) .lang("cover.generic.transfer_mode") .overlay(GTGuiTextures.TRANSFER_MODE_OVERLAY) .build()) - .child(new Row().right(0).coverChildrenHeight() + .child(Flow.row().right(0).coverChildrenHeight() .child(new TextFieldWidget().widthRel(0.5f).right(0) .setEnabledIf(w -> shouldDisplayAmountSlider()) .setNumbers(0, Integer.MAX_VALUE) diff --git a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java index eb5c6a81d9d..53701cacd6b 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java @@ -30,6 +30,7 @@ import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.ModularPanel; @@ -38,19 +39,17 @@ import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.ListWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.lwjgl.input.Keyboard; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -141,18 +140,20 @@ public boolean usesMui2() { public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { var panel = GTGuis.createPanel(this, 176, 192); + this.playerUUID = guiData.getPlayer().getUniqueID(); + return panel.child(CoverWithUI.createTitleRow(getPickItem())) - .child(createWidgets(panel, guiSyncManager)) + .child(createWidgets(guiData, guiSyncManager)) .bindPlayerInventory(); } - protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) { + protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { var name = new StringSyncValue(this::getColorStr, this::updateColor); - var entrySelectorSH = createEntrySelector(panel); - syncManager.syncValue("entry_selector", entrySelectorSH); + // todo unneeded cast in mui2 rc3 + var entrySelectorSH = (PanelSyncHandler) syncManager.panel("entry_selector", entrySelector(getType()), true); - return new Column().coverChildrenHeight().top(24) + return Flow.column().coverChildrenHeight().top(24) .margin(7, 0).widthRel(1f) .child(new Row().marginBottom(2) .coverChildrenHeight() @@ -176,18 +177,14 @@ protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) } else { entrySelectorSH.openPanel(); } - Interactable.playButtonClickSound(); return true; }))) .child(createIoRow()); } - protected abstract PanelSyncHandler createEntrySelector(ModularPanel panel); - protected abstract IWidget createEntrySlot(); protected IWidget createColorIcon() { - // todo color selector popup panel return new DynamicDrawable(() -> new Rectangle() .setColor(this.activeEntry.getColor()) .asIcon().size(16)) @@ -198,10 +195,8 @@ protected IWidget createColorIcon() { } protected IWidget createPrivateButton() { - var isPrivate = new BooleanSyncValue(this::isPrivate, this::setPrivate); - isPrivate.updateCacheFromSource(true); - return new ToggleButton() + .value(new BooleanSyncValue(this::isPrivate, this::setPrivate)) .tooltip(tooltip -> tooltip.setAutoUpdate(true)) .background(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) .hoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) @@ -210,17 +205,14 @@ protected IWidget createPrivateButton() { .tooltipBuilder(tooltip -> tooltip.addLine(IKey.lang(this.isPrivate ? "cover.ender_fluid_link.private.tooltip.enabled" : "cover.ender_fluid_link.private.tooltip.disabled"))) - .marginRight(2) - .value(isPrivate); + .marginRight(2); } protected IWidget createIoRow() { - var ioEnabled = new BooleanSyncValue(this::isIoEnabled, this::setIoEnabled); - - return new Row().marginBottom(2) + return Flow.row().marginBottom(2) .coverChildrenHeight() .child(new ToggleButton() - .value(ioEnabled) + .value(new BooleanSyncValue(this::isIoEnabled, this::setIoEnabled)) .overlay(IKey.dynamic(() -> IKey.lang(this.ioEnabled ? "behaviour.soft_hammer.enabled" : "behaviour.soft_hammer.disabled").get()) @@ -291,45 +283,16 @@ public void writeToNBT(@NotNull NBTTagCompound nbt) { nbt.setInteger("Frequency", activeEntry.getColor()); } - protected abstract class EntrySelectorSH extends PanelSyncHandler { - - private static final int TRACK_SUBPANELS = 3; - private static final int DELETE_ENTRY = 1; - private final EntryTypes type; - private final ModularPanel mainPanel; - private static final String PANEL_NAME = "entry_selector"; - private final Set opened = new HashSet<>(); - protected UUID playerUUID; - - protected EntrySelectorSH(ModularPanel mainPanel, EntryTypes type) { - super(mainPanel, EntrySelectorSH::defaultPanel); - this.type = type; - this.mainPanel = mainPanel; - } - - @Override - public void init(String key, PanelSyncManager syncManager) { - super.init(key, syncManager); - this.playerUUID = syncManager.getPlayer().getUniqueID(); - } - - private static ModularPanel defaultPanel(PanelSyncManager syncManager, PanelSyncHandler syncHandler) { - return GTGuis.createPopupPanel(PANEL_NAME, 168, 112); - } - - public UUID getPlayerUUID() { - return isPrivate ? playerUUID : null; - } - - @Override - public ModularPanel createUI(PanelSyncManager syncManager) { - List names = new ArrayList<>(VirtualEnderRegistry.getEntryNames(getPlayerUUID(), type)); - return super.createUI(syncManager) + protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type) { + return (syncManager, syncHandler) -> { + Set names = VirtualEnderRegistry.getEntryNames(getOwner(), type); + return GTGuis.createPopupPanel("entry_selector", 168, 112) .child(IKey.lang("cover.generic.ender.known_channels") - .color(UI_TITLE_COLOR).asWidget() + .color(UI_TITLE_COLOR) + .asWidget() .top(6) .left(4)) - .child(ListWidget.builder(names, name -> createRow(name, this.mainPanel, syncManager)) + .child(ListWidget.builder(names, name -> createRow(name, syncManager, type)) .background(GTGuiTextures.DISPLAY.asIcon() .width(168 - 8) .height(112 - 20)) @@ -337,177 +300,122 @@ public ModularPanel createUI(PanelSyncManager syncManager) { .size(168 - 12, 112 - 24) .left(4) .bottom(6)); - } + }; + } - protected IWidget createRow(String name, ModularPanel mainPanel, PanelSyncManager syncManager) { - T entry = VirtualEnderRegistry.getEntry(getPlayerUUID(), this.type, name); - String key = String.format("entry#%s_description", entry.getColorStr()); - var entryDescriptionSH = new EntryDescriptionSH(mainPanel, key, entry); - syncManager.syncValue(key, isPrivate ? 1 : 0, entryDescriptionSH); - - return new Row() - .left(4) - .marginBottom(2) - .height(18) - .widthRel(0.98f) - .setEnabledIf(row -> VirtualEnderRegistry.hasEntry(getOwner(), this.type, name)) - .child(new Rectangle() - .setColor(entry.getColor()) + protected PanelSyncHandler.IPanelBuilder entryDescription(String key, T entry) { + return (syncManager, syncHandler) -> { + var sync = new StringSyncValue(entry::getDescription, entry::setDescription); + return GTGuis.createPopupPanel(key, 168, 36 + 6) + .child(IKey.lang("cover.generic.ender.set_description.title", entry.getColorStr()) + .color(UI_TITLE_COLOR) .asWidget() - .marginRight(4) - .size(16) - .background(GTGuiTextures.SLOT.asIcon().size(18)) - .top(1)) - .child(new InteractableText<>(entry, CoverAbstractEnderLink.this::updateColor) - .tooltip(tooltip -> tooltip.setAutoUpdate(true)) - .tooltipBuilder(tooltip -> { - String desc = entry.getDescription(); - if (!desc.isEmpty()) - tooltip.addLine(desc); - }) - .width(64) - .height(16) - .top(1) - .marginRight(4)) - .child(new ButtonWidget<>() - .overlay(GuiTextures.GEAR) - .addTooltipLine(IKey.lang("cover.generic.ender.set_description.tooltip")) - .onMousePressed(i -> { - // open entry settings - if (entryDescriptionSH.isPanelOpen()) { - entryDescriptionSH.closePanel(); - } else { - entryDescriptionSH.openPanel(); + .left(4) + .top(6)) + .child(new TextFieldWidget() { + + // todo move this to new class? + @Override + public @NotNull Result onKeyPressed(char character, int keyCode) { + var result = super.onKeyPressed(character, keyCode); + if (result == Result.SUCCESS && keyCode == Keyboard.KEY_RETURN) { + sync.setStringValue(getText()); + if (syncHandler.isPanelOpen()) { + syncHandler.closePanel(); } - Interactable.playButtonClickSound(); - return true; - })) - .child(createSlotWidget(entry)) - .child(new ButtonWidget<>() - .overlay(GTGuiTextures.BUTTON_CROSS) - .setEnabledIf(w -> !Objects.equals(entry.getColor(), activeEntry.getColor())) - .addTooltipLine(IKey.lang("cover.generic.ender.delete_entry")) - .onMousePressed(i -> { - // todo option to force delete, maybe as a popup? - deleteEntry(getPlayerUUID(), name); - syncToServer(1, buffer -> { - NetworkUtils.writeStringSafe(buffer, getPlayerUUID().toString()); - NetworkUtils.writeStringSafe(buffer, name); - }); - Interactable.playButtonClickSound(); - return true; - })); - } + } + return result; + } + }.setTextColor(Color.WHITE.darker(1)) + .value(sync) + .widthRel(0.95f) + .height(18) + .alignX(0.5f) + .bottom(6)); + }; + } - @Override - public void closePanel() { - var manager = getSyncManager().getModularSyncManager().getPanelSyncManager(PANEL_NAME); - for (var key : opened) { - if (manager.getSyncHandler(key) instanceof PanelSyncHandler psh) { - psh.closePanel(); - } - } - super.closePanel(); - } + protected IWidget createRow(final String name, final PanelSyncManager syncManager, final EntryTypes type) { + final T entry = VirtualEnderRegistry.getEntry(getOwner(), type, name); + var key = String.format("entry#%s_description", entry.getColorStr()); + var syncKey = PanelSyncManager.makeSyncKey(key, isPrivate ? 1 : 0); + final var panelHandler = (PanelSyncHandler) syncManager.panel(syncKey, + entryDescription(key, entry), true); + final var syncHandler = new EnderCoverSyncHandler(); + syncManager.syncValue(key + "_handler", syncHandler); + + return Flow.row() + .left(4) + .marginBottom(2) + .height(18) + .widthRel(0.98f) + .setEnabledIf(row -> VirtualEnderRegistry.hasEntry(getOwner(), type, name)) + .child(new Rectangle() + .setColor(entry.getColor()) + .asWidget() + .marginRight(4) + .size(16) + .background(GTGuiTextures.SLOT.asIcon().size(18)) + .top(1)) + .child(new InteractableText<>(entry, this::updateColor) + .tooltip(tooltip -> tooltip.setAutoUpdate(true)) + .tooltipBuilder(tooltip -> { + String desc = entry.getDescription(); + if (!desc.isEmpty()) tooltip.add(desc); + }) + .width(64) + .height(16) + .top(1) + .marginRight(4)) + .child(new ButtonWidget<>() + .overlay(GuiTextures.GEAR) + .addTooltipLine(IKey.lang("cover.generic.ender.set_description.tooltip")) + .onMousePressed(i -> { + // open entry settings + if (panelHandler.isPanelOpen()) { + panelHandler.closePanel(); + } else { + panelHandler.openPanel(); + } + return true; + })) + .child(createSlotWidget(entry)) + .child(new ButtonWidget<>() + .overlay(GTGuiTextures.BUTTON_CROSS) + .setEnabledIf(w -> !Objects.equals(entry.getColor(), activeEntry.getColor())) + .addTooltipLine(IKey.lang("cover.generic.ender.delete_entry")) + .onMousePressed(i -> { + // todo option to force delete, maybe as a popup? + deleteEntry(getOwner(), name); + syncHandler.syncToServer(1, buffer -> { + NetworkUtils.writeStringSafe(buffer, + getOwner() == null ? "null" : getOwner().toString()); + NetworkUtils.writeStringSafe(buffer, name); + }); + Interactable.playButtonClickSound(); + return true; + })); + } - @Override - @SuppressWarnings("UnstableApiUsage") - public void closePanelInternal() { - var manager = getSyncManager().getModularSyncManager().getPanelSyncManager(PANEL_NAME); - for (var key : opened) { - if (manager.getSyncHandler(key) instanceof PanelSyncHandler psh) { - psh.closePanel(); - } - } - super.closePanelInternal(); - } + protected abstract IWidget createSlotWidget(T entry); + + protected abstract void deleteEntry(UUID player, String name); + + private final class EnderCoverSyncHandler extends SyncHandler { + + private static final int DELETE_ENTRY = 1; @Override - public void readOnClient(int i, PacketBuffer packetBuffer) throws IOException { - if (i == TRACK_SUBPANELS) { - handleTracking(packetBuffer); - } - super.readOnClient(i, packetBuffer); - } + public void readOnClient(int i, PacketBuffer packetBuffer) {} @Override - public void readOnServer(int i, PacketBuffer packetBuffer) throws IOException { - if (i == TRACK_SUBPANELS) { - handleTracking(packetBuffer); - } - super.readOnServer(i, packetBuffer); + public void readOnServer(int i, PacketBuffer packetBuffer) { if (i == DELETE_ENTRY) { - UUID uuid = UUID.fromString(NetworkUtils.readStringSafe(packetBuffer)); + var s = NetworkUtils.readStringSafe(packetBuffer); + UUID uuid = "null".equals(s) ? null : UUID.fromString(s); String name = NetworkUtils.readStringSafe(packetBuffer); deleteEntry(uuid, name); } } - - private void handleTracking(PacketBuffer buffer) { - boolean add = buffer.readBoolean(); - String key = NetworkUtils.readStringSafe(buffer); - if (key != null) { - if (add) opened.add(key); - else opened.remove(key); - } - } - - private class EntryDescriptionSH extends PanelSyncHandler { - - /** - * Creates a PanelSyncHandler - * - * @param mainPanel the main panel of the current GUI - */ - public EntryDescriptionSH(ModularPanel mainPanel, String key, VirtualEntry entry) { - super(mainPanel, (syncManager, syncHandler) -> defaultPanel(syncHandler, key, entry)); - } - - private static ModularPanel defaultPanel(@NotNull PanelSyncHandler syncHandler, String key, - VirtualEntry entry) { - return GTGuis.createPopupPanel(key, 168, 36 + 6) - .child(IKey.lang("cover.generic.ender.set_description.title", entry.getColorStr()) - .color(UI_TITLE_COLOR) - .asWidget() - .left(4) - .top(6)) - .child(new TextFieldWidget() - .setTextColor(Color.WHITE.darker(1)) - .widthRel(0.95f) - .height(18) - .value(new StringSyncValue(entry::getDescription, string -> { - entry.setDescription(string); - if (syncHandler.isPanelOpen()) { - syncHandler.closePanel(); - } - })) - .alignX(0.5f) - .bottom(6)); - } - - @Override - public void openPanel() { - opened.add(getKey()); - EntrySelectorSH.this.sync(3, buffer -> { - buffer.writeBoolean(true); - NetworkUtils.writeStringSafe(buffer, getKey()); - }); - super.openPanel(); - } - - @Override - public void closePanel() { - opened.remove(getKey()); - EntrySelectorSH.this.sync(3, buffer -> { - buffer.writeBoolean(false); - NetworkUtils.writeStringSafe(buffer, getKey()); - }); - super.closePanel(); - } - } - - protected abstract IWidget createSlotWidget(T entry); - - protected abstract void deleteEntry(UUID player, String name); } } diff --git a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java index 27c338154b1..4c373dfd41c 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java @@ -29,11 +29,10 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.value.sync.EnumSyncValue; -import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -119,27 +118,20 @@ public CoverPump.PumpMode getPumpMode() { } @Override - protected PanelSyncHandler createEntrySelector(ModularPanel panel) { - return new EntrySelectorSH(panel, EntryTypes.ENDER_FLUID) { + protected IWidget createSlotWidget(VirtualTank entry) { + var fluidTank = GTFluidSlot.sync(entry) + .accessibility(false, false); - @Override - protected IWidget createSlotWidget(VirtualTank entry) { - var fluidTank = GTFluidSlot.sync(entry) - .canFillSlot(false) - .canDrainSlot(false); - - return new GTFluidSlot() - .size(18) - .background(GTGuiTextures.FLUID_SLOT) - .syncHandler(fluidTank) - .marginRight(2); - } + return new GTFluidSlot() + .size(18) + .background(GTGuiTextures.FLUID_SLOT) + .syncHandler(fluidTank) + .marginRight(2); + } - @Override - protected void deleteEntry(UUID uuid, String name) { - VirtualEnderRegistry.deleteEntry(uuid, getType(), name, tank -> tank.getFluidAmount() == 0); - } - }; + @Override + protected void deleteEntry(UUID uuid, String name) { + VirtualEnderRegistry.deleteEntry(uuid, getType(), name, tank -> tank.getFluidAmount() == 0); } @Override @@ -151,15 +143,15 @@ protected IWidget createEntrySlot() { .marginRight(2); } - protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) { + protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { getFluidFilterContainer().setMaxTransferSize(1); var pumpMode = new EnumSyncValue<>(CoverPump.PumpMode.class, this::getPumpMode, this::setPumpMode); syncManager.syncValue("pump_mode", pumpMode); pumpMode.updateCacheFromSource(true); - return super.createWidgets(panel, syncManager) - .child(getFluidFilterContainer().initUI(panel, syncManager)) + return super.createWidgets(data, syncManager) + .child(getFluidFilterContainer().initUI(data, syncManager)) .child(new EnumRowBuilder<>(CoverPump.PumpMode.class) .value(pumpMode) .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilter.java b/src/main/java/gregtech/common/covers/filter/BaseFilter.java index 27f6a56bccb..b0a312b6e1e 100644 --- a/src/main/java/gregtech/common/covers/filter/BaseFilter.java +++ b/src/main/java/gregtech/common/covers/filter/BaseFilter.java @@ -144,7 +144,8 @@ public IWidget createBlacklistUI() { .value(new BooleanSyncValue( this::isBlacklistFilter, this::setBlacklistFilter)) - .textureGetter(state -> GTGuiTextures.BUTTON_BLACKLIST[state]) + .stateBackground(0, GTGuiTextures.BUTTON_BLACKLIST[0]) + .stateBackground(1, GTGuiTextures.BUTTON_BLACKLIST[1]) .addTooltip(0, IKey.lang("cover.filter.blacklist.disabled")) .addTooltip(1, IKey.lang("cover.filter.blacklist.enabled"))); } diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java index 38867b542bf..7bb6c7473e3 100644 --- a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java @@ -1,5 +1,6 @@ package gregtech.common.covers.filter; +import gregtech.api.cover.CoverWithUI; import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.IDirtyNotifiable; @@ -11,16 +12,15 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiTextures; -import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.ItemSlot; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -212,17 +212,14 @@ public void handleLegacyNBT(NBTTagCompound nbt) { } /** Uses Cleanroom MUI */ - public IWidget initUI(ModularPanel main, PanelSyncManager manager) { - PanelSyncHandler panel = manager.panel("filter_panel", main, (syncManager, syncHandler) -> { + public IWidget initUI(GuiData data, PanelSyncManager manager) { + PanelSyncHandler panel = (PanelSyncHandler) manager.panel("filter_panel", (syncManager, syncHandler) -> { var filter = hasFilter() ? getFilter() : BaseFilter.ERROR_FILTER; filter.setMaxTransferSize(getMaxTransferSize()); return filter.createPopupPanel(syncManager); - }); + }, true); - var filterButton = new ButtonWidget<>(); - filterButton.setEnabled(hasFilter()); - - return new Row().coverChildrenHeight() + return Flow.row().coverChildrenHeight() .marginBottom(2).widthRel(1f) .child(new ItemSlot() .slot(SyncHandlers.itemSlot(this, 0) @@ -235,7 +232,7 @@ public IWidget initUI(ModularPanel main, PanelSyncManager manager) { })) .size(18).marginRight(2) .background(GTGuiTextures.SLOT, GTGuiTextures.FILTER_SLOT_OVERLAY.asIcon().size(16))) - .child(filterButton + .child(new ButtonWidget<>() .background(GTGuiTextures.MC_BUTTON, GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) .hoverBackground(GuiTextures.MC_BUTTON_HOVERED, GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) @@ -246,10 +243,11 @@ public IWidget initUI(ModularPanel main, PanelSyncManager manager) { } else { panel.closePanel(); } - Interactable.playButtonClickSound(); return true; })) .child(IKey.dynamic(this::getFilterName) + .color(CoverWithUI.UI_TEXT_COLOR) + .shadow(false) .alignment(Alignment.CenterRight).asWidget() .left(36).right(0).height(18)); } diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 0eec589f555..0d91fd97cf8 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -20,7 +20,7 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.UITexture; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.utils.BooleanConsumer; import com.cleanroommc.modularui.utils.Color; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; @@ -29,8 +29,7 @@ import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.CycleButtonWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; @@ -112,7 +111,7 @@ public void initUI(Consumer widgetGroup) {} var caseSensitive = new BooleanSyncValue(this.filterReader::isCaseSensitive, setCaseSensitive); var matchAll = new BooleanSyncValue(this.filterReader::shouldMatchAll, setMatchAll); - return new Column().widthRel(1f).coverChildrenHeight() + return Flow.column().widthRel(1f).coverChildrenHeight() .child(new HighlightedTextField() .setHighlightRule(this::highlightRule) .onUnfocus(() -> { @@ -123,9 +122,9 @@ public void initUI(Consumer widgetGroup) {} .setTextColor(Color.WHITE.darker(1)) .value(expression).marginBottom(4) .height(18).widthRel(1f)) - .child(new Row().coverChildrenHeight() + .child(Flow.row().coverChildrenHeight() .widthRel(1f) - .child(new Column().height(18) + .child(Flow.column().height(18) .coverChildrenWidth().marginRight(2) .child(GTGuiTextures.OREDICT_INFO.asWidget() .size(8).top(0) @@ -148,7 +147,8 @@ public void initUI(Consumer widgetGroup) {} .child(new CycleButtonWidget() .size(18).value(caseSensitive) .marginRight(2) - .textureGetter(state -> GTGuiTextures.BUTTON_CASE_SENSITIVE[state]) + .stateBackground(0, GTGuiTextures.BUTTON_CASE_SENSITIVE[0]) + .stateBackground(1, GTGuiTextures.BUTTON_CASE_SENSITIVE[1]) .addTooltip(0, IKey.lang("cover.ore_dictionary_filter.button.case_sensitive.disabled")) .addTooltip(1, @@ -156,7 +156,8 @@ public void initUI(Consumer widgetGroup) {} .child(new CycleButtonWidget() .size(18).value(matchAll) .marginRight(2) - .textureGetter(state -> GTGuiTextures.BUTTON_MATCH_ALL[state]) + .stateBackground(0, GTGuiTextures.BUTTON_MATCH_ALL[0]) + .stateBackground(1, GTGuiTextures.BUTTON_MATCH_ALL[1]) .addTooltip(0, IKey.lang("cover.ore_dictionary_filter.button.match_all.disabled")) .addTooltip(1, @@ -180,7 +181,7 @@ protected void getStatusIcon(Widget widget) { widget.background(texture); } - protected void createStatusTooltip(Tooltip tooltip) { + protected void createStatusTooltip(RichTooltip tooltip) { var result = this.filterReader.getResult(); if (result == null) return; List list = new ArrayList<>(); diff --git a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java index ed2b3a40eaf..b36acc61283 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java @@ -2,8 +2,8 @@ import gregtech.api.cover.CoverWithUI; import gregtech.api.mui.GTGuis; -import gregtech.api.mui.sync.FixedFluidSlotSH; import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; @@ -11,9 +11,8 @@ import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.Widget; -import com.cleanroommc.modularui.widgets.FluidSlot; import com.cleanroommc.modularui.widgets.SlotGroupWidget; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; @@ -53,13 +52,15 @@ public void configureFilterTanks(int amount) { @Override public @NotNull Widget createWidgets(PanelSyncManager syncManager) { - return new Row().coverChildrenHeight().widthRel(1f) + return Flow.row().coverChildrenHeight().widthRel(1f) .child(SlotGroupWidget.builder() .matrix("FFF", "FFF", "FFF") - .key('F', i -> new FluidSlot() - .syncHandler(new FixedFluidSlotSH(filterReader.getFluidTank(i)).phantom(true))) + .key('F', i -> new GTFluidSlot() + .syncHandler(GTFluidSlot.sync(filterReader.getFluidTank(i)) + .phantom(true) + .showAmount(getFilterReader()::shouldShowAmount))) .build().marginRight(4)) .child(createBlacklistUI()); } diff --git a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java index 4eaf4ffc865..d69e6de7649 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java @@ -26,8 +26,7 @@ import com.cleanroommc.modularui.widgets.CycleButtonWidget; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.SlotGroupWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.slot.SlotGroup; import org.jetbrains.annotations.NotNull; @@ -114,7 +113,7 @@ public void initUI(Consumer widgetGroup) { syncManager.registerSlotGroup(filterInventory); - return new Row().coverChildren() + return Flow.row().coverChildren() .child(SlotGroupWidget.builder() .matrix("XXX", "XXX", @@ -134,7 +133,7 @@ public void initUI(Consumer widgetGroup) { .getInteger(SimpleItemFilterReader.COUNT); if (count > 0) tooltip.addLine( - IKey.format("Count: %s", TextFormattingUtil.formatNumbers(count))); + IKey.str("Count: %s", TextFormattingUtil.formatNumbers(count))); } }) .slot(SyncHandlers.phantomItemSlot(this.filterReader, index) @@ -146,16 +145,18 @@ public void initUI(Consumer widgetGroup) { } }))) .build().marginRight(4)) - .child(new Column().width(18).coverChildren() + .child(Flow.column().width(18).coverChildren() .child(createBlacklistUI()) .child(new CycleButtonWidget() .value(ignoreDamage) - .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_DAMAGE[state]) + .stateBackground(0, GTGuiTextures.BUTTON_IGNORE_DAMAGE[0]) + .stateBackground(1, GTGuiTextures.BUTTON_IGNORE_DAMAGE[1]) .addTooltip(0, IKey.lang("cover.item_filter.ignore_damage.disabled")) .addTooltip(1, IKey.lang("cover.item_filter.ignore_damage.enabled"))) .child(new CycleButtonWidget() .value(ignoreNBT) - .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_NBT[state]) + .stateBackground(0, GTGuiTextures.BUTTON_IGNORE_NBT[0]) + .stateBackground(1, GTGuiTextures.BUTTON_IGNORE_NBT[1]) .addTooltip(0, IKey.lang("cover.item_filter.ignore_nbt.disabled")) .addTooltip(1, IKey.lang("cover.item_filter.ignore_nbt.enabled")))); } diff --git a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java index 425189b7de2..d7cbf29c463 100644 --- a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java @@ -22,8 +22,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.jetbrains.annotations.NotNull; @@ -115,8 +114,8 @@ public void initUI(Consumer widgetGroup) { filterReader::setFilteringMode); syncManager.syncValue("filter_mode", filterMode); - return new Row().coverChildren() - .child(new Column().coverChildren().marginRight(4) + return Flow.row().coverChildren() + .child(Flow.column().coverChildren().marginRight(4) .child(createFilterModeButton(filterMode, SmartFilteringMode.ELECTROLYZER)) .child(createFilterModeButton(filterMode, SmartFilteringMode.CENTRIFUGE)) .child(createFilterModeButton(filterMode, SmartFilteringMode.SIFTER))) diff --git a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java index 5a7091e838e..f7523d976d1 100644 --- a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java @@ -21,6 +21,7 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; @@ -65,6 +66,7 @@ public ActionResult onItemRightClick(World world, EntityPlayer player @Override public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(guiData.getUsedItemStack(), 176, 120); ItemDrawable circuitPreview = new ItemDrawable(guiData.getUsedItemStack()); for (int i = 0; i <= 32; i++) { int finalI = i; @@ -73,6 +75,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager ItemStack item = IntCircuitIngredient.getIntegratedCircuit(finalI); item.setCount(guiData.getUsedItemStack().getCount()); circuitPreview.setItem(item); + if (Interactable.hasShiftDown()) panel.animateClose(); guiData.getPlayer().setHeldItem(guiData.getHand(), item); })); } @@ -91,8 +94,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .syncHandler("config", index)); } } - return GTGuis.createPanel(guiData.getUsedItemStack(), 176, 120) - .child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) + return panel.child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) .child(circuitPreview.asIcon().size(16).asWidget() .size(18) .top(19).alignX(0.5f) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java index 8cf7c4f2e6a..935d40d451f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java @@ -4,33 +4,28 @@ import gregtech.api.capability.impl.FilteredItemHandler; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.NotifiableFluidTank; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; -import gregtech.api.gui.widgets.*; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.util.GTUtility; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -38,16 +33,28 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.RichTextWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.function.Consumer; public class MetaTileEntityFluidHatch extends MetaTileEntityMultiblockNotifiablePart implements IMultiblockAbilityPart, IControllable { public static final int INITIAL_INVENTORY_SIZE = 8000; + public static final int LOCK_FILL = GregtechDataCodes.assignId(); // only holding this for convenience protected final HatchFluidTank fluidTank; @@ -161,6 +168,8 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == GregtechDataCodes.WORKING_ENABLED) { this.workingEnabled = buf.readBoolean(); + } else if (dataId == LOCK_FILL) { + this.lockedFluid = NetworkUtils.readFluidStack(buf); } } @@ -212,93 +221,85 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createTankUI(fluidTank, getMetaFullName(), entityPlayer).build(getHolder(), entityPlayer); + public boolean usesMui2() { + return true; } - public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, EntityPlayer entityPlayer) { - // Create base builder/widget references - Builder builder = ModularUI.defaultBuilder(); - TankWidget tankWidget; - - // Add input/output-specific widgets - if (isExportHatch) { - tankWidget = new PhantomTankWidget(fluidTank, 69, 43, 18, 18, - () -> this.lockedFluid, - f -> { - if (this.fluidTank.getFluidAmount() != 0) { - return; - } - if (f == null) { - this.setLocked(false); - this.lockedFluid = null; - } else { - this.setLocked(true); - this.lockedFluid = f.copy(); - this.lockedFluid.amount = 1; - } - }) - .setAlwaysShowFull(true).setDrawHoveringText(false); - - builder.image(7, 16, 81, 46, GuiTextures.DISPLAY) - .widget(new SlotWidget(exportItems, 0, 90, 44, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)) - .widget(new ToggleButtonWidget(7, 64, 18, 18, - GuiTextures.BUTTON_LOCK, this::isLocked, this::setLocked) - .setTooltipText("gregtech.gui.fluid_lock.tooltip") - .shouldUseBaseBackground()); - } else { - tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setAlwaysShowFull(true).setDrawHoveringText(false); - - builder.image(7, 16, 81, 55, GuiTextures.DISPLAY) - .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) - .widget(new SlotWidget(exportItems, 0, 90, 53, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)); - } - - // Add general widgets - return builder.label(6, 6, title) - .label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF) - .widget(new AdvancedTextWidget(11, 30, getFluidAmountText(tankWidget), 0xFFFFFF)) - .widget(new AdvancedTextWidget(11, 40, getFluidNameText(tankWidget), 0xFFFFFF)) - .widget(tankWidget) - .widget(new FluidContainerSlotWidget(importItems, 0, 90, 16, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.IN_SLOT_OVERLAY)) - .bindPlayerInventory(entityPlayer.inventory); - } - - protected Consumer> getFluidNameText(TankWidget tankWidget) { - return (list) -> { - TextComponentTranslation translation = tankWidget.getFluidTextComponent(); - // If there is no fluid in the tank, but there is a locked fluid - if (translation == null) { - translation = GTUtility.getFluidTranslation(this.lockedFluid); - } - - if (translation != null) { - list.add(translation); - } - }; - } - - protected Consumer> getFluidAmountText(TankWidget tankWidget) { - return (list) -> { - String fluidAmount = ""; - - // Nothing in the tank - if (tankWidget.getFormattedFluidAmount().equals("0")) { - // Display Zero to show information about the locked fluid - if (this.lockedFluid != null) { - fluidAmount = "0"; - } - } else { - fluidAmount = tankWidget.getFormattedFluidAmount(); - } - if (!fluidAmount.isEmpty()) { - list.add(new TextComponentString(fluidAmount)); - } - }; + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + var fluidSyncHandler = GTFluidSlot.sync(fluidTank) + .showAmount(false) + .accessibility(true, !isExportHatch) + .handleLocking(() -> this.lockedFluid, fluidStack -> { + setLocked(fluidStack != null); + this.lockedFluid = fluidStack; + this.fluidTank.onContentsChanged(); + }, this::setLocked); + + return GTGuis.createPanel(this, 176, 166) + .child(IKey.lang(getMetaFullName()).asWidget().pos(6, 6)) + + // export specific + .childIf(isExportHatch, new ItemSlot() + .pos(90, 44) + .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) + .slot(new ModularSlot(exportItems, 0) + .accessibility(false, true))) + .childIf(isExportHatch, new ToggleButton() + .pos(7, 63) + .overlay(GTGuiTextures.BUTTON_LOCK) + // todo doing things this way causes flickering if it fails + // due to sync value cache + .value(new BooleanSyncValue(this::isLocked, b -> fluidSyncHandler.lockFluid(b, false))) + .addTooltip(true, IKey.lang("gregtech.gui.fluid_lock.tooltip.enabled")) + .addTooltip(false, IKey.lang("gregtech.gui.fluid_lock.tooltip.disabled"))) + + // import specific + .childIf(!isExportHatch, GTGuiTextures.TANK_ICON.asWidget() + .pos(91, 36) + .size(14, 15)) + .childIf(!isExportHatch, new ItemSlot() + .pos(90, 53) + .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) + .slot(new ModularSlot(exportItems, 0) + .accessibility(false, true))) + + // common ui + .child(new RichTextWidget() + .size(81 - 6, (isExportHatch ? 46 : 55) - 8) + // .padding(3, 4) + .background(GTGuiTextures.DISPLAY.asIcon().size(81, isExportHatch ? 46 : 55)) + .pos(7 + 3, 16 + 4) + .textColor(Color.WHITE.main) + .alignment(Alignment.TopLeft) + .autoUpdate(true) + .textBuilder(richText -> { + richText.addLine(IKey.lang("gregtech.gui.fluid_amount")); + String name = fluidSyncHandler.getFluidLocalizedName(); + if (name == null) return; + if (name.length() > 25) name = name.substring(0, 25) + "..."; + + richText.addLine(IKey.str(name)); + richText.addLine(IKey.str(fluidSyncHandler.getFormattedFluidAmount())); + })) + .child(new GTFluidSlot() + .disableBackground() + .pos(69, isExportHatch ? 43 : 52) + .size(18) + .syncHandler(fluidSyncHandler)) + .child(new ItemSlot() + .pos(90, 16) + .background(GTGuiTextures.SLOT, GTGuiTextures.IN_SLOT_OVERLAY) + .slot(new ModularSlot(importItems, 0) + .singletonSlotGroup() + .filter(stack -> { + if (!isExportHatch) return true; + var h = FluidUtil.getFluidHandler(stack); + if (h == null) return false; + return h.getTankProperties()[0].getContents() == null; + }) + .accessibility(true, true))) + .bindPlayerInventory(); } @Override @@ -324,11 +325,10 @@ private boolean isLocked() { } private void setLocked(boolean locked) { - if (this.locked == locked) return; + if (!isExportHatch || this.locked == locked) return; this.locked = locked; - if (!getWorld().isRemote) { - markDirty(); - } + + if (!getWorld().isRemote) markDirty(); if (locked && fluidTank.getFluid() != null) { this.lockedFluid = fluidTank.getFluid().copy(); this.lockedFluid.amount = 1; @@ -352,6 +352,7 @@ public int fillInternal(FluidStack resource, boolean doFill) { if (doFill && locked && lockedFluid == null) { lockedFluid = resource.copy(); lockedFluid.amount = 1; + writeCustomData(LOCK_FILL, buffer -> NetworkUtils.writeFluidStack(buffer, lockedFluid)); } return accepted; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index 50435231a3b..a549ccbf81f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -47,7 +47,7 @@ import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.jetbrains.annotations.NotNull; @@ -310,7 +310,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .minColWidth(18).minRowHeight(18) .alignX(0.5f) .matrix(widgets)) - .child(new Column() + .child(Flow.column() .pos(backgroundWidth - 7 - 18, backgroundHeight - 18 * 4 - 7 - 5) .width(18).height(18 * 4 + 5) .child(GTGuiTextures.getLogo(getUITheme()).asWidget().size(17).top(18 * 3 + 5)) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java index cf053eb8500..6ac0ad4ee05 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java @@ -6,18 +6,16 @@ import gregtech.api.capability.IControllable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.NotifiableFluidTank; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -31,8 +29,15 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.layout.Grid; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; public class MetaTileEntityMultiFluidHatch extends MetaTileEntityMultiblockNotifiablePart @@ -114,12 +119,19 @@ public T getCapability(Capability capability, EnumFacing side) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeBoolean(workingEnabled); + for (var tank : fluidTankList.getFluidTanks()) { + NetworkUtils.writeFluidStack(buf, tank.getFluid()); + } } @Override public void receiveInitialSyncData(PacketBuffer buf) { super.receiveInitialSyncData(buf); this.workingEnabled = buf.readBoolean(); + for (var tank : fluidTankList.getFluidTanks()) { + var fluid = NetworkUtils.readFluidStack(buf); + tank.fill(fluid, true); + } } @Override @@ -190,23 +202,29 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { int rowSize = (int) Math.sqrt(numSlots); - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, - 18 + 18 * rowSize + 94) - .label(10, 5, getMetaFullName()); - - for (int y = 0; y < rowSize; y++) { - for (int x = 0; x < rowSize; x++) { - int index = y * rowSize + x; - builder.widget( - new TankWidget(fluidTankList.getTankAt(index), 89 - rowSize * 9 + x * 18, 18 + y * 18, 18, 18) - .setBackgroundTexture(GuiTextures.FLUID_SLOT) - .setContainerClicking(true, !isExportHatch) - .setAlwaysShowFull(true)); - } + + List fluidSlots = new ArrayList<>(); + for (int i = 0; i < numSlots; i++) { + fluidSlots.add(new GTFluidSlot()); } - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * rowSize + 12); - return builder.build(getHolder(), entityPlayer); + + return GTGuis.createPanel(this, 176, 18 + 18 * rowSize + 94) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(new Grid() + .margin(0) + .leftRel(0.5f) + .top(17) + .mapTo(rowSize, fluidSlots, + (i, slot) -> slot.syncHandler(GTFluidSlot.sync(fluidTankList.getTankAt(i)) + .accessibility(true, !isExportHatch))) + .coverChildren()) + .bindPlayerInventory(); } } diff --git a/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java index 1b0ccff4ebe..2530e38a587 100644 --- a/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java +++ b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java @@ -3,58 +3,73 @@ import gregtech.api.GTValues; import gregtech.api.mui.sync.GTFluidSyncHandler; import gregtech.api.util.FluidTooltipUtil; +import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; import gregtech.client.utils.TooltipHelper; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import com.cleanroommc.modularui.api.ITheme; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiDraw; -import com.cleanroommc.modularui.drawable.TextRenderer; +import com.cleanroommc.modularui.drawable.text.TextRenderer; +import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; -import com.cleanroommc.modularui.screen.Tooltip; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularScreen; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetSlotTheme; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.utils.NumberFormat; +import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; - -public class GTFluidSlot extends Widget implements Interactable, JeiIngredientProvider { +public final class GTFluidSlot extends Widget implements Interactable, JeiIngredientProvider, + JeiGhostIngredientSlot { private final TextRenderer textRenderer = new TextRenderer(); private GTFluidSyncHandler syncHandler; + private boolean disableBackground = false; public GTFluidSlot() { - tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltip().setAutoUpdate(true); + // .setHasTitleMargin(true); tooltipBuilder(tooltip -> { if (!isSynced()) return; var fluid = this.syncHandler.getFluid(); + + if (fluid == null) + fluid = this.syncHandler.getLockedFluid(); + if (fluid == null) return; - tooltip.addLine(fluid.getLocalizedName()); - tooltip.addLine(IKey.lang("gregtech.fluid.amount", fluid.amount, this.syncHandler.getCapacity())); + tooltip.addLine(IKey.str(fluid.getLocalizedName())); + if (this.syncHandler.showAmount()) + tooltip.addLine(IKey.lang("gregtech.fluid.amount", fluid.amount, this.syncHandler.getCapacity())); + + if (this.syncHandler.isPhantom() && this.syncHandler.showAmount()) + tooltip.addLine(IKey.lang("modularui.fluid.phantom.control")); // Add various tooltips from the material - List formula = FluidTooltipUtil.getFluidTooltip(fluid); - if (formula != null) { - for (String s : formula) { - if (s.isEmpty()) continue; - tooltip.addLine(s); - } + for (String s : FluidTooltipUtil.getFluidTooltip(fluid)) { + if (s.isEmpty()) continue; + tooltip.addLine(IKey.str(s)); } - addIngotMolFluidTooltip(fluid, tooltip); + if (this.syncHandler.showAmount()) + addIngotMolFluidTooltip(fluid, tooltip); }); } @@ -67,10 +82,11 @@ public void onInit() { this.textRenderer.setShadow(true); this.textRenderer.setScale(0.5f); this.textRenderer.setColor(Color.WHITE.main); + getContext().getJeiSettings().addJeiGhostIngredientSlot(this); } public GTFluidSlot syncHandler(IFluidTank fluidTank) { - return syncHandler(new GTFluidSyncHandler(fluidTank)); + return syncHandler(sync(fluidTank)); } public GTFluidSlot syncHandler(GTFluidSyncHandler syncHandler) { @@ -79,55 +95,82 @@ public GTFluidSlot syncHandler(GTFluidSyncHandler syncHandler) { return this; } + public GTFluidSlot disableBackground() { + this.disableBackground = true; + return this; + } + + @Override + public boolean isValidSyncHandler(SyncHandler syncHandler) { + return syncHandler instanceof GTFluidSyncHandler; + } + @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { + public void drawBackground(ModularGuiContext context, WidgetTheme widgetTheme) { + if (disableBackground) return; + super.drawBackground(context, widgetTheme); + } + + @Override + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { + if (widgetTheme instanceof WidgetSlotTheme slotTheme) { + draw(context, slotTheme); + } + } + + public void draw(ModularGuiContext context, WidgetSlotTheme widgetTheme) { FluidStack content = this.syncHandler.getFluid(); - if (content != null) { - GuiDraw.drawFluidTexture(content, 1, 1, getArea().w() - 2, getArea().h() - 2, 0); + if (content == null) + content = this.syncHandler.getLockedFluid(); - String s = NumberFormat.formatWithMaxDigits(getBaseUnitAmount(content.amount)) + getBaseUnit(); + GuiDraw.drawFluidTexture(content, 1, 1, getArea().w() - 2, getArea().h() - 2, 0); + + if (content != null && this.syncHandler.showAmount()) { + String amount = NumberFormat.formatWithMaxDigits(content.amount, 3) + "L"; this.textRenderer.setAlignment(Alignment.CenterRight, getArea().width - 1f); this.textRenderer.setPos(0, 12); - this.textRenderer.draw(s); + this.textRenderer.draw(amount); } + if (isHovering()) { GlStateManager.colorMask(true, true, true, false); - GuiDraw.drawRect(1, 1, getArea().w() - 2, getArea().h() - 2, - getWidgetTheme(context.getTheme()).getSlotHoverColor()); + GuiDraw.drawRect(1, 1, getArea().w() - 2, getArea().h() - 2, widgetTheme.getSlotHoverColor()); GlStateManager.colorMask(true, true, true, true); } } - protected double getBaseUnitAmount(double amount) { - return amount / 1000; - } - - protected String getBaseUnit() { - return "L"; - } - - @NotNull @Override - public Result onMouseTapped(int mouseButton) { + public @NotNull Result onMousePressed(int mouseButton) { + var data = MouseData.create(mouseButton); if (this.syncHandler.canFillSlot() || this.syncHandler.canDrainSlot()) { - this.syncHandler.syncToServer(1, buffer -> buffer.writeBoolean(mouseButton == 0)); - Interactable.playButtonClickSound(); + this.syncHandler.handleClick(data); + + if (this.syncHandler.canLockFluid()) + this.syncHandler.toggleLockFluid(); + return Result.SUCCESS; } return Result.IGNORE; } @Override - public WidgetSlotTheme getWidgetTheme(ITheme theme) { - return theme.getFluidSlotTheme(); + public boolean onMouseScroll(ModularScreen.UpOrDown scrollDirection, int amount) { + if (!this.syncHandler.isPhantom()) return false; + if ((scrollDirection.isUp() && !this.syncHandler.canFillSlot()) || + (scrollDirection.isDown() && !this.syncHandler.canDrainSlot())) { + return false; + } + MouseData mouseData = MouseData.create(scrollDirection.modifier); + this.syncHandler.handlePhantomScroll(mouseData); + return true; } @Override - public @Nullable Object getIngredient() { - return this.syncHandler.getFluid(); + protected WidgetTheme getWidgetThemeInternal(ITheme theme) { + return theme.getFluidSlotTheme(); } - public static void addIngotMolFluidTooltip(FluidStack fluidStack, Tooltip tooltip) { + public static void addIngotMolFluidTooltip(FluidStack fluidStack, RichTooltip tooltip) { // Add tooltip showing how many "ingot moles" (increments of 144) this fluid is if shift is held if (TooltipHelper.isShiftDown() && fluidStack.amount > GTValues.L) { int numIngots = fluidStack.amount / GTValues.L; @@ -136,7 +179,37 @@ public static void addIngotMolFluidTooltip(FluidStack fluidStack, Tooltip toolti if (extra != 0) { fluidAmount += String.format(" + %d L", extra); } - tooltip.addLine(TextFormatting.GRAY + LocalizationUtils.format("gregtech.gui.amount_raw") + fluidAmount); + tooltip.add(TextFormatting.GRAY + LocalizationUtils.format("gregtech.gui.amount_raw") + fluidAmount); } } + + @Override + public void setGhostIngredient(@NotNull FluidStack ingredient) { + if (this.syncHandler.isPhantom()) { + this.syncHandler.setFluid(ingredient); + this.syncHandler.syncToServer(GTFluidSyncHandler.UPDATE_TANK, + buffer -> NetworkUtils.writeFluidStack(buffer, ingredient)); + } else { + this.syncHandler.lockFluid(ingredient, true); + } + } + + @Override + public @Nullable FluidStack castGhostIngredientIfValid(@NotNull Object ingredient) { + if (ingredient instanceof FluidStack stack) { + return stack; + } else if (ingredient instanceof ItemStack stack && + stack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null)) { + if (stack.getCount() > 1) stack = GTUtility.copy(1, stack); + + var handler = stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + return handler == null ? null : handler.drain(Integer.MAX_VALUE, true); + } + return null; + } + + @Override + public @Nullable Object getIngredient() { + return this.syncHandler.getFluid(); + } } diff --git a/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java index 3bb6a3e652b..c7f339db275 100644 --- a/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java +++ b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java @@ -1,7 +1,7 @@ package gregtech.common.mui.widget; import com.cleanroommc.modularui.api.value.IStringValue; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widgets.textfield.TextFieldHandler; import com.cleanroommc.modularui.widgets.textfield.TextFieldRenderer; @@ -53,7 +53,7 @@ public HighlightedTextField getThis() { } @Override - public void onRemoveFocus(GuiContext context) { + public void onRemoveFocus(ModularGuiContext context) { super.onRemoveFocus(context); highlighter.runHighlighter(getText()); if (isSynced()) @@ -70,7 +70,7 @@ public static final class TextHighlighter extends TextFieldRenderer { private Function highlightRule = string -> string; - private Map cacheMap = new Object2ObjectOpenHashMap<>(); + private final Map cacheMap = new Object2ObjectOpenHashMap<>(); public TextHighlighter(TextFieldHandler handler) { super(handler); @@ -81,15 +81,15 @@ public void setHighlightRule(Function highlightRule) { } @Override - protected float draw(String text, float x, float y) { - return super.draw(this.cacheMap.getOrDefault(text, text), x, y); + protected void draw(String text, float x, float y) { + super.draw(this.cacheMap.getOrDefault(text, text), x, y); } public void runHighlighter(String text) { if (this.highlightRule == null) { return; } - this.cacheMap.computeIfAbsent(text, string -> this.highlightRule.apply(string)); + this.cacheMap.computeIfAbsent(text, this.highlightRule); } } } diff --git a/src/main/java/gregtech/common/mui/widget/InteractableText.java b/src/main/java/gregtech/common/mui/widget/InteractableText.java index eac6936059a..bcafa15208d 100644 --- a/src/main/java/gregtech/common/mui/widget/InteractableText.java +++ b/src/main/java/gregtech/common/mui/widget/InteractableText.java @@ -38,6 +38,11 @@ public Result onMousePressed(int mouseButton) { return Result.SUCCESS; } + @Override + public boolean isValidSyncHandler(SyncHandler syncHandler) { + return syncHandler instanceof EntryColorSH; + } + private static class EntryColorSH extends SyncHandler { private final Consumer setter; diff --git a/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java index 1948364bbec..e4d0ea8648c 100644 --- a/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java +++ b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java @@ -7,7 +7,7 @@ import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; import com.cleanroommc.modularui.api.drawable.IKey; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.widgets.ItemSlot; import it.unimi.dsi.fastutil.objects.Object2BooleanAVLTreeMap; @@ -106,7 +106,7 @@ public void updatePreview() { } @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { super.draw(context, widgetTheme); if (this.matchSuccess) { GTGuiTextures.OREDICT_MATCH diff --git a/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java index f429a9d749e..f26eacee77a 100644 --- a/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java +++ b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java @@ -19,6 +19,7 @@ public List getMixinConfigs() { configs.add("mixins.gregtech.ccl.json"); configs.add("mixins.gregtech.littletiles.json"); configs.add("mixins.gregtech.vintagium.json"); + configs.add("mixins.gregtech.mui2.json"); configs.add("mixins.gregtech.nothirium.json"); return configs; diff --git a/src/main/java/gregtech/mixins/jei/IngredientGridMixin.java b/src/main/java/gregtech/mixins/jei/IngredientGridMixin.java new file mode 100644 index 00000000000..2b876ca38b8 --- /dev/null +++ b/src/main/java/gregtech/mixins/jei/IngredientGridMixin.java @@ -0,0 +1,30 @@ +package gregtech.mixins.jei; + +import net.minecraft.client.Minecraft; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import mezz.jei.gui.GuiScreenHelper; +import mezz.jei.gui.overlay.IngredientGrid; +import mezz.jei.gui.overlay.IngredientGridWithNavigation; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(value = IngredientGridWithNavigation.class, remap = false) +public class IngredientGridMixin { + + @Shadow + @Final + private GuiScreenHelper guiScreenHelper; + + @WrapOperation(method = "drawTooltips", + at = @At(value = "INVOKE", + target = "Lmezz/jei/gui/overlay/IngredientGrid;drawTooltips(Lnet/minecraft/client/Minecraft;II)V")) + private void considerExclusions(IngredientGrid instance, Minecraft minecraft, int mouseX, int mouseY, + Operation original) { + if (!guiScreenHelper.isInGuiExclusionArea(mouseX, mouseY)) + original.call(instance, minecraft, mouseX, mouseY); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java b/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java new file mode 100644 index 00000000000..678de031802 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java @@ -0,0 +1,79 @@ +package gregtech.mixins.mui2; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.client.event.GuiScreenEvent; + +import com.cleanroommc.modularui.ClientEventHandler; +import com.cleanroommc.modularui.api.IMuiScreen; +import com.cleanroommc.modularui.core.mixin.GuiScreenAccessor; +import com.cleanroommc.modularui.screen.ClientScreenHandler; +import com.cleanroommc.modularui.screen.ModularScreen; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.IOException; + +@Mixin(value = ClientEventHandler.class, remap = false) +@SuppressWarnings("UnstableApiUsage") +public abstract class ClientEventHandlerMixin { + + @Redirect(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$MouseInputEvent$Pre;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;handleMouseInput()V")) + private static void fixMouseInput(GuiScreen instance) { + int button = Mouse.getEventButton(); + if (instance instanceof IMuiScreen screen && instance instanceof GuiScreenAccessor acc) { + ModularScreen ms = screen.getScreen(); + if (Mouse.getEventButtonState()) { + acc.setEventButton(button); + acc.setLastMouseEvent(Minecraft.getSystemTime()); + ms.onMousePressed(button); + + } else if (button != -1) { + acc.setEventButton(-1); + ms.onMouseRelease(button); + + } else if (acc.getEventButton() != -1 && acc.getLastMouseEvent() > 0L) { + long l = Minecraft.getSystemTime() - acc.getLastMouseEvent(); + ms.onMouseDrag(button, l); + } + } + } + + @Inject(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$MouseInputEvent$Pre;)V", + at = @At("TAIL")) + private static void fixScrollJei(GuiScreenEvent.MouseInputEvent.Pre event, CallbackInfo ci) throws IOException { + if (!event.isCanceled()) + ClientScreenHandler.onGuiInputLow(event); + } + + @Unique + private static Character gregTech$lastChar = null; + + @Redirect(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$KeyboardInputEvent$Pre;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;handleKeyboardInput()V")) + private static void fixKeyInput(GuiScreen instance) { + if (instance instanceof IMuiScreen screen && instance instanceof GuiScreenAccessor acc) { + char c0 = Keyboard.getEventCharacter(); + int key = Keyboard.getEventKey(); + boolean state = Keyboard.getEventKeyState(); + if (state) { + gregTech$lastChar = c0; + screen.getScreen().onKeyPressed(c0, key); + } else { + // releasing a key + // for some reason when you press E after joining a world the button will not trigger the press event, + // but only the release event, causing this to be null + if (gregTech$lastChar == null) return; + // when the key is released, the event char is empty + screen.getScreen().onKeyRelease(gregTech$lastChar, key); + } + } + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java b/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java new file mode 100644 index 00000000000..5d53a35d3d0 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java @@ -0,0 +1,141 @@ +package gregtech.mixins.mui2; + +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.ItemHandlerHelper; + +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularContainer; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.ItemSlotSH; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.IOException; + +@Mixin(value = ItemSlotSH.class, remap = false) +public abstract class ItemSlotSHMixin extends SyncHandler { + + @Unique + private boolean gregTech$registered; + + @Shadow + protected abstract void phantomScroll(MouseData mouseData); + + @Shadow + public abstract void setEnabled(boolean enabled, boolean sync); + + @Shadow + public abstract boolean isPhantom(); + + @Shadow + private ItemStack lastStoredPhantomItem; + + @Shadow + public abstract ModularSlot getSlot(); + + @Shadow + public abstract void incrementStackCount(int amount); + + @WrapOperation(method = "init", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/screen/ModularContainer;registerSlot(Ljava/lang/String;Lcom/cleanroommc/modularui/widgets/slot/ModularSlot;)V")) + protected void wrapRegister(ModularContainer instance, String slotGroup, ModularSlot modularSlot, + Operation original) { + if (!gregTech$registered) { + original.call(instance, slotGroup, modularSlot); + gregTech$registered = true; + } + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#90 + */ + @Overwrite + public void readOnServer(int id, PacketBuffer buf) throws IOException { + if (id == 2) { + phantomClick(MouseData.readPacket(buf)); + } else if (id == 3) { + phantomScroll(MouseData.readPacket(buf)); + } else if (id == 4) { + setEnabled(buf.readBoolean(), false); + } else if (id == 5) { + if (!isPhantom()) return; + gregTech$phantomClick(MouseData.create(0), buf.readItemStack()); + } + } + + @Inject(method = "readOnClient", at = @At("HEAD")) + protected void handlePhantomScroll(int id, PacketBuffer buf, CallbackInfo ci) { + if (id == 3) { + this.lastStoredPhantomItem = NetworkUtils.readItemStack(buf); + getSlot().putStack(this.lastStoredPhantomItem.copy()); + } + } + + @Inject(method = "phantomScroll", at = @At("TAIL")) + protected void syncPhantomScroll(MouseData mouseData, CallbackInfo ci) { + syncToClient(3, buffer -> NetworkUtils.writeItemStack(buffer, this.lastStoredPhantomItem)); + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#90 + */ + @Overwrite + protected void phantomClick(MouseData mouseData) { + gregTech$phantomClick(mouseData, getSyncManager().getCursorItem()); + } + + @Unique + protected void gregTech$phantomClick(MouseData mouseData, ItemStack cursorStack) { + ItemStack slotStack = getSlot().getStack(); + ItemStack stackToPut; + if (!cursorStack.isEmpty() && !slotStack.isEmpty() && + !ItemHandlerHelper.canItemStacksStack(cursorStack, slotStack)) { + stackToPut = cursorStack.copy(); + if (mouseData.mouseButton == 1) { + stackToPut.setCount(1); + } + stackToPut.setCount(Math.min(stackToPut.getCount(), getSlot().getItemStackLimit(stackToPut))); + getSlot().putStack(stackToPut); + this.lastStoredPhantomItem = stackToPut.copy(); + } else if (slotStack.isEmpty()) { + if (cursorStack.isEmpty()) { + if (mouseData.mouseButton == 1 && !this.lastStoredPhantomItem.isEmpty()) { + stackToPut = this.lastStoredPhantomItem.copy(); + } else { + return; + } + } else { + stackToPut = cursorStack.copy(); + } + if (mouseData.mouseButton == 1) { + stackToPut.setCount(1); + } + stackToPut.setCount(Math.min(stackToPut.getCount(), getSlot().getItemStackLimit(stackToPut))); + getSlot().putStack(stackToPut); + this.lastStoredPhantomItem = stackToPut.copy(); + } else { + if (mouseData.mouseButton == 0) { + if (mouseData.shift) { + getSlot().putStack(ItemStack.EMPTY); + } else { + incrementStackCount(-1); + } + } else if (mouseData.mouseButton == 1) { + incrementStackCount(1); + } + } + } +} diff --git a/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java b/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java new file mode 100644 index 00000000000..99a850b1c10 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java @@ -0,0 +1,47 @@ +package gregtech.mixins.mui2; + +import com.cleanroommc.modularui.api.widget.ISynced; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.ModularSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncHandler; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.WidgetTree; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.concurrent.atomic.AtomicInteger; + +@Mixin(value = PanelSyncHandler.class, remap = false) +public abstract class PanelSyncHandlerMixin { + + @Shadow + private PanelSyncManager syncManager; + + @Shadow + public abstract boolean isPanelOpen(); + + @Redirect(method = "openPanel(Z)V", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/widget/WidgetTree;collectSyncValues(Lcom/cleanroommc/modularui/value/sync/PanelSyncManager;Lcom/cleanroommc/modularui/screen/ModularPanel;)V")) + protected void redirectCollectValues(PanelSyncManager syncManager, ModularPanel panel) { + AtomicInteger id = new AtomicInteger(0); + String syncKey = ModularSyncManager.AUTO_SYNC_PREFIX + panel.getName(); + WidgetTree.foreachChildBFS(panel, widget -> { + if (widget instanceof ISyncedsynced) { + if (synced.isSynced() && !this.syncManager.hasSyncHandler(synced.getSyncHandler())) { + this.syncManager.syncValue(syncKey, id.getAndIncrement(), synced.getSyncHandler()); + } + } + return true; + }, false); + } + + @Inject(method = "openPanel(Z)V", at = @At("HEAD"), cancellable = true) + protected void openCheck(boolean syncToServer, CallbackInfo ci) { + if (isPanelOpen()) ci.cancel(); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java b/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java new file mode 100644 index 00000000000..9bea0ab1af2 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java @@ -0,0 +1,36 @@ +package gregtech.mixins.mui2; + +import gregtech.api.util.GTLog; + +import net.minecraft.network.PacketBuffer; + +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Map; + +@Mixin(value = PanelSyncManager.class, remap = false) +public abstract class PanelSyncManagerMixin { + + @Shadow + @Final + private Map syncHandlers; + + @Shadow + private String panelName; + + @Inject(method = "receiveWidgetUpdate", at = @At("HEAD"), cancellable = true) + public void injectCheck(String mapKey, int id, PacketBuffer buf, CallbackInfo ci) { + if (!this.syncHandlers.containsKey(mapKey)) { + GTLog.logger.warn("[ModularUI] SyncHandler \"{}\" does not exist for panel \"{}\"! ID was {}.", mapKey, + panelName, id); + ci.cancel(); + } + } +} diff --git a/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java b/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java new file mode 100644 index 00000000000..41c269111ab --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java @@ -0,0 +1,119 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.UnboxFix; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.text.AnimatedText; +import com.cleanroommc.modularui.drawable.text.StyledText; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.widgets.TextWidget; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(value = StyledText.class, remap = false) +public abstract class StyledTextMixin implements UnboxFix { + + @Shadow + @Final + private IKey key; + + @Shadow + private Alignment alignment; + + @Shadow + private Integer color; + + @Shadow + private float scale; + + @Shadow + private Boolean shadow; + + @Unique + private boolean gregTech$defaultTextColor = true; + + @Unique + private boolean gregTech$defaultShadow = true; + + @Override + public void gregTech$useDefaultTextColor(boolean b) { + gregTech$defaultTextColor = b; + } + + @Override + public void gregTech$useDefaultShadow(boolean b) { + gregTech$defaultShadow = b; + } + + @Inject(method = "color", at = @At("HEAD")) + private void setDefault(int color, CallbackInfoReturnable cir) { + gregTech$useDefaultTextColor(false); + } + + @Inject(method = "shadow", at = @At("HEAD")) + private void setDefault(boolean shadow, CallbackInfoReturnable cir) { + gregTech$useDefaultShadow(false); + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#86 + */ + @Overwrite + public TextWidget asWidget() { + var text = new TextWidget(this.key) + .alignment(this.alignment) + .scale(this.scale); + + ((UnboxFix) text).gregTech$useDefaultTextColor(this.gregTech$defaultTextColor); + ((UnboxFix) text).gregTech$useDefaultShadow(this.gregTech$defaultShadow); + + return text.color(color == null ? 0 : color) + .shadow(shadow != null && shadow); + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#86 + */ + @Overwrite + public AnimatedText withAnimation() { + var text = new AnimatedText(this.key) + .alignment(this.alignment) + .scale(this.scale); + + ((UnboxFix) text).gregTech$useDefaultTextColor(this.gregTech$defaultTextColor); + ((UnboxFix) text).gregTech$useDefaultShadow(this.gregTech$defaultShadow); + + return text.color(color == null ? 0 : color) + .shadow(shadow != null && shadow); + } + + @SideOnly(Side.CLIENT) + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setColor(I)V")) + public int fixColor(int color, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultTextColor ? theme.getTextColor() : color; + } + + @SideOnly(Side.CLIENT) + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setShadow(Z)V")) + public boolean fixShadow(boolean shadow, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultShadow ? theme.getTextShadow() : shadow; + } +} diff --git a/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java b/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java new file mode 100644 index 00000000000..40320a51020 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java @@ -0,0 +1,57 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.UnboxFix; + +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.TextWidget; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(value = TextWidget.class, remap = false) +public abstract class TextWidgetMixin extends Widget implements UnboxFix { + + @Unique + private boolean gregTech$defaultTextColor = true; + + @Unique + private boolean gregTech$defaultShadow = true; + + @Override + public void gregTech$useDefaultTextColor(boolean b) { + gregTech$defaultTextColor = b; + } + + @Override + public void gregTech$useDefaultShadow(boolean b) { + gregTech$defaultShadow = b; + } + + @Override + public boolean canHover() { + return hasTooltip(); + } + + @ModifyReturnValue(method = { "getDefaultHeight", "getDefaultWidth" }, at = @At("TAIL")) + public int clamp(int r) { + return Math.max(1, r); + } + + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setColor(I)V")) + public int fixColor(int color, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultTextColor ? theme.getTextColor() : color; + } + + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setShadow(Z)V")) + public boolean fixShadow(boolean shadow, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultShadow ? theme.getTextShadow() : shadow; + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java b/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java new file mode 100644 index 00000000000..3838ecf5805 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java @@ -0,0 +1,22 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.StateOverlay; + +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.widgets.AbstractCycleButtonWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(value = ToggleButton.class, remap = false) +public class ToggleButtonMixin extends AbstractCycleButtonWidget implements StateOverlay { + + public StateOverlay overlay(boolean selected, IDrawable... overlay) { + this.overlay = addToArray(this.overlay, overlay, selected ? 1 : 0); + return (StateOverlay) getThis(); + } + + public StateOverlay hoverOverlay(boolean selected, IDrawable... overlay) { + this.hoverOverlay = addToArray(this.hoverOverlay, overlay, selected ? 1 : 0); + return (StateOverlay) getThis(); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/TooltipMixin.java b/src/main/java/gregtech/mixins/mui2/TooltipMixin.java new file mode 100644 index 00000000000..7883e8b12de --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/TooltipMixin.java @@ -0,0 +1,100 @@ +package gregtech.mixins.mui2; + +import com.cleanroommc.modularui.drawable.text.RichText; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.RichTextWidget; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.function.Consumer; + +@Mixin(value = RichTooltip.class, remap = false) +public abstract class TooltipMixin { + + @Shadow + private boolean dirty; + + @Shadow + @Final + private RichText text; + + @Shadow + private Consumer tooltipBuilder; + + @Shadow + public abstract RichTooltip getThis(); + + @Shadow + public abstract void markDirty(); + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#83 + */ + @Overwrite + public void buildTooltip() { + this.dirty = false; + if (this.tooltipBuilder != null) { + this.text.clearText(); + this.tooltipBuilder.accept(getThis()); + } + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#83 + */ + @Overwrite + public RichTooltip tooltipBuilder(Consumer tooltipBuilder) { + Consumer existingBuilder = this.tooltipBuilder; + if (existingBuilder != null) { + this.tooltipBuilder = tooltip -> { + existingBuilder.accept(getThis()); + tooltipBuilder.accept(getThis()); + }; + } else { + this.tooltipBuilder = tooltipBuilder; + } + markDirty(); + return getThis(); + } + + @Mixin(value = RichTextWidget.class, remap = false) + private static abstract class RichTextWidgetMixin extends Widget { + + @Shadow + private boolean autoUpdate; + + @Shadow + private boolean dirty; + + @Shadow + @Final + private RichText text; + + @Shadow + private Consumer builder; + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#83 + */ + @Overwrite + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { + super.draw(context, widgetTheme); + if (this.autoUpdate || this.dirty) { + if (this.builder != null) { + this.text.clearText(); + this.builder.accept(this.text); + } + this.dirty = false; + } + this.text.drawAtZero(context, getArea(), widgetTheme); + } + } +} diff --git a/src/main/resources/mixins.gregtech.jei.json b/src/main/resources/mixins.gregtech.jei.json index 2520843c7d6..47158a7ea6c 100644 --- a/src/main/resources/mixins.gregtech.jei.json +++ b/src/main/resources/mixins.gregtech.jei.json @@ -1,12 +1,13 @@ { - "package" : "gregtech.mixins.jei", - "refmap" : "mixins.gregtech.refmap.json", - "target" : "@env(DEFAULT)", - "minVersion" : "0.8", - "compatibilityLevel" : "JAVA_8", - "mixins" : [ + "package": "gregtech.mixins.jei", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "IngredientGridMixin", "JEITooltipMixin" ], - "client" : [], - "server" : [] + "client": [], + "server": [] } diff --git a/src/main/resources/mixins.gregtech.mui2.json b/src/main/resources/mixins.gregtech.mui2.json new file mode 100644 index 00000000000..cb97f2be00c --- /dev/null +++ b/src/main/resources/mixins.gregtech.mui2.json @@ -0,0 +1,24 @@ +{ + "package": "gregtech.mixins.mui2", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "injectors": { + "maxShiftBy": 10 + }, + "mixins": [ + "ItemSlotSHMixin", + "PanelSyncHandlerMixin", + "PanelSyncManagerMixin", + "StyledTextMixin", + "TextWidgetMixin", + "ToggleButtonMixin", + "TooltipMixin", + "TooltipMixin$RichTextWidgetMixin" + ], + "client": [ + "ClientEventHandlerMixin" + ], + "server": [] +}