Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b4868a2
start of multiblock UI design
YoungOnionMC Dec 22, 2025
6647271
blah
YoungOnionMC Dec 22, 2025
9884dc2
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Dec 26, 2025
ae17f0d
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Dec 26, 2025
57bbd8e
some stuff
YoungOnionMC Jan 5, 2026
166bc4d
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Jan 5, 2026
0ac9b05
more multiblock testing
YoungOnionMC Jan 5, 2026
1bf1b56
try to start on dynamic text for the stuff
YoungOnionMC Jan 5, 2026
63dfe68
test2
YoungOnionMC Jan 5, 2026
93f859f
attempt 3
YoungOnionMC Jan 6, 2026
e86870a
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Jan 7, 2026
d883c8c
more text stuff
YoungOnionMC Jan 7, 2026
e8b15dc
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Jan 8, 2026
7563018
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Jan 8, 2026
e8cecbd
some more text functions
Jan 16, 2026
3dc5c09
Merge remote-tracking branch 'origin/yo/mui2/multiblock-p1' into yo/m…
YoungOnionMC Jan 16, 2026
fb6f5ac
more funcs p2
YoungOnionMC Jan 19, 2026
63541b2
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Feb 3, 2026
41534ab
more methods
YoungOnionMC Feb 3, 2026
65448cb
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Feb 3, 2026
64baa72
Fix coil drawable syncing
jurrejelle Feb 3, 2026
5a512b0
Add GTRECIPE bytebufadapter and outputlines functions
jurrejelle Feb 3, 2026
e907c6d
Fix scrolling of recipe output list
jurrejelle Feb 3, 2026
3af1be6
Create proper lines for fluid/item outputs
jurrejelle Feb 3, 2026
1e20bf3
Remove test recipe
jurrejelle Feb 3, 2026
d8850be
comment out narration widget stuff, try to attempt start aligned chil…
Feb 3, 2026
475db74
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Feb 4, 2026
f76bc9d
alignment works again :iminsomuchpain:
YoungOnionMC Feb 4, 2026
4a263a4
Merge branch 'mui2-refactor' of https://github.com/GregTechCEu/GregTe…
YoungOnionMC Feb 5, 2026
1fc5544
update 8.0 into dis
YoungOnionMC Feb 5, 2026
09b8174
start of multiblocks
YoungOnionMC Feb 8, 2026
e9de73d
remove test recipe
YoungOnionMC Feb 8, 2026
964e73e
spots
YoungOnionMC Feb 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,29 @@

import com.gregtechceu.gtceu.api.block.ICoilType;
import com.gregtechceu.gtceu.api.blockentity.BlockEntityCreationInfo;
import com.gregtechceu.gtceu.api.mui.base.drawable.IDrawable;
import com.gregtechceu.gtceu.api.mui.drawable.*;
import com.gregtechceu.gtceu.api.mui.factory.PosGuiData;
import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue;
import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager;
import com.gregtechceu.gtceu.api.mui.widget.ParentWidget;
import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget;
import com.gregtechceu.gtceu.api.mui.widgets.layout.Column;
import com.gregtechceu.gtceu.api.mui.widgets.layout.Row;
import com.gregtechceu.gtceu.client.mui.screen.ModularPanel;
import com.gregtechceu.gtceu.client.mui.screen.UISettings;
import com.gregtechceu.gtceu.common.block.CoilBlock;
import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets;
import com.gregtechceu.gtceu.common.data.mui.GTMultiblockPanelUtil;
import com.gregtechceu.gtceu.common.mui.GTGuiTextures;
import com.gregtechceu.gtceu.common.mui.GTGuis;

import net.minecraft.MethodsReturnNonnullByDefault;

import lombok.Getter;

import java.util.function.Supplier;

import javax.annotation.ParametersAreNonnullByDefault;

@ParametersAreNonnullByDefault
Expand Down Expand Up @@ -36,4 +53,47 @@ public void onStructureFormed() {
public int getCoilTier() {
return coilType.getTier();
}

@Override
public ModularPanel buildUI(PosGuiData data, PanelSyncManager syncManager, UISettings settings) {
var panel = GTGuis.createPanel(this, 176 + 32, 164 + 36);

var panelUtil = new GTMultiblockPanelUtil(this);

IntSyncValue coilTier = syncManager.getOrCreateSyncHandler("coilTier", IntSyncValue.class,
() -> new IntSyncValue(this::getCoilTier));

Supplier<IDrawable> coilTexture = () -> new UITexture.Builder()
.location(CoilBlock.CoilType.values()[coilTier.getIntValue()].getTexture())
.imageSize(16, 16).colorType(ColorType.DEFAULT).tiled().build();

var widget1 = new DynamicDrawable(coilTexture).asWidget().size(4, 16).heightRel(1.0f);
var widget2 = new DynamicDrawable(coilTexture).asWidget().size(4, 16).heightRel(1.0f);

panel.child(GTMuiWidgets.createTitleBar(this.getDefinition(), 176 + 36))
.child(new ParentWidget<>()
.widthRel(0.95f)
.heightRel(.45f)
.margin(4, 0)
.left(3).top(3)
.child(new Row()
.child(widget1)
.child(panelUtil.getMainTextPanel(syncManager, 208, 90))
.child(widget2))

)
.child(new Column()
.coverChildren()
.leftRel(1.0f)
.reverseLayout(true)
.bottom(16)
.padding(0, 8, 4, 4)
.childPadding(2)
.background(GTGuiTextures.BACKGROUND.getSubArea(0.25f, 0f, 1.0f, 1.0f))
.child(GTMuiWidgets.createPowerButton(this, syncManager))
.child(GTMuiWidgets.createVoidingButton(this, syncManager)))
.child(SlotGroupWidget.playerInventory(false).left(7).bottom(7));

return panel;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,46 @@
import com.gregtechceu.gtceu.api.GTValues;
import com.gregtechceu.gtceu.api.blockentity.BlockEntityCreationInfo;
import com.gregtechceu.gtceu.api.capability.IEnergyContainer;
import com.gregtechceu.gtceu.api.capability.IParallelHatch;
import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability;
import com.gregtechceu.gtceu.api.capability.recipe.IO;
import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler;
import com.gregtechceu.gtceu.api.gui.GuiTextures;
import com.gregtechceu.gtceu.api.gui.fancy.*;
import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine;
import com.gregtechceu.gtceu.api.machine.feature.IMuiMachine;
import com.gregtechceu.gtceu.api.machine.feature.IOverclockMachine;
import com.gregtechceu.gtceu.api.machine.feature.ITieredMachine;
import com.gregtechceu.gtceu.api.machine.feature.IVoidable;
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine;
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart;
import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic;
import com.gregtechceu.gtceu.api.misc.EnergyContainerList;
import com.gregtechceu.gtceu.api.recipe.modifier.RecipeModifierList;
import com.gregtechceu.gtceu.api.mui.factory.PosGuiData;
import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager;
import com.gregtechceu.gtceu.api.mui.widget.ParentWidget;
import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget;
import com.gregtechceu.gtceu.api.mui.widgets.layout.Column;
import com.gregtechceu.gtceu.api.mui.widgets.layout.Row;
import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField;
import com.gregtechceu.gtceu.common.data.GTRecipeModifiers;
import com.gregtechceu.gtceu.client.mui.screen.ModularPanel;
import com.gregtechceu.gtceu.client.mui.screen.UISettings;
import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets;
import com.gregtechceu.gtceu.common.data.mui.GTMultiblockPanelUtil;
import com.gregtechceu.gtceu.common.mui.GTGuiTextures;
import com.gregtechceu.gtceu.common.mui.GTGuis;
import com.gregtechceu.gtceu.utils.GTUtil;

import com.lowdragmc.lowdraglib.gui.modular.ModularUI;
import com.lowdragmc.lowdraglib.gui.widget.*;

import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;

import lombok.Getter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;

import javax.annotation.ParametersAreNonnullByDefault;

@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class WorkableElectricMultiblockMachine extends WorkableMultiblockMachine implements IFancyUIMachine,
IDisplayUIMachine, ITieredMachine, IOverclockMachine {
public class WorkableElectricMultiblockMachine extends WorkableMultiblockMachine
implements IMuiMachine, ITieredMachine, IOverclockMachine {

// runtime
protected EnergyContainerList energyContainer;
Expand Down Expand Up @@ -93,92 +93,120 @@ public void setBatchEnabled(boolean batch) {
//////////////////////////////////////
// ********** GUI ***********//
//////////////////////////////////////

@Override
public void addDisplayText(List<Component> textList) {
int numParallels;
int subtickParallels;
int batchParallels;
int totalRuns;
boolean exact = false;
if (recipeLogic.isActive() && recipeLogic.getLastRecipe() != null) {
numParallels = recipeLogic.getLastRecipe().parallels;
subtickParallels = recipeLogic.getLastRecipe().subtickParallels;
batchParallels = recipeLogic.getLastRecipe().batchParallels;
totalRuns = recipeLogic.getLastRecipe().getTotalRuns();
exact = true;
} else {
numParallels = getParallelHatch()
.map(IParallelHatch::getCurrentParallel)
.orElse(0);
subtickParallels = 0;
batchParallels = 0;
totalRuns = 0;
}

MultiblockDisplayText.builder(textList, isFormed())
.setWorkingStatus(recipeLogic.isWorkingEnabled(), recipeLogic.isActive())
.addEnergyUsageLine(energyContainer)
.addEnergyTierLine(tier)
.addMachineModeLine(getRecipeType(), getRecipeTypes().length > 1)
.addTotalRunsLine(totalRuns)
.addParallelsLine(numParallels, exact)
.addSubtickParallelsLine(subtickParallels)
.addBatchModeLine(isBatchEnabled(), batchParallels)
.addWorkingStatusLine()
.addProgressLine(recipeLogic)
.addOutputLines(recipeLogic.getLastRecipe());
getDefinition().getAdditionalDisplay().accept(this, textList);
IDisplayUIMachine.super.addDisplayText(textList);
public ModularPanel buildUI(PosGuiData data, PanelSyncManager syncManager, UISettings settings) {
var panel = GTGuis.createPanel(this, 176, 164);

var panelUtil = new GTMultiblockPanelUtil(this);

panel.child(GTMuiWidgets.createTitleBar(this.getDefinition(), 176))
.child(new ParentWidget<>()
.widthRel(0.95f)
.heightRel(.45f)
.margin(4, 0)
.left(3).top(5)
.child(new Row()
.child(panelUtil.getMainTextPanel(syncManager, 170, 70))))
.child(new Column()
.coverChildren()
.leftRel(1.0f)
.reverseLayout(true)
.bottom(16)
.padding(0, 8, 4, 4)
.childPadding(2)
.background(GTGuiTextures.BACKGROUND.getSubArea(0.25f, 0f, 1.0f, 1.0f))
.child(GTMuiWidgets.createPowerButton(this, syncManager))
.child(GTMuiWidgets.createVoidingButton(this, syncManager)))
.child(SlotGroupWidget.playerInventory(false).left(7).bottom(7));

return panel;
}

@Override
public Widget createUIWidget() {
var group = new WidgetGroup(0, 0, 182 + 8, 117 + 8);
group.addWidget(new DraggableScrollableWidgetGroup(4, 4, 182, 117).setBackground(getScreenTexture())
.addWidget(new LabelWidget(4, 5, self().getBlockState().getBlock().getDescriptionId()))
.addWidget(new ComponentPanelWidget(4, 17, this::addDisplayText)
.textSupplier(this.getLevel().isClientSide ? null : this::addDisplayText)
.setMaxWidthLimit(200)
.clickHandler(this::handleDisplayClick)));
group.setBackground(GuiTextures.BACKGROUND_INVERSE);
return group;
}

@Override
public ModularUI createUI(Player entityPlayer) {
return new ModularUI(198, 208, this, entityPlayer).widget(new FancyMachineUIWidget(this, 198, 208));
}

@Override
public List<IFancyUIProvider> getSubTabs() {
return getParts().stream().filter(Objects::nonNull).map(IFancyUIProvider.class::cast).toList();
}

@Override
public void attachConfigurators(ConfiguratorPanel configuratorPanel) {
IVoidable.attachConfigurators(configuratorPanel, this);
if (getDefinition().getRecipeModifier() instanceof RecipeModifierList list && Arrays.stream(list.getModifiers())
.anyMatch(modifier -> modifier == GTRecipeModifiers.BATCH_MODE)) {
configuratorPanel.attachConfigurators(new IFancyConfiguratorButton.Toggle(
GuiTextures.BUTTON_BATCH.getSubTexture(0, 0, 1, 0.5),
GuiTextures.BUTTON_BATCH.getSubTexture(0, 0.5, 1, 0.5),
this::isBatchEnabled,
(cd, p) -> setBatchEnabled(p))
.setTooltipsSupplier(
p -> List.of(
Component.translatable("gtceu.machine.batch_" + (p ? "enabled" : "disabled")))));
}

IFancyUIMachine.super.attachConfigurators(configuratorPanel);
}

@Override
public void attachTooltips(TooltipsPanel tooltipsPanel) {
for (IMultiPart part : getParts()) {
part.attachFancyTooltipsToController(this, tooltipsPanel);
}
}
// @Override
// public void addDisplayText(List<Component> textList) {
// int numParallels;
// int subtickParallels;
// int batchParallels;
// int totalRuns;
// boolean exact = false;
// if (recipeLogic.isActive() && recipeLogic.getLastRecipe() != null) {
// numParallels = recipeLogic.getLastRecipe().parallels;
// subtickParallels = recipeLogic.getLastRecipe().subtickParallels;
// batchParallels = recipeLogic.getLastRecipe().batchParallels;
// totalRuns = recipeLogic.getLastRecipe().getTotalRuns();
// exact = true;
// } else {
// numParallels = getParallelHatch()
// .map(IParallelHatch::getCurrentParallel)
// .orElse(0);
// subtickParallels = 0;
// batchParallels = 0;
// totalRuns = 0;
// }
//
// MultiblockDisplayText.builder(textList, isFormed())
// .setWorkingStatus(recipeLogic.isWorkingEnabled(), recipeLogic.isActive())
// .addEnergyUsageLine(energyContainer)
// .addEnergyTierLine(tier)
// .addMachineModeLine(getRecipeType(), getRecipeTypes().length > 1)
// .addTotalRunsLine(totalRuns)
// .addParallelsLine(numParallels, exact)
// .addSubtickParallelsLine(subtickParallels)
// .addBatchModeLine(isBatchEnabled(), batchParallels)
// .addWorkingStatusLine()
// .addProgressLine(recipeLogic.getProgress(), recipeLogic.getMaxProgress(),
// recipeLogic.getProgressPercent())
// .addOutputLines(recipeLogic.getLastRecipe());
// getDefinition().getAdditionalDisplay().accept(this, textList);
// IDisplayUIMachine.super.addDisplayText(textList);
// }

// @Override
// public Widget createUIWidget() {
// var group = new WidgetGroup(0, 0, 182 + 8, 117 + 8);
// group.addWidget(new DraggableScrollableWidgetGroup(4, 4, 182, 117).setBackground(getScreenTexture())
// .addWidget(new LabelWidget(4, 5, self().getBlockState().getBlock().getDescriptionId()))
// .addWidget(new ComponentPanelWidget(4, 17, this::addDisplayText)
// .textSupplier(this.getLevel().isClientSide ? null : this::addDisplayText)
// .setMaxWidthLimit(200)
// .clickHandler(this::handleDisplayClick)));
// group.setBackground(GuiTextures.BACKGROUND_INVERSE);
// return group;
// }
//
// @Override
// public ModularUI createUI(Player entityPlayer) {
// return new ModularUI(198, 208, this, entityPlayer).widget(new FancyMachineUIWidget(this, 198, 208));
// }
//
// @Override
// public List<IFancyUIProvider> getSubTabs() {
// return getParts().stream().filter(Objects::nonNull).map(IFancyUIProvider.class::cast).toList();
// }
//
// @Override
// public void attachConfigurators(ConfiguratorPanel configuratorPanel) {
// if (getDefinition().getRecipeModifier() instanceof RecipeModifierList list && Arrays.stream(list.getModifiers())
// .anyMatch(modifier -> modifier == GTRecipeModifiers.BATCH_MODE)) {
// configuratorPanel.attachConfigurators(new IFancyConfiguratorButton.Toggle(
// GuiTextures.BUTTON_BATCH.getSubTexture(0, 0, 1, 0.5),
// GuiTextures.BUTTON_BATCH.getSubTexture(0, 0.5, 1, 0.5),
// this::isBatchEnabled,
// (cd, p) -> setBatchEnabled(p))
// .setTooltipsSupplier(
// p -> List.of(
// Component.translatable("gtceu.machine.batch_" + (p ? "enabled" : "disabled")))));
// }
//
// IFancyUIMachine.super.attachConfigurators(configuratorPanel);
// }
//
// @Override
// public void attachTooltips(TooltipsPanel tooltipsPanel) {
// for (IMultiPart part : getParts()) {
// part.attachFancyTooltipsToController(this, tooltipsPanel);
// }
// }

//////////////////////////////////////
// ******** OVERCLOCK *********//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public enum Status implements StringRepresentable {
@Nullable
@SaveField
@SyncToClient
@Getter
private Component waitingReason = null;
/**
* unsafe, it may not be found from {@link RecipeManager}. Do not index it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -558,10 +558,10 @@ public static void drawDebugScreen(GuiGraphics graphics, @Nullable ModularScreen
float scale = ConfigHolder.INSTANCE.dev.mui.scale;
int shift = (int) (11 * scale + 0.5f);
int lineY = screenH - shift - 2;
if (GTCEu.Mods.isJEILoaded() || GTCEu.Mods.isEMILoaded() || GTCEu.Mods.isREILoaded()) lineY -= 12;
if (GTCEu.Mods.isJEILoaded() || GTCEu.Mods.isEMILoaded() || GTCEu.Mods.isREILoaded()) lineY -= 20;
GuiDraw.drawText(graphics, "Mouse Pos: " + mouseX + ", " + mouseY, 5, lineY, scale, outlineColor, true);
lineY -= shift + 2;
GuiDraw.drawText(graphics, "FPS: " + fpsCounter.getFps(), 5, screenH - 23, scale, outlineColor, true);
lineY -= shift;
GuiDraw.drawText(graphics, "FPS: " + fpsCounter.getFps(), 5, lineY, scale, outlineColor, true);
lineY -= shift;
GuiDraw.drawText(graphics, "Theme ID: " + context.getTheme().getId(), 5, lineY, scale, outlineColor, true);
LocatedWidget locatedHovered = muiScreen.getPanelManager().getTopWidgetLocated(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,9 +810,11 @@ public int getHeight() {

@Override
public void visitWidgets(@NotNull Consumer<AbstractWidget> consumer) {
for (WidgetWrapper wrapper : panelManager.getReverseOpenPanelsWrappers()) {
consumer.accept(wrapper);
}
/*
* for (WidgetWrapper wrapper : panelManager.getReverseOpenPanelsWrappers()) {
* consumer.accept(wrapper);
* }
*/
}

private static final Component USAGE_NARRATION = Component.translatable("narrator.screen.usage");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@ void checkDirty() {
this.panelsClone.clear();
this.panelsClone.addAll(this.panels);

this.panelWrappers.clear();
this.panelsClone.stream()
.map(WidgetWrapper::new)
.forEach(this.panelWrappers::add);
/*
* this.panelWrappers.clear();
* this.panelsClone.stream()
* .map(WidgetWrapper::new)
* .forEach(this.panelWrappers::add);
*/

this.dirty = false;
}
Expand Down
Loading
Loading