filename:
common/src/main/java/rearth/oritech/client/ui/RedstoneAddonScreen.java
branch:
1.21
back to repo
package rearth.oritech.client.ui;
import io.wispforest.owo.ui.base.BaseOwoHandledScreen;
import io.wispforest.owo.ui.component.ButtonComponent;
import io.wispforest.owo.ui.component.Components;
import io.wispforest.owo.ui.component.LabelComponent;
import io.wispforest.owo.ui.container.Containers;
import io.wispforest.owo.ui.container.FlowLayout;
import io.wispforest.owo.ui.core.*;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.jetbrains.annotations.NotNull;
import rearth.oritech.block.entity.addons.RedstoneAddonBlockEntity;
import rearth.oritech.util.ScreenProvider;
import java.util.ArrayList;
import java.util.List;
import static rearth.oritech.client.ui.BasicMachineScreen.ORITECH_PANEL;
import static rearth.oritech.client.ui.BasicMachineScreen.getItemFrame;
public class RedstoneAddonScreen extends BaseOwoHandledScreen<FlowLayout, RedstoneAddonScreenHandler> {
private LabelComponent activeLabel;
private FlowLayout overlay;
private final List<ButtonComponent> buttons = new ArrayList<>();
private FlowLayout buttonContainer;
private LabelComponent descriptionLabel;
public RedstoneAddonScreen(RedstoneAddonScreenHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
}
@Override
protected @NotNull OwoUIAdapter<FlowLayout> createAdapter() {
return OwoUIAdapter.create(this, Containers::verticalFlow);
}
@Override
protected void build(FlowLayout rootComponent) {
rootComponent
.surface(Surface.VANILLA_TRANSLUCENT)
.horizontalAlignment(HorizontalAlignment.CENTER)
.verticalAlignment(VerticalAlignment.CENTER);
overlay = Containers.horizontalFlow(Sizing.fixed(176), Sizing.fixed(100));
overlay.padding(Insets.of(3)).margins(Insets.of(3));
var spacer = Containers.horizontalFlow(Sizing.fixed(176), Sizing.fixed(166 - 100 + 5));
rootComponent.child(overlay.surface(ORITECH_PANEL));
rootComponent.child(spacer);
var modes = RedstoneAddonBlockEntity.RedstoneMode.values();
var activeMode = handler.blockEntity.activeMode;
activeLabel = Components.label(getModeText(activeMode));
activeLabel.horizontalTextAlignment(HorizontalAlignment.CENTER);
activeLabel.sizing(Sizing.fill(), Sizing.content(2));
activeLabel.positioning(Positioning.absolute(0, 15));
overlay.child(activeLabel);
descriptionLabel = Components.label(getDescriptionText(activeMode));
descriptionLabel.horizontalTextAlignment(HorizontalAlignment.CENTER);
descriptionLabel.sizing(Sizing.fill(), Sizing.content(2));
descriptionLabel.positioning(Positioning.absolute(0, 25));
overlay.child(descriptionLabel);
System.out.println(activeMode);
var slider = Components.discreteSlider(Sizing.fixed(160), 0, modes.length - 1);
slider.positioning(Positioning.absolute(8, 63));
slider.snap(true);
slider.onChanged().subscribe(this::onModeSelected);
slider.setFromDiscreteValue(activeMode.ordinal());
overlay.child(slider);
addTitle(overlay);
}
private void onModeSelected(double mode) {
var modes = RedstoneAddonBlockEntity.RedstoneMode.values();
if (mode >= modes.length) return;
var activeMode = modes[(int) mode];
activeLabel.text(getModeText(activeMode));
descriptionLabel.text(getDescriptionText(activeMode));
handler.blockEntity.activeMode = activeMode;
if (activeMode.equals(RedstoneAddonBlockEntity.RedstoneMode.OUTPUT_SLOT)) {
overlay.verticalSizing().animate(250, Easing.CUBIC, Sizing.fixed(194)).forwards();
addSlotSelector();
} else if (overlay.verticalSizing().get().value != 100) {
overlay.verticalSizing().animate(270, Easing.CUBIC, Sizing.fixed(100)).forwards();
removeSlotSelector();
}
triggerServerUpdate();
}
private void addSlotSelector() {
removeSlotSelector(); // in case the user is moving really fast and the call order is messed up
var controller = handler.blockEntity.getCachedController();
if (!(controller instanceof ScreenProvider screenProvider)) return;
var slots = screenProvider.getGuiSlots();
buttonContainer = Containers.horizontalFlow(Sizing.fixed(176), Sizing.fixed(100));
buttonContainer.positioning(Positioning.absolute(0, 100));
// small separator line
buttonContainer.child(Components.box(Sizing.fixed(160), Sizing.fixed(1)).color(new Color(0.1f, 0.1f, 0.1f)).positioning(Positioning.absolute(8, 0)));
var title = Components.label(Text.translatable("title.oritech.redstone_addon"));
title.horizontalTextAlignment(HorizontalAlignment.CENTER);
buttonContainer.child(title.positioning(Positioning.relative(50, 5)));
for (var slot : slots) {
var button = Components.button(Text.literal(" "), elem -> {
setActiveSlot(slot.index());
});
buttons.add(button);
buttonContainer.child(getItemFrame(slot.x(), slot.y()));
buttonContainer.child(button.sizing(Sizing.fixed(10)).positioning(Positioning.absolute(slot.x() + 3, slot.y() + 3)));
}
setActiveSlot(handler.blockEntity.monitoredSlot);
if (screenProvider.showProgress()) {
var arrowConfig = screenProvider.getIndicatorConfiguration();
var arrow = Components.texture(arrowConfig.full(), 0, 0, arrowConfig.width(), arrowConfig.height(), arrowConfig.width(), arrowConfig.height());
buttonContainer.child(arrow.positioning(Positioning.absolute(arrowConfig.x(), arrowConfig.y())));
}
overlay.child(buttonContainer);
}
private void removeSlotSelector() {
if (buttonContainer == null) return;
overlay.removeChild(buttonContainer);
buttons.clear();
buttonContainer = null;
}
private void setActiveSlot(int slot) {
for (int i = 0; i < buttons.size(); i++) {
var button = buttons.get(i);
button.active = i != slot;
}
handler.blockEntity.monitoredSlot = slot;
triggerServerUpdate();
}
private Text getModeText(RedstoneAddonBlockEntity.RedstoneMode mode) {
return Text.translatable("title.oritech.redstone_" + mode.toString().toLowerCase()).formatted(Formatting.BOLD, Formatting.DARK_GRAY);
}
private Text getDescriptionText(RedstoneAddonBlockEntity.RedstoneMode mode) {
return Text.translatable("tooltip.oritech.redstone_" + mode.toString().toLowerCase()).formatted(Formatting.BLACK);
}
private void addTitle(FlowLayout overlay) {
var blockTitle = handler.blockEntity.getCachedState().getBlock().getName();
var label = Components.label(blockTitle);
label.color(new Color(64 / 255f, 64 / 255f, 64 / 255f));
label.sizing(Sizing.fixed(176), Sizing.content(2));
label.horizontalTextAlignment(HorizontalAlignment.CENTER);
label.zIndex(1);
overlay.child(label.positioning(Positioning.relative(50, 2)));
}
private void triggerServerUpdate() {
handler.blockEntity.sendDataToServer();
}
}