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

Migrate to ModularUI: Covers #2069

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
*/
dependencies {
// Hard Dependencies
//api files("libs/modularui-2.1.0-dev.jar")
implementation "curse.maven:modularui-624243:4692437"
implementation files("libs/modularui-2.2.2-dev.jar")
//implementation 'curse.maven:modularui-624243:4779301-sources-4779302'

// the CCL deobf jar uses very old MCP mappings, making it error at runtime in runClient/runServer
// therefore we manually deobf the regular jar
Expand Down
Binary file removed libs/modularui-2.1.0-dev.jar
Binary file not shown.
Binary file added libs/modularui-2.2.2-dev.jar
Binary file not shown.
Binary file added libs/modularui-2.2.2-sources.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion src/main/java/gregtech/GregTechMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
+ "after:forestry;"
+ "after:jei@[4.15.0,);"
+ "after:crafttweaker@[4.1.20,);"
+ "after:groovyscript@[0.6.0,);"
+ "after:groovyscript@[0.5.1,);"
+ "after:theoneprobe;"
+ "after:hwyla;")
public class GregTechMod {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/gregtech/api/cover/CoverWithUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ default ModularScreen createScreen(GuiCreationContext guiCreationContext, Modula
}

@Override
default ModularPanel buildUI(GuiCreationContext guiCreationContext, GuiSyncManager guiSyncManager, boolean isClient) {
default ModularPanel buildUI(GuiCreationContext creationContext, GuiSyncManager syncManager, boolean isClient) {
return null;
}
}
76 changes: 76 additions & 0 deletions src/main/java/gregtech/api/cover/filter/Filter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package gregtech.api.cover.filter;

import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.value.sync.BooleanSyncValue;
import com.cleanroommc.modularui.value.sync.GuiSyncManager;
import com.cleanroommc.modularui.widgets.CycleButtonWidget;
import gregtech.api.newgui.GuiTextures;
import gregtech.api.util.IDirtyNotifiable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import org.jetbrains.annotations.NotNull;

public abstract class Filter<T> {

private IDirtyNotifiable dirtyNotifiable;
private boolean inverted = false;

public abstract boolean matches(T t, boolean ignoreInverted);

public boolean matches(T t) {
return matches(t, false);
}

/**
* Determines how much can transferred based on t.
*
* @param object by default an instance of T, but can be different fe. in {@link gregtech.common.covers.filter.item.ItemFilter}
* @param globalTransferLimit transferLimit of the holder
* @return transfer limit
*/
public abstract int getTransferLimit(Object object, int globalTransferLimit);

/**
* Creates the filter ui.
* Ideally you manually set the size of the resulting widgets, so that covers can auto size themselves properly.
*
* @return the non-null filter ui widget
*/
@NotNull
public abstract IWidget createFilterUI(ModularPanel mainPanel, GuiSyncManager syncManager);

public IWidget createBlacklistButton(ModularPanel mainPanel, GuiSyncManager syncManager) {
return new CycleButtonWidget()
.value(new BooleanSyncValue(this::isInverted, this::setInverted))
.texture(GuiTextures.BUTTON_BLACKLIST)
.size(18, 18)
.pos(121, 0);
}

public void writeToNBT(NBTTagCompound nbt) {
nbt.setBoolean("Inverted", this.inverted);
}

public void readFromNBT(NBTTagCompound nbt) {
this.inverted = nbt.getBoolean("Inverted");
}

public boolean isInverted() {
return inverted;
}

public void setInverted(boolean inverted) {
this.inverted = inverted;
}

public final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) {
this.dirtyNotifiable = dirtyNotifiable;
}

public final void markDirty() {
if (dirtyNotifiable != null) {
dirtyNotifiable.markAsDirty();
}
}
}
207 changes: 207 additions & 0 deletions src/main/java/gregtech/api/cover/filter/FilterHolder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package gregtech.api.cover.filter;

import com.cleanroommc.modularui.api.drawable.IKey;
import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.manager.GuiCreationContext;
import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.utils.Color;
import com.cleanroommc.modularui.value.sync.GuiSyncManager;
import com.cleanroommc.modularui.widget.ParentWidget;
import com.cleanroommc.modularui.widgets.ButtonWidget;
import com.cleanroommc.modularui.widgets.ItemSlot;
import com.cleanroommc.modularui.widgets.slot.ModularSlot;
import gregtech.api.newgui.FilterPanelSyncHandler;
import gregtech.api.newgui.GTGuis;
import gregtech.api.newgui.GuiTextures;
import gregtech.api.util.IDirtyNotifiable;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
import org.jetbrains.annotations.Nullable;

public abstract class FilterHolder<T, F extends Filter<T>> implements INBTSerializable<NBTTagCompound> {

@Nullable
private F currentFilter;
protected final IDirtyNotifiable dirtyNotifiable;
private FilterMode mode = FilterMode.BOTH;
protected final IItemHandlerModifiable filterInventory;
protected final int filterSlotIndex;
private final boolean saveFilterInventory;

protected FilterHolder(IDirtyNotifiable dirtyNotifiable) {
this(new ItemStackHandler() {
@Override
public int getSlotLimit(int slot) {
return 1;
}
}, 0, dirtyNotifiable);
}

protected FilterHolder(IItemHandlerModifiable filterInventory, int filterSlotIndex, IDirtyNotifiable dirtyNotifiable) {
this.filterInventory = filterInventory;
this.filterSlotIndex = filterSlotIndex;
this.dirtyNotifiable = dirtyNotifiable;
this.saveFilterInventory = filterInventory instanceof INBTSerializable<?>;
}

public IWidget createFilterUI(ModularPanel mainPanel, GuiCreationContext creationContext, GuiSyncManager syncManager) {
ButtonWidget<?> openFilterConfigButton = new ButtonWidget<>();
FilterPanelSyncHandler filterPanelSyncHandler = new FilterPanelSyncHandler(mainPanel, this);
syncManager.syncValue("filter_config", filterPanelSyncHandler);
return new ParentWidget<>()
.height(18).widthRel(1f)
.child(IKey.lang("cover.filter.label").asWidget().height(18).left(0))
.child(new ItemSlot()
.slot(new ModularSlot(this.filterInventory, this.filterSlotIndex)
.singletonSlotGroup()
.filter(item -> getFilterOf(item) != null)
.changeListener((stack, onlyAmountChanged, client, init) -> {
checkFilter(stack);
if (!init && client) {
openFilterConfigButton.setEnabled(hasFilter());
if (!hasFilter() || filterPanelSyncHandler.isPanelOpen()) {
filterPanelSyncHandler.closePanel();
} else {
filterPanelSyncHandler.openPanel();
}
}
}))
.pos(60, 0))
.child(openFilterConfigButton
.onMousePressed(mouseButton -> {
if (hasFilter() && !filterPanelSyncHandler.isPanelOpen()) {
filterPanelSyncHandler.openPanel();
}
return true;
})
.overlay(IKey.lang("cover.filter.settings_open.label"))
.pos(80, 0)
.size(82, 18));
}

public ModularPanel buildFilterPanel(ModularPanel mainPanel, GuiSyncManager syncManager, FilterPanelSyncHandler filterPanelSyncHandler) {
ModularPanel panel;
if (!hasFilter()) {
return (panel = GTGuis.createPanel("error", 32, 30))
.background(GuiTextures.BACKGROUND)
.child(IKey.lang("An Error occurred!").color(Color.RED.normal).asWidget()
.size(130, 20))
.child(ButtonWidget.panelCloseButton(filterPanelSyncHandler));
}

IWidget filterUI = this.currentFilter.createFilterUI(mainPanel, syncManager);
filterUI.flex().pos(5, 20).margin(5);
panel = new ModularPanel("filter_config")
.coverChildren()
.relative(mainPanel)
.top(0)
.rightRel(1f)
.padding(5)
.child(IKey.lang("cover.filter.settings.label").asWidget().pos(5, 5));
panel.child(ButtonWidget.panelCloseButton(filterPanelSyncHandler))
.child(filterUI);
return panel;
}

@Nullable
public F getFilterOf(ItemStack stack) {
if (stack == null || stack.isEmpty()) {
return null;
}
Filter<?> filter = FilterRegistry.createFilter(stack);
if (filter == null) {
return null;
}
if (getFilterClass().isAssignableFrom(filter.getClass())) {
return (F) filter;
}
return null;
}

public abstract Class<F> getFilterClass();

public void checkFilter(ItemStack itemStack) {
F filter = getFilterOf(itemStack);
if (currentFilter == null ^ filter == null || (currentFilter != null && currentFilter.getClass() != filter.getClass())) {
setCurrentFilter(filter);
}
}

public void onFilterChanged(@Nullable F oldFilter, @Nullable F newFilter) {
}

public void setCurrentFilter(@Nullable F currentFilter) {
if (this.currentFilter != currentFilter) {
F oldFilter = this.currentFilter;
this.currentFilter = currentFilter;
if (this.currentFilter != null) {
this.currentFilter.setDirtyNotifiable(dirtyNotifiable);
}
onFilterChanged(oldFilter, this.currentFilter);
}
}

@Nullable
public F getCurrentFilter() {
return currentFilter;
}

public boolean hasFilter() {
return currentFilter != null;
}

public void setFilterMode(FilterMode mode) {
this.mode = mode;
}

public FilterMode getFilterMode() {
return mode;
}

public IItemHandlerModifiable getFilterInventory() {
return filterInventory;
}

public boolean test(T t, boolean ignoresInverted) {
return currentFilter == null || currentFilter.matches(t, ignoresInverted);
}

public boolean test(T t) {
return currentFilter == null || currentFilter.matches(t);
}

@Override
public NBTTagCompound serializeNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setByte("Mode", (byte) mode.ordinal());
if (currentFilter != null) {
NBTTagCompound filterInventory = new NBTTagCompound();
currentFilter.writeToNBT(filterInventory);
nbt.setTag("Filter", filterInventory);
}
if (saveFilterInventory) {
nbt.setTag("FilterInventory", ((INBTSerializable<NBTTagCompound>) filterInventory).serializeNBT());
}
return nbt;
}

@Override
public void deserializeNBT(NBTTagCompound nbt) {
this.mode = FilterMode.values()[nbt.getByte("Mode")];
if (saveFilterInventory) {
((INBTSerializable<NBTTagCompound>) filterInventory).deserializeNBT(nbt.getCompoundTag("FilterInventory"));
}
if (currentFilter == null) {
checkFilter(filterInventory.getStackInSlot(filterSlotIndex));
}
if (currentFilter != null) {
this.currentFilter.readFromNBT(nbt.getCompoundTag("Filter"));
if (nbt.hasKey("IsBlacklist")) {
this.currentFilter.setInverted(nbt.getBoolean("IsBlacklist"));
}
}
}
}
6 changes: 6 additions & 0 deletions src/main/java/gregtech/api/cover/filter/FilterMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package gregtech.api.cover.filter;

public enum FilterMode {

INSERT, EXTRACT, BOTH
}
40 changes: 40 additions & 0 deletions src/main/java/gregtech/api/cover/filter/FilterRegistry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gregtech.api.cover.filter;

import gregtech.api.util.ItemStackHashStrategy;
import gregtech.common.covers.filter.fluid.SimpleFluidFilter;
import gregtech.common.covers.filter.item.SimpleItemFilter;
import gregtech.common.items.MetaItems;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
import net.minecraft.item.ItemStack;

import javax.annotation.Nullable;
import java.util.Map;
import java.util.function.Supplier;

public class FilterRegistry {

public static void init() {
register(MetaItems.ITEM_FILTER.getStackForm(), SimpleItemFilter::new);
//register(MetaItems.ORE_DICTIONARY_FILTER.getStackForm(), OreDictFilter::new);
//register(MetaItems.SMART_FILTER.getStackForm(), SmartFilter::new);
register(MetaItems.FLUID_FILTER.getStackForm(), SimpleFluidFilter::new);
}

private static final Map<ItemStack, Supplier<Filter<?>>> REGISTRY = new Object2ObjectOpenCustomHashMap<>(ItemStackHashStrategy.builder()
.compareItem(true)
.compareDamage(true)
.build());

public static void register(ItemStack item, Supplier<Filter<?>> filterCreator) {
REGISTRY.put(item.copy(), filterCreator);
}

@Nullable
public static Filter<?> createFilter(ItemStack item) {
Supplier<Filter<?>> filterCreator = REGISTRY.get(item);
if (filterCreator == null) {
return null;
}
return filterCreator.get();
}
}
21 changes: 21 additions & 0 deletions src/main/java/gregtech/api/newgui/FilterPanelSyncHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gregtech.api.newgui;

import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.value.sync.GuiSyncManager;
import com.cleanroommc.modularui.value.sync.PanelSyncHandler;
import gregtech.api.cover.filter.FilterHolder;

public class FilterPanelSyncHandler extends PanelSyncHandler {

private final FilterHolder<?, ?> filterHolder;

public FilterPanelSyncHandler(ModularPanel mainPanel, FilterHolder<?, ?> filterHolder) {
super(mainPanel);
this.filterHolder = filterHolder;
}

@Override
public ModularPanel createUI(ModularPanel mainPanel, GuiSyncManager syncManager) {
return this.filterHolder.buildFilterPanel(mainPanel, syncManager, this);
}
}
Loading