Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MUI for multiblock I/O buses #2266

Merged
merged 15 commits into from
Dec 10, 2023
38 changes: 38 additions & 0 deletions src/main/java/gregtech/api/mui/GTGuiTextures.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@ public static class IDs {
public static final String STEEL_BACKGROUND = "gregtech_steel_bg";
public static final String PRIMITIVE_BACKGROUND = "gregtech_primitive_bg";

public static final String STANDARD_SLOT = "gregtech_standard_slot";
public static final String BRONZE_SLOT = "gregtech_bronze_slot";
public static final String STEEL_SLOT = "gregtech_steel_slot";
public static final String PRIMITIVE_SLOT = "gregtech_primitive_slot";

public static final String STANDARD_BUTTON = "gregtech_standard_button";
}

// GT LOGOS
public static final UITexture GREGTECH_LOGO = UITexture.fullImage(GTValues.MODID,
"textures/gui/icon/gregtech_logo.png");

// BACKGROUNDS
public static final UITexture BACKGROUND = UITexture.builder()
.location(GTValues.MODID, "textures/gui/base/background.png")
Expand Down Expand Up @@ -50,6 +57,13 @@ public static class IDs {
.build();

// SLOTS
public static final UITexture SLOT = new UITexture.Builder()
.location(GTValues.MODID, "textures/gui/base/slot.png")
.imageSize(18, 18)
.adaptable(1)
.registerAsBackground(IDs.STANDARD_SLOT, true)
.build();

public static final UITexture SLOT_BRONZE = new UITexture.Builder()
.location(GTValues.MODID, "textures/gui/base/slot_bronze.png")
.imageSize(18, 18)
Expand All @@ -71,5 +85,29 @@ public static class IDs {
.registerAsBackground(IDs.PRIMITIVE_SLOT)
.build();

// SLOT OVERLAYS

public static final UITexture INT_CIRCUIT_OVERLAY = UITexture.fullImage(GTValues.MODID,
"textures/gui/overlay/int_circuit_overlay.png", true);

// BUTTONS

public static final UITexture BUTTON = new UITexture.Builder()
.location(GTValues.MODID, "textures/gui/widget/button.png")
.imageSize(18, 18)
.adaptable(1)
.registerAsIcon(IDs.STANDARD_BUTTON)
.canApplyTheme()
.build();

public static final UITexture BUTTON_ITEM_OUTPUT = UITexture.fullImage(GTValues.MODID,
"textures/gui/widget/button_item_output_overlay.png");

public static final UITexture BUTTON_AUTO_COLLAPSE = UITexture.fullImage(GTValues.MODID,
"textures/gui/widget/button_auto_collapse_overlay.png");

public static final UITexture BUTTON_X = UITexture.fullImage(GTValues.MODID,
"textures/gui/widget/button_x_overlay.png", true);

public static void init() {/**/}
}
8 changes: 8 additions & 0 deletions src/main/java/gregtech/api/mui/GTGuiTheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ public class GTGuiTheme {

public static final GTGuiTheme STANDARD = new Builder("gregtech_standard")
.panel(GTGuiTextures.IDs.STANDARD_BACKGROUND)
.itemSlot(GTGuiTextures.IDs.STANDARD_SLOT)
.color(ConfigHolder.client.defaultUIColor)
.toggleButton(GTGuiTextures.IDs.STANDARD_BUTTON,
GTGuiTextures.IDs.STANDARD_SLOT,
ConfigHolder.client.defaultUIColor)
.build();

public static final GTGuiTheme BRONZE = new Builder("gregtech_bronze")
Expand Down Expand Up @@ -245,6 +249,10 @@ public Builder toggleButton(String toggleButtonId, String selectedBackgroundId)
return toggleButton(toggleButtonId, selectedBackgroundId, 0xFFFFFFFF, true);
}

public Builder toggleButton(String toggleButtonId, String selectedBackgroundId, int selectedColor) {
return toggleButton(toggleButtonId, selectedBackgroundId, 0xFFFFFFFF, true, null, selectedColor);
}

public Builder toggleButton(String toggleButtonId, String selectedBackgroundId, int textColor,
boolean textShadow) {
return toggleButton(toggleButtonId, selectedBackgroundId, textColor, textShadow, null, 0xFFBBBBBB);
Expand Down
212 changes: 212 additions & 0 deletions src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package gregtech.api.mui.widget;

import gregtech.api.capability.impl.GhostCircuitItemStackHandler;
import gregtech.api.mui.GTGuiTextures;
import gregtech.api.mui.GTGuis;
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.drawable.IKey;
import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.drawable.ItemDrawable;
import com.cleanroommc.modularui.screen.ModularScreen;
import com.cleanroommc.modularui.screen.Tooltip;
import com.cleanroommc.modularui.utils.MouseData;
import com.cleanroommc.modularui.value.sync.ItemSlotSH;
import com.cleanroommc.modularui.widgets.ButtonWidget;
import com.cleanroommc.modularui.widgets.ItemSlot;
import com.cleanroommc.modularui.widgets.layout.Grid;
import com.cleanroommc.modularui.widgets.slot.ModularSlot;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class GhostCircuitSlotWidget extends ItemSlot {

private static final int SYNC_CIRCUIT_INDEX = 10;

public GhostCircuitSlotWidget() {
tooltipBuilder(this::getCircuitSlotTooltip);
}

@Override
public @NotNull Result onMousePressed(int mouseButton) {
if (!isSelectorPanelOpen()) {
if (mouseButton == 0 && TooltipHelper.isShiftDown()) {
createSelectorPanel();
} else {
MouseData mouseData = MouseData.create(mouseButton);
getSyncHandler().syncToServer(2, mouseData::writeToPacket);
}
}
return Result.SUCCESS;
}

@Override
public boolean onMouseScroll(ModularScreen.UpOrDown scrollDirection, int amount) {
if (isSelectorPanelOpen()) return true;
MouseData mouseData = MouseData.create(scrollDirection.modifier);
getSyncHandler().syncToServer(3, mouseData::writeToPacket);
return false;
}

@Override
public ItemSlot slot(ModularSlot slot) {
ItemSlotSH sh = new GhostCircuitSyncHandler(slot);
isValidSyncHandler(sh);
setSyncHandler(sh);
return this;
}

@Override
protected List<String> getItemTooltip(ItemStack stack) {
// we don't want the item tooltip
return Collections.emptyList();
}

protected void getCircuitSlotTooltip(@NotNull Tooltip tooltip) {
String configString;
int value = getSyncHandler().getGhostCircuitHandler().getCircuitValue();
if (value == GhostCircuitItemStackHandler.NO_CONFIG) {
configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value").getFormattedText();
} else {
configString = String.valueOf(value);
}

tooltip.addLine(IKey.lang("gregtech.gui.configurator_slot.tooltip", configString));
}

@Override
public @NotNull GhostCircuitSyncHandler getSyncHandler() {
return (GhostCircuitSyncHandler) super.getSyncHandler();
}

@Override
public void onMouseDrag(int mouseButton, long timeSinceClick) {}

@Override
public boolean onMouseRelease(int mouseButton) {
return true;
}

private boolean isSelectorPanelOpen() {
return getPanel().getScreen().isPanelOpen("circuit_selector");
}

private void createSelectorPanel() {
ItemDrawable circuitPreview = new ItemDrawable(getSyncHandler().getSlot().getStack());

List<List<IWidget>> 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())
.onMousePressed(mouseButton -> {
getSyncHandler().syncToServer(SYNC_CIRCUIT_INDEX, buf -> buf.writeShort(index));
circuitPreview.setItem(IntCircuitIngredient.getIntegratedCircuit(index));
return true;
}));
}
}

getPanel().getScreen().openPanel(GTGuis.createPanel("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)));
}

private static class GhostCircuitSyncHandler extends ItemSlotSH {

public GhostCircuitSyncHandler(ModularSlot slot) {
super(slot);
}

@Override
protected void phantomClick(MouseData mouseData) {
if (mouseData.mouseButton == 0) {
// increment on left-click
setCircuitValue(getNextCircuitValue(1));
} else if (mouseData.mouseButton == 1 && mouseData.shift) {
// clear on shift-right-click
setCircuitValue(GhostCircuitItemStackHandler.NO_CONFIG);
} else if (mouseData.mouseButton == 1) {
// decrement on right-click
setCircuitValue(getNextCircuitValue(-1));
}
}

@Override
protected void phantomScroll(MouseData mouseData) {
setCircuitValue(getNextCircuitValue(mouseData.mouseButton));
}

private void setCircuitValue(int value) {
GhostCircuitItemStackHandler handler = getGhostCircuitHandler();
if (handler.getCircuitValue() != value) {
handler.setCircuitValue(value);
syncToClient(1, buf -> {
buf.writeBoolean(false);
buf.writeItemStack(handler.getStackInSlot(0));
buf.writeBoolean(false);
});
}
}

@Override
public void readOnServer(int id, PacketBuffer buf) throws IOException {
if (id == SYNC_CIRCUIT_INDEX) {
setCircuitValue(buf.readShort());
} else {
super.readOnServer(id, buf);
}
}

private int getNextCircuitValue(int delta) {
GhostCircuitItemStackHandler handler = getGhostCircuitHandler();

// if no circuit, skip 0 and return 32 if decrementing,
// or, skip 0 and return 1 when incrementing
if (!handler.hasCircuitValue()) {
return delta == 1 ? 1 : IntCircuitIngredient.CIRCUIT_MAX;
// if at max, loop around to no circuit
} else if (handler.getCircuitValue() + delta > IntCircuitIngredient.CIRCUIT_MAX) {
return GhostCircuitItemStackHandler.NO_CONFIG;
// if at 1, skip 0 and return to no circuit
} else if (handler.getCircuitValue() + delta < 1) {
return GhostCircuitItemStackHandler.NO_CONFIG;
}

// normal case: change by "delta" which is either 1 or -1
return handler.getCircuitValue() + delta;
}

public GhostCircuitItemStackHandler getGhostCircuitHandler() {
IItemHandler handler = getSlot().getItemHandler();
if (!(handler instanceof GhostCircuitItemStackHandler ghostHandler)) {
throw new IllegalStateException(
"GhostCircuitSyncHandler has IItemHandler that is not GhostCircuitItemStackHandler");
}
return ghostHandler;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import gregtech.api.items.metaitem.stats.IItemBehaviour;
import gregtech.api.items.metaitem.stats.ISubItemHandler;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.mui.GTGuiTextures;
import gregtech.api.mui.GTGuis;
import gregtech.api.recipes.ingredients.IntCircuitIngredient;
import gregtech.api.util.GTUtility;
Expand All @@ -17,7 +18,6 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import com.cleanroommc.modularui.api.drawable.IDrawable;
import com.cleanroommc.modularui.api.drawable.IKey;
import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.drawable.ItemDrawable;
Expand Down Expand Up @@ -85,17 +85,17 @@ public ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManage
if (index > 32) break;
options.get(i).add(new ButtonWidget<>()
.size(18)
.background(com.cleanroommc.modularui.drawable.GuiTextures.SLOT,
.background(GTGuiTextures.SLOT,
new ItemDrawable(IntCircuitIngredient.getIntegratedCircuit(index)).asIcon().size(16))
.syncHandler("config", index));
}
}
return GTGuis.createPanel(guiCreationContext.getUsedItemStack(), 176, 120)
.child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5))
.child(new IDrawable.DrawableWidget(circuitPreview.asIcon().size(16))
.child(circuitPreview.asIcon().size(16).asWidget()
.size(18)
.top(19).alignX(0.5f)
.background(com.cleanroommc.modularui.drawable.GuiTextures.SLOT))
.background(GTGuiTextures.SLOT))
.child(new Grid()
.left(7).right(7).top(41).height(4 * 18)
.matrix(options)
Expand Down
Loading