Skip to content

Commit d4ba9a9

Browse files
authored
Refactor Container customiztion and phantom slots & crafting grids (#118)
* separate phantom slots from vanilla slots * UISettings, extendable ModularContainer, remove ContainerCustomizer and more * reimplement shift transfer to phantom slots * use final static vars for sync ids * easy crafting grids & player inv improvements * fix * fix
1 parent b069b4d commit d4ba9a9

40 files changed

+1502
-933
lines changed

src/main/java/com/cleanroommc/modularui/api/IGuiHolder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cleanroommc.modularui.factory.GuiData;
44
import com.cleanroommc.modularui.screen.ModularPanel;
55
import com.cleanroommc.modularui.screen.ModularScreen;
6-
6+
import com.cleanroommc.modularui.screen.UISettings;
77
import com.cleanroommc.modularui.value.sync.PanelSyncManager;
88

99
import net.minecraftforge.fml.relauncher.Side;
@@ -19,7 +19,7 @@ public interface IGuiHolder<T extends GuiData> {
1919
* Only called on client side.
2020
*
2121
* @param data information about the creation context
22-
* @param mainPanel the panel created in {@link #buildUI(GuiData, PanelSyncManager)}
22+
* @param mainPanel the panel created in {@link #buildUI(GuiData, PanelSyncManager, UISettings)}
2323
* @return a modular screen instance with the given panel
2424
*/
2525
@SideOnly(Side.CLIENT)
@@ -34,6 +34,7 @@ default ModularScreen createScreen(T data, ModularPanel mainPanel) {
3434
*
3535
* @param data information about the creation context
3636
* @param syncManager sync handler where widget sync handlers should be registered
37+
* @param settings settings which apply to the whole ui and not just this panel
3738
*/
38-
ModularPanel buildUI(T data, PanelSyncManager syncManager);
39+
ModularPanel buildUI(T data, PanelSyncManager syncManager, UISettings settings);
3940
}

src/main/java/com/cleanroommc/modularui/api/UIFactory.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package com.cleanroommc.modularui.api;
22

33
import com.cleanroommc.modularui.factory.GuiData;
4-
import com.cleanroommc.modularui.screen.GuiContainerWrapper;
5-
import com.cleanroommc.modularui.screen.ModularContainer;
6-
import com.cleanroommc.modularui.screen.ModularPanel;
7-
import com.cleanroommc.modularui.screen.ModularScreen;
4+
import com.cleanroommc.modularui.screen.*;
85
import com.cleanroommc.modularui.value.sync.PanelSyncManager;
96

107
import net.minecraft.entity.player.EntityPlayer;
@@ -36,16 +33,17 @@ public interface UIFactory<D extends GuiData> {
3633
*
3734
* @param guiData gui data
3835
* @param syncManager sync manager
36+
* @param settings ui settings
3937
* @return new main panel
4038
*/
4139
@ApiStatus.OverrideOnly
42-
ModularPanel createPanel(D guiData, PanelSyncManager syncManager);
40+
ModularPanel createPanel(D guiData, PanelSyncManager syncManager, UISettings settings);
4341

4442
/**
4543
* Creates the screen for the GUI. Is only called on client side.
4644
*
4745
* @param guiData gui data
48-
* @param mainPanel main panel created in {@link #createPanel(GuiData, PanelSyncManager)}
46+
* @param mainPanel main panel created in {@link #createPanel(GuiData, PanelSyncManager, UISettings)}
4947
* @return new main panel
5048
*/
5149
@SideOnly(Side.CLIENT)
@@ -68,6 +66,28 @@ default IMuiScreen createScreenWrapper(ModularContainer container, ModularScreen
6866
return new GuiContainerWrapper(container, screen);
6967
}
7068

69+
/**
70+
* The default container supplier. This is called when no custom container in {@link UISettings} is set.
71+
*
72+
* @return new container instance
73+
*/
74+
default ModularContainer createContainer() {
75+
return new ModularContainer();
76+
}
77+
78+
/**
79+
* A default function to check if the current interacting player can interact with the ui. If not overridden on {@link UISettings},
80+
* then this is called every tick while a UI opened by this factory is open. Once this function returns false, the UI is immediately
81+
* closed.
82+
*
83+
* @param player current interacting player
84+
* @param guiData gui data of the current ui
85+
* @return if the player can interact with the player.
86+
*/
87+
default boolean canInteractWith(EntityPlayer player, D guiData) {
88+
return player == guiData.getPlayer();
89+
}
90+
7191
/**
7292
* Writes the gui data to a buffer.
7393
*

src/main/java/com/cleanroommc/modularui/api/widget/IVanillaSlot.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
/**
66
* Marks a {@link IWidget}, that this is a vanilla item slot.
77
*/
8-
@FunctionalInterface
98
public interface IVanillaSlot {
109

1110
/**
1211
* @return the item slot of this widget
1312
*/
1413
Slot getVanillaSlot();
14+
15+
boolean handleAsVanillaSlot();
1516
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.cleanroommc.modularui.core.mixin;
2+
3+
import net.minecraft.inventory.Container;
4+
import net.minecraft.inventory.InventoryCrafting;
5+
6+
import net.minecraft.item.ItemStack;
7+
import net.minecraft.util.NonNullList;
8+
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.gen.Accessor;
11+
12+
@Mixin(InventoryCrafting.class)
13+
public interface InventoryCraftingAccessor {
14+
15+
@Accessor
16+
NonNullList<ItemStack> getStackList();
17+
18+
@Accessor
19+
Container getEventHandler();
20+
}

src/main/java/com/cleanroommc/modularui/drawable/ItemDrawable.java

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import com.cleanroommc.modularui.utils.JsonHelper;
88
import com.cleanroommc.modularui.widget.Widget;
99

10+
import net.minecraft.block.Block;
11+
import net.minecraft.item.Item;
1012
import net.minecraft.item.ItemStack;
1113
import net.minecraft.nbt.JsonToNBT;
1214
import net.minecraft.nbt.NBTException;
@@ -17,18 +19,46 @@
1719
import com.google.gson.JsonObject;
1820
import com.google.gson.JsonParseException;
1921
import org.jetbrains.annotations.NotNull;
22+
import org.jetbrains.annotations.Nullable;
2023

2124
import java.util.NoSuchElementException;
2225

2326
public class ItemDrawable implements IDrawable {
2427

2528
private ItemStack item = ItemStack.EMPTY;
2629

27-
public ItemDrawable() {
28-
}
30+
public ItemDrawable() {}
2931

3032
public ItemDrawable(@NotNull ItemStack item) {
31-
this.item = item;
33+
setItem(item);
34+
}
35+
36+
public ItemDrawable(@NotNull Item item) {
37+
setItem(item);
38+
}
39+
40+
public ItemDrawable(@NotNull Item item, int meta) {
41+
setItem(item, meta);
42+
}
43+
44+
public ItemDrawable(@NotNull Item item, int meta, int amount) {
45+
setItem(item, meta, amount);
46+
}
47+
48+
public ItemDrawable(@NotNull Item item, int meta, int amount, @Nullable NBTTagCompound nbt) {
49+
setItem(item, meta, amount, nbt);
50+
}
51+
52+
public ItemDrawable(@NotNull Block item) {
53+
setItem(item);
54+
}
55+
56+
public ItemDrawable(@NotNull Block item, int meta) {
57+
setItem(item, meta);
58+
}
59+
60+
public ItemDrawable(@NotNull Block item, int meta, int amount) {
61+
setItem(new ItemStack(item, amount, meta));
3262
}
3363

3464
@SideOnly(Side.CLIENT)
@@ -52,6 +82,36 @@ public ItemDrawable setItem(@NotNull ItemStack item) {
5282
return this;
5383
}
5484

85+
public ItemDrawable setItem(@NotNull Item item) {
86+
return setItem(item, 0, 1, null);
87+
}
88+
89+
public ItemDrawable setItem(@NotNull Item item, int meta) {
90+
return setItem(item, meta, 1, null);
91+
}
92+
93+
public ItemDrawable setItem(@NotNull Item item, int meta, int amount) {
94+
return setItem(item, meta, amount, null);
95+
}
96+
97+
public ItemDrawable setItem(@NotNull Item item, int meta, int amount, @Nullable NBTTagCompound nbt) {
98+
ItemStack itemStack = new ItemStack(item, amount, meta);
99+
itemStack.setTagCompound(nbt);
100+
return setItem(itemStack);
101+
}
102+
103+
public ItemDrawable setItem(@NotNull Block item) {
104+
return setItem(item, 0, 1);
105+
}
106+
107+
public ItemDrawable setItem(@NotNull Block item, int meta) {
108+
return setItem(item, meta, 1);
109+
}
110+
111+
public ItemDrawable setItem(@NotNull Block item, int meta, int amount) {
112+
return setItem(new ItemStack(item, amount, meta));
113+
}
114+
55115
public static ItemDrawable ofJson(JsonObject json) {
56116
String itemS = JsonHelper.getString(json, null, "item");
57117
if (itemS == null) throw new JsonParseException("Item property not found!");

src/main/java/com/cleanroommc/modularui/factory/AbstractUIFactory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.cleanroommc.modularui.screen.ModularPanel;
66
import com.cleanroommc.modularui.screen.ModularScreen;
77

8+
import com.cleanroommc.modularui.screen.UISettings;
89
import com.cleanroommc.modularui.value.sync.PanelSyncManager;
910

1011
import org.jetbrains.annotations.NotNull;
@@ -28,9 +29,9 @@ protected AbstractUIFactory(String name) {
2829
public abstract IGuiHolder<T> getGuiHolder(T data);
2930

3031
@Override
31-
public ModularPanel createPanel(T guiData, PanelSyncManager syncManager) {
32+
public ModularPanel createPanel(T guiData, PanelSyncManager syncManager, UISettings settings) {
3233
IGuiHolder<T> guiHolder = Objects.requireNonNull(getGuiHolder(guiData), "Gui holder must not be null!");
33-
return guiHolder.buildUI(guiData, syncManager);
34+
return guiHolder.buildUI(guiData, syncManager, settings);
3435
}
3536

3637
@Override

src/main/java/com/cleanroommc/modularui/factory/ClientGUI.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.cleanroommc.modularui.factory;
22

33
import com.cleanroommc.modularui.api.MCHelper;
4-
import com.cleanroommc.modularui.screen.ContainerCustomizer;
54
import com.cleanroommc.modularui.screen.JeiSettingsImpl;
5+
import com.cleanroommc.modularui.screen.ModularContainer;
66
import com.cleanroommc.modularui.screen.ModularScreen;
7+
import com.cleanroommc.modularui.screen.UISettings;
78

89
import net.minecraft.client.gui.GuiScreen;
910
import net.minecraftforge.fml.relauncher.Side;
@@ -12,6 +13,8 @@
1213
import org.jetbrains.annotations.NotNull;
1314
import org.jetbrains.annotations.Nullable;
1415

16+
import java.util.function.Supplier;
17+
1518
/**
1619
* Helper class to open client only GUIs. This class is safe to use inside a Modular GUI.
1720
* Direct calls to {@link net.minecraft.client.Minecraft#displayGuiScreen(GuiScreen)} are redirected to this class if
@@ -29,7 +32,7 @@ private ClientGUI() {
2932
* @param screen new modular screen
3033
*/
3134
public static void open(@NotNull ModularScreen screen) {
32-
open(screen, new JeiSettingsImpl(), null);
35+
open(screen, new UISettings());
3336
}
3437

3538
/**
@@ -40,30 +43,45 @@ public static void open(@NotNull ModularScreen screen) {
4043
* @param jeiSettings custom jei settings
4144
*/
4245
public static void open(@NotNull ModularScreen screen, @NotNull JeiSettingsImpl jeiSettings) {
43-
GuiManager.openScreen(screen, jeiSettings, null);
46+
GuiManager.openScreen(screen, new UISettings(jeiSettings));
47+
}
48+
49+
/**
50+
* Opens a modular screen on the next client tick with custom jei settings.
51+
* It needs to be opened in next tick, because we might break the current GUI if we open it now.
52+
*
53+
* @param screen new modular screen
54+
* @param container custom container
55+
*/
56+
public static void open(@NotNull ModularScreen screen, @Nullable Supplier<ModularContainer> container) {
57+
UISettings settings = new UISettings();
58+
settings.customContainer(container);
59+
GuiManager.openScreen(screen, settings);
4460
}
4561

4662
/**
4763
* Opens a modular screen on the next client tick with custom jei settings.
4864
* It needs to be opened in next tick, because we might break the current GUI if we open it now.
4965
*
50-
* @param screen new modular screen
51-
* @param containerCustomizer container customizer
66+
* @param screen new modular screen
67+
* @param jeiSettings custom jei settings
68+
* @param container custom container
5269
*/
53-
public static void open(@NotNull ModularScreen screen, @NotNull ContainerCustomizer containerCustomizer) {
54-
GuiManager.openScreen(screen, new JeiSettingsImpl(), containerCustomizer);
70+
public static void open(@NotNull ModularScreen screen, @NotNull JeiSettingsImpl jeiSettings, @Nullable Supplier<ModularContainer> container) {
71+
UISettings settings = new UISettings(jeiSettings);
72+
settings.customContainer(container);
73+
GuiManager.openScreen(screen, settings);
5574
}
5675

5776
/**
5877
* Opens a modular screen on the next client tick with custom jei settings.
5978
* It needs to be opened in next tick, because we might break the current GUI if we open it now.
6079
*
61-
* @param screen new modular screen
62-
* @param jeiSettings custom jei settings
63-
* @param containerCustomizer container customizer
80+
* @param screen new modular screen
81+
* @param settings ui settings
6482
*/
65-
public static void open(@NotNull ModularScreen screen, @NotNull JeiSettingsImpl jeiSettings, @Nullable ContainerCustomizer containerCustomizer) {
66-
GuiManager.openScreen(screen, jeiSettings, containerCustomizer);
83+
public static void open(@NotNull ModularScreen screen, @NotNull UISettings settings) {
84+
GuiManager.openScreen(screen, settings);
6785
}
6886

6987
/**
Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.cleanroommc.modularui.factory;
22

3-
import com.cleanroommc.modularui.api.JeiSettings;
43
import com.cleanroommc.modularui.network.NetworkUtils;
5-
import com.cleanroommc.modularui.screen.JeiSettingsImpl;
64

75
import net.minecraft.entity.player.EntityPlayer;
86
import net.minecraft.item.ItemStack;
@@ -12,7 +10,6 @@
1210
/**
1311
* This class and subclasses are holding necessary data to find the exact same GUI on client and server.
1412
* For example, if the GUI was opened by right-clicking a TileEntity, then this data needs a world and a block pos.
15-
* Additionally, this can be used to configure JEI via {@link #getJeiSettings()}.
1613
* <p>
1714
* Also see {@link PosGuiData} (useful for TileEntities), {@link SidedPosGuiData} (useful for covers from GregTech) and
1815
* {@link HandGuiData} (useful for guis opened by interacting with an item in the players hand) for default implementations.
@@ -21,7 +18,6 @@
2118
public class GuiData {
2219

2320
private final EntityPlayer player;
24-
private JeiSettings jeiSettings;
2521

2622
public GuiData(EntityPlayer player) {
2723
this.player = Objects.requireNonNull(player);
@@ -42,19 +38,4 @@ public ItemStack getMainHandItem() {
4238
public ItemStack getOffHandItem() {
4339
return this.player.getHeldItemOffhand();
4440
}
45-
46-
public JeiSettings getJeiSettings() {
47-
if (this.jeiSettings == null) {
48-
throw new IllegalStateException("Not yet initialised!");
49-
}
50-
return this.jeiSettings;
51-
}
52-
53-
final JeiSettingsImpl getJeiSettingsImpl() {
54-
return (JeiSettingsImpl) this.jeiSettings;
55-
}
56-
57-
final void setJeiSettings(JeiSettings jeiSettings) {
58-
this.jeiSettings = Objects.requireNonNull(jeiSettings);
59-
}
6041
}

0 commit comments

Comments
 (0)