PrettyPipes/src/main/java/de/ellpeck/prettypipes/terminal/containers/ItemTerminalGui.java
2020-09-22 19:14:07 +02:00

260 lines
11 KiB
Java

package de.ellpeck.prettypipes.terminal.containers;
import com.mojang.blaze3d.matrix.MatrixStack;
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.misc.ItemOrder;
import de.ellpeck.prettypipes.misc.ItemTerminalWidget;
import de.ellpeck.prettypipes.misc.PlayerPrefs;
import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.packets.PacketRequest;
import joptsimple.internal.Strings;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ItemTerminalGui extends ContainerScreen<ItemTerminalContainer> {
private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/item_terminal.png");
private List<ItemStack> items;
private List<ItemStack> sortedItems;
private Button minusButton;
private Button plusButton;
private Button requestButton;
private Button orderButton;
private Button ascendingButton;
private String lastSearchText;
private int requestAmount = 1;
private int scrollOffset;
public TextFieldWidget search;
public ItemTerminalGui(ItemTerminalContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
super(screenContainer, inv, titleIn);
this.xSize = 176 + 15;
this.ySize = 236;
}
@Override
protected void init() {
super.init();
this.plusButton = this.addButton(new Button(this.guiLeft + this.getXOffset() + 95 - 7 + 12, this.guiTop + 103, 12, 12, new StringTextComponent("+"), button -> {
int modifier = requestModifier();
if (modifier > 1 && this.requestAmount == 1) {
this.requestAmount = modifier;
} else {
this.requestAmount += modifier;
}
if (this.requestAmount > 384)
this.requestAmount = 384;
}));
this.minusButton = this.addButton(new Button(this.guiLeft + this.getXOffset() + 95 - 7 - 24, this.guiTop + 103, 12, 12, new StringTextComponent("-"), button -> {
this.requestAmount -= requestModifier();
if (this.requestAmount < 1)
this.requestAmount = 1;
}));
this.minusButton.active = false;
this.requestButton = this.addButton(new Button(this.guiLeft + this.getXOffset() + 95 - 7 - 25, this.guiTop + 115, 50, 20, new TranslationTextComponent("info." + PrettyPipes.ID + ".request"), button -> {
Optional<ItemTerminalWidget> widget = this.streamWidgets().filter(w -> w.selected).findFirst();
if (!widget.isPresent())
return;
ItemStack stack = widget.get().stack.copy();
stack.setCount(1);
PacketHandler.sendToServer(new PacketRequest(this.container.tile.getPos(), stack, this.requestAmount));
this.requestAmount = 1;
}));
this.requestButton.active = false;
this.orderButton = this.addButton(new Button(this.guiLeft - 22, this.guiTop, 20, 20, new StringTextComponent(""), button -> {
if (this.sortedItems == null)
return;
PlayerPrefs prefs = PlayerPrefs.get();
prefs.terminalItemOrder = prefs.terminalItemOrder.next();
prefs.save();
this.updateWidgets();
}));
this.ascendingButton = this.addButton(new Button(this.guiLeft - 22, this.guiTop + 22, 20, 20, new StringTextComponent(""), button -> {
if (this.sortedItems == null)
return;
PlayerPrefs prefs = PlayerPrefs.get();
prefs.terminalAscending = !prefs.terminalAscending;
prefs.save();
this.updateWidgets();
}));
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 9; x++)
this.addButton(new ItemTerminalWidget(this.guiLeft + this.getXOffset() + 8 + x * 18, this.guiTop + 18 + y * 18, x, y, this));
}
this.search = this.addButton(new TextFieldWidget(this.font, this.guiLeft + this.getXOffset() + 97, this.guiTop + 6, 86, 8, new StringTextComponent("")));
this.search.setEnableBackgroundDrawing(false);
this.lastSearchText = "";
if (this.items != null)
this.updateWidgets();
}
protected int getXOffset() {
return 0;
}
@Override
public void tick() {
super.tick();
this.requestButton.active = this.streamWidgets().anyMatch(w -> w.selected);
this.plusButton.active = this.requestAmount < 384;
this.minusButton.active = this.requestAmount > 1;
this.search.tick();
if (this.items != null) {
String text = this.search.getText();
if (!this.lastSearchText.equals(text)) {
this.lastSearchText = text;
this.updateWidgets();
}
}
}
@Override
public boolean keyPressed(int x, int y, int z) {
// for some reason we have to do this to make the text field allow the inventory key to be typed
if (this.search.isFocused()) {
InputMappings.Input mouseKey = InputMappings.getInputByCode(x, y);
if (this.minecraft.gameSettings.keyBindInventory.isActiveAndMatches(mouseKey))
return false;
}
return super.keyPressed(x, y, z);
}
public void updateItemList(List<ItemStack> items) {
this.items = items;
this.updateWidgets();
}
public void updateWidgets() {
PlayerPrefs prefs = PlayerPrefs.get();
this.ascendingButton.setMessage(new StringTextComponent(prefs.terminalAscending ? "^" : "v"));
this.orderButton.setMessage(new StringTextComponent(prefs.terminalItemOrder.name().substring(0, 1)));
Comparator<ItemStack> comparator = prefs.terminalItemOrder.comparator;
if (!prefs.terminalAscending)
comparator = comparator.reversed();
this.sortedItems = new ArrayList<>(this.items);
this.sortedItems.sort(comparator);
String searchText = this.search.getText();
if (!Strings.isNullOrEmpty(searchText)) {
this.sortedItems.removeIf(s -> {
String search = searchText;
String toCompare;
if (search.startsWith("@")) {
toCompare = s.getItem().getRegistryName().getNamespace();
search = search.substring(1);
} else {
// don't use formatted text here since we want to search for name
toCompare = s.getDisplayName().getString();
}
return !toCompare.toLowerCase(Locale.ROOT).contains(search.toLowerCase(Locale.ROOT));
});
}
if (this.sortedItems.size() < 9 * 4)
this.scrollOffset = 0;
List<ItemTerminalWidget> widgets = this.streamWidgets().collect(Collectors.toList());
for (int i = 0; i < widgets.size(); i++) {
ItemTerminalWidget widget = widgets.get(i);
int index = i + this.scrollOffset * 9;
if (index >= this.sortedItems.size()) {
widget.stack = ItemStack.EMPTY;
widget.visible = false;
} else {
widget.stack = this.sortedItems.get(index);
widget.visible = true;
}
}
}
@Override
public void render(MatrixStack matrix, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(matrix);
super.render(matrix, mouseX, mouseY, partialTicks);
for (Widget widget : this.buttons) {
if (widget instanceof ItemTerminalWidget)
widget.renderToolTip(matrix, mouseX, mouseY);
}
if (this.sortedItems != null) {
PlayerPrefs prefs = PlayerPrefs.get();
if (this.orderButton.isHovered())
this.renderTooltip(matrix, new TranslationTextComponent("info." + PrettyPipes.ID + ".order", I18n.format("info." + PrettyPipes.ID + ".order." + prefs.terminalItemOrder.name().toLowerCase(Locale.ROOT))), mouseX, mouseY);
if (this.ascendingButton.isHovered())
this.renderTooltip(matrix, new TranslationTextComponent("info." + PrettyPipes.ID + "." + (prefs.terminalAscending ? "ascending" : "descending")), mouseX, mouseY);
}
this.func_230459_a_(matrix, mouseX, mouseY);
}
@Override
protected void drawGuiContainerForegroundLayer(MatrixStack matrix, int mouseX, int mouseY) {
this.font.drawString(matrix, this.playerInventory.getDisplayName().getString(), 8 + this.getXOffset(), this.ySize - 96 + 2, 4210752);
this.font.drawString(matrix, this.title.getString(), 8, 6, 4210752);
String amount = String.valueOf(this.requestAmount);
this.font.drawString(matrix, amount, (176 + 15 - this.font.getStringWidth(amount)) / 2F - 7 + this.getXOffset(), 106, 4210752);
}
@Override
protected void drawGuiContainerBackgroundLayer(MatrixStack matrix, float partialTicks, int mouseX, int mouseY) {
this.getMinecraft().getTextureManager().bindTexture(this.getTexture());
this.blit(matrix, this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
if (this.sortedItems != null && this.sortedItems.size() >= 9 * 4) {
float percentage = this.scrollOffset / (float) (this.sortedItems.size() / 9 - 3);
this.blit(matrix, this.guiLeft + this.getXOffset() + 172, this.guiTop + 18 + (int) (percentage * (70 - 15)), 232, 241, 12, 15);
} else {
this.blit(matrix, this.guiLeft + this.getXOffset() + 172, this.guiTop + 18, 244, 241, 12, 15);
}
}
protected ResourceLocation getTexture() {
return TEXTURE;
}
@Override
public boolean mouseScrolled(double x, double y, double scroll) {
if (this.sortedItems != null && this.sortedItems.size() >= 9 * 4) {
int offset = MathHelper.clamp(this.scrollOffset - (int) Math.signum(scroll), 0, this.sortedItems.size() / 9 - 3);
if (offset != this.scrollOffset) {
this.scrollOffset = offset;
this.updateWidgets();
}
}
return true;
}
public Stream<ItemTerminalWidget> streamWidgets() {
return this.buttons.stream()
.filter(w -> w instanceof ItemTerminalWidget)
.map(w -> (ItemTerminalWidget) w);
}
private static int requestModifier() {
if (hasControlDown()) {
return 10;
} else if (hasShiftDown()) {
return 64;
} else {
return 1;
}
}
}