Improved Window- and GuiBuilder

- New, more flexible GuiBuilders
- Cloneable Window- and GuiBuilder
- Modifiers for Window- and GuiBuilder
- Multiple rename handlers for AnvilWindows
This commit is contained in:
NichtStudioCode 2023-01-29 17:18:07 +01:00
parent 79cc152838
commit d00922379d
72 changed files with 1168 additions and 503 deletions

@ -15,6 +15,7 @@ import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.inventoryaccess.util.ReflectionUtils; import xyz.xenondevs.inventoryaccess.util.ReflectionUtils;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory { class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
@ -24,7 +25,7 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
private static final Field RESULT_INVENTORY_FIELD = ReflectionUtils.getField(ContainerAnvil.class, true, "resultInventory"); private static final Field RESULT_INVENTORY_FIELD = ReflectionUtils.getField(ContainerAnvil.class, true, "resultInventory");
private final IChatBaseComponent title; private final IChatBaseComponent title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final EntityPlayer player; private final EntityPlayer player;
@ -34,16 +35,16 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, Consumer<String> renameHandler) { public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.inventory, super(player.nextContainerCounter(), player.inventory,
ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0))); ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
repairInventory = ReflectionUtils.getFieldValue(REPAIR_INVENTORY_FIELD, this); repairInventory = ReflectionUtils.getFieldValue(REPAIR_INVENTORY_FIELD, this);
@ -138,8 +139,9 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -25,28 +25,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title; private final Component title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final ServerPlayer player; private final ServerPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) { public AnvilInventoryImpl(ServerPlayer player, Component title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.getInventory(), super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0))); ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(),
@ -145,8 +146,9 @@ class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -25,28 +25,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title; private final Component title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final ServerPlayer player; private final ServerPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) { public AnvilInventoryImpl(ServerPlayer player, Component title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.getInventory(), super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0))); ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(),
@ -145,8 +146,9 @@ class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -25,28 +25,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title; private final Component title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final ServerPlayer player; private final ServerPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) { public AnvilInventoryImpl(ServerPlayer player, Component title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.getInventory(), super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0))); ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(),
@ -145,8 +146,9 @@ class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -15,6 +15,7 @@ import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.inventoryaccess.util.ReflectionUtils; import xyz.xenondevs.inventoryaccess.util.ReflectionUtils;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory { class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
@ -24,7 +25,7 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
private static final Field RESULT_INVENTORY_FIELD = ReflectionUtils.getField(ContainerAnvil.class, true, "resultInventory"); private static final Field RESULT_INVENTORY_FIELD = ReflectionUtils.getField(ContainerAnvil.class, true, "resultInventory");
private final IChatBaseComponent title; private final IChatBaseComponent title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final EntityPlayer player; private final EntityPlayer player;
@ -34,16 +35,16 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, Consumer<String> renameHandler) { public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.inventory, super(player.nextContainerCounter(), player.inventory,
ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0))); ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
repairInventory = ReflectionUtils.getFieldValue(REPAIR_INVENTORY_FIELD, this); repairInventory = ReflectionUtils.getFieldValue(REPAIR_INVENTORY_FIELD, this);
@ -138,8 +139,9 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -13,28 +13,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory { class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
private final IChatBaseComponent title; private final IChatBaseComponent title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final EntityPlayer player; private final EntityPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, Consumer<String> renameHandler) { public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.inventory, super(player.nextContainerCounter(), player.inventory,
ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0))); ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(containerAccess.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(containerAccess.getLocation(),
@ -125,8 +126,9 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -13,28 +13,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory { class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
private final IChatBaseComponent title; private final IChatBaseComponent title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final EntityPlayer player; private final EntityPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, Consumer<String> renameHandler) { public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.inventory, super(player.nextContainerCounter(), player.inventory,
ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0))); ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(containerAccess.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(containerAccess.getLocation(),
@ -125,8 +126,9 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -13,28 +13,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory { class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
private final IChatBaseComponent title; private final IChatBaseComponent title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final EntityPlayer player; private final EntityPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, Consumer<String> renameHandler) { public AnvilInventoryImpl(EntityPlayer player, IChatBaseComponent title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.inventory, super(player.nextContainerCounter(), player.inventory,
ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0))); ContainerAccess.at(player.getWorld(), new BlockPosition(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(containerAccess.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(containerAccess.getLocation(),
@ -125,8 +126,9 @@ class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -24,28 +24,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title; private final Component title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final ServerPlayer player; private final ServerPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) { public AnvilInventoryImpl(ServerPlayer player, Component title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.getInventory(), super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0))); ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(),
@ -139,8 +140,9 @@ class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -25,28 +25,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title; private final Component title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final ServerPlayer player; private final ServerPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) { public AnvilInventoryImpl(ServerPlayer player, Component title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.getInventory(), super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0))); ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(),
@ -145,8 +146,9 @@ class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -25,28 +25,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title; private final Component title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final ServerPlayer player; private final ServerPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) { public AnvilInventoryImpl(ServerPlayer player, Component title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.getInventory(), super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0))); ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(),
@ -145,8 +146,9 @@ class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -25,28 +25,29 @@ import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title; private final Component title;
private final Consumer<String> renameHandler; private final List<Consumer<String>> renameHandlers;
private final CraftInventoryView view; private final CraftInventoryView view;
private final ServerPlayer player; private final ServerPlayer player;
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List<Consumer<String>> renameHandlers) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers);
} }
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) { public AnvilInventoryImpl(ServerPlayer player, Component title, List<Consumer<String>> renameHandlers) {
super(player.nextContainerCounter(), player.getInventory(), super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0))); ContainerLevelAccess.create(player.level, new BlockPos(0, 0, 0)));
this.title = title; this.title = title;
this.renameHandler = renameHandler; this.renameHandlers = renameHandlers;
this.player = player; this.player = player;
CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(),
@ -145,8 +146,9 @@ class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// save rename text // save rename text
text = s; text = s;
// call the rename handler // call rename handlers
if (renameHandler != null) renameHandler.accept(s); if (renameHandlers != null)
renameHandlers.forEach(handler -> handler.accept(s));
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again // the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2); sendItem(2);

@ -2,6 +2,7 @@ package xyz.xenondevs.inventoryaccess;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.CartographyInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.CartographyInventory;
import xyz.xenondevs.inventoryaccess.abstraction.util.InventoryUtils; import xyz.xenondevs.inventoryaccess.abstraction.util.InventoryUtils;
@ -11,6 +12,7 @@ import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.inventoryaccess.util.ReflectionUtils; import xyz.xenondevs.inventoryaccess.util.ReflectionUtils;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
public class InventoryAccess { public class InventoryAccess {
@ -62,12 +64,12 @@ public class InventoryAccess {
* *
* @param player The {@link Player} that should see this {@link AnvilInventory} * @param player The {@link Player} that should see this {@link AnvilInventory}
* @param title The inventory title * @param title The inventory title
* @param renameHandler A {@link Consumer} that is called whenever the {@link Player} * @param renameHandlers A list of {@link Consumer}s that are called whenever the {@link Player}
* types something in the renaming section of the anvil * types something in the renaming section of the anvil.
* @return The {@link AnvilInventory} * @return The {@link AnvilInventory}
*/ */
public static AnvilInventory createAnvilInventory(@NotNull Player player, @NotNull ComponentWrapper title, Consumer<String> renameHandler) { public static AnvilInventory createAnvilInventory(@NotNull Player player, @NotNull ComponentWrapper title, @Nullable List<@NotNull Consumer<String>> renameHandlers) {
return ReflectionUtils.construct(ANVIL_INVENTORY_CONSTRUCTOR, player, title, renameHandler); return ReflectionUtils.construct(ANVIL_INVENTORY_CONSTRUCTOR, player, title, renameHandlers);
} }
/** /**

@ -2,6 +2,7 @@ package xyz.xenondevs.inventoryaccess.component;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.jetbrains.annotations.NotNull;
public class AdventureComponentWrapper implements ComponentWrapper { public class AdventureComponentWrapper implements ComponentWrapper {
@ -12,8 +13,17 @@ public class AdventureComponentWrapper implements ComponentWrapper {
} }
@Override @Override
public String serializeToJson() { public @NotNull String serializeToJson() {
return GsonComponentSerializer.gson().serialize(component); return GsonComponentSerializer.gson().serialize(component);
} }
@Override
public @NotNull ComponentWrapper clone() {
try {
return (ComponentWrapper) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
} }

@ -2,6 +2,7 @@ package xyz.xenondevs.inventoryaccess.component;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
import org.jetbrains.annotations.NotNull;
public class BaseComponentWrapper implements ComponentWrapper { public class BaseComponentWrapper implements ComponentWrapper {
@ -12,8 +13,21 @@ public class BaseComponentWrapper implements ComponentWrapper {
} }
@Override @Override
public String serializeToJson() { public @NotNull String serializeToJson() {
return ComponentSerializer.toString(components); return ComponentSerializer.toString(components);
} }
@Override
public @NotNull BaseComponentWrapper clone() {
try {
var clone = (BaseComponentWrapper) super.clone();
for (int i = 0; i < clone.components.length; i++) {
clone.components[i] = clone.components[i].duplicate();
}
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
} }

@ -1,7 +1,11 @@
package xyz.xenondevs.inventoryaccess.component; package xyz.xenondevs.inventoryaccess.component;
public interface ComponentWrapper { import org.jetbrains.annotations.NotNull;
String serializeToJson(); public interface ComponentWrapper extends Cloneable {
@NotNull String serializeToJson();
@NotNull ComponentWrapper clone();
} }

@ -0,0 +1,11 @@
@file:Suppress("PackageDirectoryMismatch")
package xyz.xenondevs.invui.gui.builder
import xyz.xenondevs.invui.gui.Gui
fun <G : Gui, B : GuiBuilder<G>> GuiType<G, B>.create(builderConsumer: B.() -> Unit): G {
val builder = builder()
builder.builderConsumer()
return builder.build()
}

@ -1,10 +1,8 @@
@file:Suppress("PackageDirectoryMismatch") @file:Suppress("PackageDirectoryMismatch")
package xyz.xenondevs.invui.window.type package xyz.xenondevs.invui.window.builder
import xyz.xenondevs.invui.window.Window import xyz.xenondevs.invui.window.Window
import xyz.xenondevs.invui.window.builder.WindowBuilder
import xyz.xenondevs.invui.window.builder.WindowType
fun <W : Window, B : WindowBuilder<W>> WindowType<W, B>.create(builderConsumer: B.() -> Unit): W { fun <W : Window, B : WindowBuilder<W>> WindowType<W, B>.create(builderConsumer: B.() -> Unit): W {
val builder = builder() val builder = builder()

@ -2,7 +2,7 @@ package xyz.xenondevs.invui.gui;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.builder.GuiBuilder; import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.impl.PagedItemsGuiImpl; import xyz.xenondevs.invui.gui.impl.PagedItemsGuiImpl;
import xyz.xenondevs.invui.gui.impl.PagedNestedGuiImpl; import xyz.xenondevs.invui.gui.impl.PagedNestedGuiImpl;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
@ -14,7 +14,7 @@ import java.util.function.BiConsumer;
/** /**
* A {@link Gui} with pages. * A {@link Gui} with pages.
* *
* @see GuiBuilder * @see GuiType
* @see PagedItemsGuiImpl * @see PagedItemsGuiImpl
* @see PagedNestedGuiImpl * @see PagedNestedGuiImpl
*/ */
@ -108,7 +108,7 @@ public abstract class AbstractPagedGui<C> extends AbstractGui implements PagedGu
} }
@Override @Override
public void registerPageChangeHandler(@NotNull BiConsumer<Integer, Integer> pageChangeHandler) { public void addPageChangeHandler(@NotNull BiConsumer<Integer, Integer> pageChangeHandler) {
if (pageChangeHandlers == null) { if (pageChangeHandlers == null) {
pageChangeHandlers = new ArrayList<>(); pageChangeHandlers = new ArrayList<>();
} }
@ -117,7 +117,7 @@ public abstract class AbstractPagedGui<C> extends AbstractGui implements PagedGu
} }
@Override @Override
public void unregisterPageChangeHandler(@NotNull BiConsumer<Integer, Integer> pageChangeHandler) { public void removePageChangeHandler(@NotNull BiConsumer<Integer, Integer> pageChangeHandler) {
if (pageChangeHandlers != null) { if (pageChangeHandlers != null) {
pageChangeHandlers.remove(pageChangeHandler); pageChangeHandlers.remove(pageChangeHandler);
} }

@ -1,11 +1,14 @@
package xyz.xenondevs.invui.gui; package xyz.xenondevs.invui.gui;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl; import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl;
import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl; import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.util.SlotUtils; import xyz.xenondevs.invui.util.SlotUtils;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer;
/** /**
* A scrollable {@link Gui} * A scrollable {@link Gui}
@ -19,8 +22,9 @@ public abstract class AbstractScrollGui<C> extends AbstractGui implements Scroll
private final int lineLength; private final int lineLength;
private final int lineAmount; private final int lineAmount;
private final int[] contentListSlots; private final int[] contentListSlots;
private int offset;
protected int offset; private List<BiConsumer<Integer, Integer>> scrollHandlers;
public AbstractScrollGui(int width, int height, boolean infiniteLines, int... contentListSlots) { public AbstractScrollGui(int width, int height, boolean infiniteLines, int... contentListSlots) {
super(width, height); super(width, height);
@ -109,6 +113,25 @@ public abstract class AbstractScrollGui<C> extends AbstractGui implements Scroll
} }
} }
@Override
public void setScrollHandlers(@NotNull List<@NotNull BiConsumer<Integer, Integer>> scrollHandlers) {
this.scrollHandlers = scrollHandlers;
}
@Override
public void addScrollHandler(@NotNull BiConsumer<Integer, Integer> scrollHandler) {
if (scrollHandlers == null)
scrollHandlers = new ArrayList<>();
scrollHandlers.add(scrollHandler);
}
@Override
public void removeScrollHandler(@NotNull BiConsumer<Integer, Integer> scrollHandler) {
if (scrollHandlers != null)
scrollHandlers.remove(scrollHandler);
}
protected abstract List<? extends SlotElement> getElements(int from, int to); protected abstract List<? extends SlotElement> getElements(int from, int to);
} }

@ -82,13 +82,13 @@ public abstract class AbstractTabGui extends AbstractGui implements TabGui {
this.tabChangeHandlers = tabChangeHandlers; this.tabChangeHandlers = tabChangeHandlers;
} }
public void registerTabChangeHandler(@NotNull BiConsumer<Integer, Integer> tabChangeHandler) { public void addTabChangeHandler(@NotNull BiConsumer<Integer, Integer> tabChangeHandler) {
if (tabChangeHandlers == null) tabChangeHandlers = new ArrayList<>(); if (tabChangeHandlers == null) tabChangeHandlers = new ArrayList<>();
tabChangeHandlers.add(tabChangeHandler); tabChangeHandlers.add(tabChangeHandler);
} }
@Override @Override
public void unregisterTabChangeHandler(@NotNull BiConsumer<Integer, Integer> tabChangeHandler) { public void removeTabChangeHandler(@NotNull BiConsumer<Integer, Integer> tabChangeHandler) {
if (tabChangeHandlers != null) tabChangeHandlers.remove(tabChangeHandler); if (tabChangeHandlers != null) tabChangeHandlers.remove(tabChangeHandler);
} }

@ -5,7 +5,7 @@ import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.animation.Animation; import xyz.xenondevs.invui.animation.Animation;
import xyz.xenondevs.invui.gui.builder.GuiBuilder; import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.impl.NormalGuiImpl; import xyz.xenondevs.invui.gui.impl.NormalGuiImpl;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.Item;
@ -28,7 +28,7 @@ import java.util.function.Predicate;
* In order to create an {@link Inventory} which is visible * In order to create an {@link Inventory} which is visible
* to players, you will need to use a {@link Window}. * to players, you will need to use a {@link Window}.
* *
* @see GuiBuilder * @see GuiType
* @see AbstractGui * @see AbstractGui
* @see AbstractPagedGui * @see AbstractPagedGui
* @see AbstractScrollGui * @see AbstractScrollGui

@ -125,7 +125,7 @@ public interface PagedGui<C> extends Gui {
* *
* @param content The content to set. * @param content The content to set.
*/ */
void setContent(List<@Nullable C> content); void setContent(@Nullable List<@NotNull C> content);
/** /**
* Gets the registered page change handlers. * Gets the registered page change handlers.
@ -146,13 +146,13 @@ public interface PagedGui<C> extends Gui {
* *
* @param handler The handler to register. * @param handler The handler to register.
*/ */
void registerPageChangeHandler(@NotNull BiConsumer<Integer, Integer> handler); void addPageChangeHandler(@NotNull BiConsumer<Integer, Integer> handler);
/** /**
* Unregisters a page change handler. * Unregisters a page change handler.
* *
* @param handler The handler to unregister. * @param handler The handler to unregister.
*/ */
void unregisterPageChangeHandler(@NotNull BiConsumer<Integer, Integer> handler); void removePageChangeHandler(@NotNull BiConsumer<Integer, Integer> handler);
} }

@ -1,14 +1,16 @@
package xyz.xenondevs.invui.gui; package xyz.xenondevs.invui.gui;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl; import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl;
import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl; import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl;
import xyz.xenondevs.invui.gui.impl.ScrollVIGuiImpl; import xyz.xenondevs.invui.gui.impl.ScrollInventoryGuiImpl;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.Item;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory; import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public interface ScrollGui<C> extends Gui { public interface ScrollGui<C> extends Gui {
@ -71,7 +73,7 @@ public interface ScrollGui<C> extends Gui {
* @return The created {@link ScrollGui}. * @return The created {@link ScrollGui}.
*/ */
static @NotNull ScrollGui<VirtualInventory> ofInventories(int width, int height, @NotNull List<@NotNull VirtualInventory> inventories, int... contentListSlots) { static @NotNull ScrollGui<VirtualInventory> ofInventories(int width, int height, @NotNull List<@NotNull VirtualInventory> inventories, int... contentListSlots) {
return new ScrollVIGuiImpl(width, height, inventories, contentListSlots); return new ScrollInventoryGuiImpl(width, height, inventories, contentListSlots);
} }
/** /**
@ -82,7 +84,7 @@ public interface ScrollGui<C> extends Gui {
* @return The created {@link ScrollGui}. * @return The created {@link ScrollGui}.
*/ */
static @NotNull ScrollGui<VirtualInventory> ofInventories(@NotNull Structure structure, @NotNull List<@NotNull VirtualInventory> inventories) { static @NotNull ScrollGui<VirtualInventory> ofInventories(@NotNull Structure structure, @NotNull List<@NotNull VirtualInventory> inventories) {
return new ScrollVIGuiImpl(inventories, structure); return new ScrollInventoryGuiImpl(inventories, structure);
} }
/** /**
@ -125,6 +127,27 @@ public interface ScrollGui<C> extends Gui {
* *
* @param content The content to set. * @param content The content to set.
*/ */
void setContent(@NotNull List<@NotNull C> content); void setContent(@Nullable List<@NotNull C> content);
/**
* Replaces the currently registered scroll handlers with the specified ones.
*
* @param scrollHandlers The new scroll handlers.
*/
void setScrollHandlers(@NotNull List<@NotNull BiConsumer<Integer, Integer>> scrollHandlers);
/**
* Adds a scroll handler to this {@link ScrollGui}.
*
* @param scrollHandler The scroll handler to add.
*/
void addScrollHandler(@NotNull BiConsumer<Integer, Integer> scrollHandler);
/**
* Removes the specified scroll handler from this {@link ScrollGui}.
*
* @param scrollHandler The scroll handler to remove.
*/
void removeScrollHandler(@NotNull BiConsumer<Integer, Integer> scrollHandler);
} }

@ -83,13 +83,13 @@ public interface TabGui extends Gui {
* *
* @param handler The handler to register. * @param handler The handler to register.
*/ */
void registerTabChangeHandler(@NotNull BiConsumer<Integer, Integer> handler); void addTabChangeHandler(@NotNull BiConsumer<Integer, Integer> handler);
/** /**
* Unregisters a page change handler. * Unregisters a page change handler.
* *
* @param handler The handler to unregister. * @param handler The handler to unregister.
*/ */
void unregisterTabChangeHandler(@NotNull BiConsumer<Integer, Integer> handler); void removeTabChangeHandler(@NotNull BiConsumer<Integer, Integer> handler);
} }

@ -0,0 +1,159 @@
package xyz.xenondevs.invui.gui.builder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.structure.Marker;
import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.item.Item;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.ItemWrapper;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* A builder class to easily construct {@link Gui Guis}.<br>
* It provides similar functionality to Bukkit's {@link ShapedRecipe}, as it
* allows for a structure String which defines the layout of the {@link Gui}.
*/
public abstract class AbstractGuiBuilder<G extends Gui, S extends AbstractGuiBuilder<G, S>> implements GuiBuilder<G> {
protected Structure structure;
protected ItemProvider background;
protected List<Consumer<Gui>> modifiers;
@Contract("_, _, _, -> this")
public S setStructure(int width, int height, @NotNull String structureData) {
structure = new Structure(width, height, structureData);
return getThis();
}
@Contract("_ -> this")
public S setStructure(@NotNull String... structureData) {
structure = new Structure(structureData);
return getThis();
}
@Contract("_ -> this")
public S setStructure(@NotNull Structure structure) {
this.structure = structure;
return getThis();
}
@Contract("_, _ -> this")
public S addIngredient(char key, @NotNull ItemStack itemStack) {
structure.addIngredient(key, itemStack);
return getThis();
}
@Contract("_, _ -> this")
public S addIngredient(char key, @NotNull ItemProvider itemProvider) {
structure.addIngredient(key, itemProvider);
return getThis();
}
@Contract("_, _ -> this")
public S addIngredient(char key, @NotNull Item item) {
structure.addIngredient(key, item);
return getThis();
}
@Contract("_, _ -> this")
public S addIngredient(char key, @NotNull VirtualInventory inventory) {
structure.addIngredient(key, inventory);
return getThis();
}
@Contract("_, _, _ -> this")
public S addIngredient(char key, @NotNull VirtualInventory inventory, @Nullable ItemProvider background) {
structure.addIngredient(key, inventory, background);
return getThis();
}
@Contract("_, _ -> this")
public S addIngredient(char key, @NotNull SlotElement element) {
structure.addIngredient(key, element);
return getThis();
}
@Contract("_, _ -> this")
public S addIngredient(char key, @NotNull Marker marker) {
structure.addIngredient(key, marker);
return getThis();
}
@Contract("_, _ -> this")
public S addIngredient(char key, @NotNull Supplier<? extends Item> itemSupplier) {
structure.addIngredient(key, itemSupplier);
return getThis();
}
@Contract("_, _ -> this")
public S addIngredientElementSupplier(char key, @NotNull Supplier<? extends SlotElement> elementSupplier) {
structure.addIngredientElementSupplier(key, elementSupplier);
return getThis();
}
@Contract("_ -> this")
public S setBackground(@NotNull ItemProvider itemProvider) {
background = itemProvider;
return getThis();
}
@Contract("_ -> this")
public S setBackground(@NotNull ItemStack itemStack) {
background = new ItemWrapper(itemStack);
return getThis();
}
@Contract("_ -> this")
public S addModifier(@NotNull Consumer<@NotNull Gui> modifier) {
if (modifiers == null)
modifiers = new ArrayList<>();
modifiers.add(modifier);
return getThis();
}
@Contract("_ -> this")
public S setModifiers(@NotNull List<@NotNull Consumer<@NotNull Gui>> modifiers) {
this.modifiers = modifiers;
return getThis();
}
protected void applyModifiers(@NotNull G gui) {
if (background != null) {
gui.setBackground(background);
}
if (modifiers != null) {
modifiers.forEach(modifier -> modifier.accept(gui));
}
}
@SuppressWarnings("unchecked")
@Override
public @NotNull AbstractGuiBuilder<G, S> clone() {
try {
var clone = (AbstractGuiBuilder<G, S>) super.clone();
clone.structure = structure.clone();
if (modifiers != null)
clone.modifiers = new ArrayList<>(modifiers);
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
@Contract(value = "-> this", pure = true)
protected abstract S getThis();
}

@ -0,0 +1,60 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.PagedGui;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
public abstract class AbstractPagedGuiBuilder<C, S extends AbstractPagedGuiBuilder<C, S>> extends AbstractGuiBuilder<PagedGui<C>, S> {
protected List<C> content;
protected List<BiConsumer<Integer, Integer>> pageChangeHandlers;
@Contract("_ -> this")
public S setContent(@NotNull List<@NotNull C> content) {
this.content = content;
return getThis();
}
@Contract("_ -> this")
public S addContent(@NotNull C content) {
if (this.content == null)
this.content = new ArrayList<>();
this.content.add(content);
return getThis();
}
@Contract("_ -> this")
public S setPageChangeHandlers(@NotNull List<@NotNull BiConsumer<Integer, Integer>> handlers) {
pageChangeHandlers = handlers;
return getThis();
}
@Contract("_ -> this")
public S addPageChangeHandler(@NotNull BiConsumer<Integer, Integer> handler) {
if (pageChangeHandlers == null)
pageChangeHandlers = new ArrayList<>(1);
pageChangeHandlers.add(handler);
return getThis();
}
@Override
protected void applyModifiers(@NotNull PagedGui<C> gui) {
super.applyModifiers(gui);
gui.setPageChangeHandlers(pageChangeHandlers);
}
@Override
public @NotNull AbstractPagedGuiBuilder<C, S> clone() {
var clone = (AbstractPagedGuiBuilder<C, S>) super.clone();
clone.content = new ArrayList<>(content);
clone.pageChangeHandlers = new ArrayList<>(pageChangeHandlers);
return clone;
}
}

@ -0,0 +1,60 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.ScrollGui;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
public abstract class AbstractScrollGuiBuilder<C, S extends AbstractScrollGuiBuilder<C, S>> extends AbstractGuiBuilder<ScrollGui<C>, S>{
protected List<C> content;
protected List<BiConsumer<Integer, Integer>> scrollHandlers;
@Contract("_ -> this")
public S setContent(@NotNull List<@NotNull C> content) {
this.content = content;
return getThis();
}
@Contract("_ -> this")
public S addContent(@NotNull C content) {
if (this.content == null)
this.content = new ArrayList<>();
this.content.add(content);
return getThis();
}
@Contract("_ -> this")
public S setScrollHandlers(@NotNull List<@NotNull BiConsumer<Integer, Integer>> handlers) {
scrollHandlers = handlers;
return getThis();
}
@Contract("_ -> this")
public S addScrollHandler(@NotNull BiConsumer<Integer, Integer> handler) {
if (scrollHandlers == null)
scrollHandlers = new ArrayList<>(1);
scrollHandlers.add(handler);
return getThis();
}
@Override
protected void applyModifiers(@NotNull ScrollGui<C> gui) {
super.applyModifiers(gui);
gui.setScrollHandlers(scrollHandlers);
}
@Override
public @NotNull AbstractScrollGuiBuilder<C, S> clone() {
var clone = (AbstractScrollGuiBuilder<C, S>) super.clone();
clone.content = new ArrayList<>(content);
clone.scrollHandlers = new ArrayList<>(scrollHandlers);
return clone;
}
}

@ -1,126 +1,15 @@
package xyz.xenondevs.invui.gui.builder; package xyz.xenondevs.invui.gui.builder;
import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Contract;
import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.builder.guitype.GuiType;
import xyz.xenondevs.invui.gui.structure.Marker;
import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.item.Item;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.ItemWrapper;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
import java.util.ArrayList; public interface GuiBuilder<G extends Gui> extends Cloneable {
import java.util.List;
import java.util.function.Supplier;
@Contract("-> new")
@NotNull G build();
/** @Contract("-> new")
* A builder class to easily construct {@link Gui}s.<br> @NotNull GuiBuilder<G> clone();
* It provides similar functionality to Bukkit's {@link ShapedRecipe}, as it
* allows for a structure String which defines the layout of the {@link Gui}.
*/
public class GuiBuilder<G extends Gui, C> {
protected final GuiType<G, C> guiType;
protected final GuiContext<C> context;
public GuiBuilder(@NotNull GuiType<G, C> guiType) {
this.guiType = guiType;
this.context = new GuiContext<>();
}
public GuiBuilder<G, C> setStructure(int width, int height, @NotNull String structureData) {
context.setStructure(new Structure(width, height, structureData));
return this;
}
public GuiBuilder<G, C> setStructure(@NotNull String... structureData) {
return setStructure(new Structure(structureData));
}
public GuiBuilder<G, C> setStructure(@NotNull Structure structure) {
context.setStructure(structure);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull ItemStack itemStack) {
context.getStructure().addIngredient(key, itemStack);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull ItemProvider itemProvider) {
context.getStructure().addIngredient(key, itemProvider);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull Item item) {
context.getStructure().addIngredient(key, item);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull VirtualInventory inventory) {
context.getStructure().addIngredient(key, inventory);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull VirtualInventory inventory, @Nullable ItemProvider background) {
context.getStructure().addIngredient(key, inventory, background);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull SlotElement element) {
context.getStructure().addIngredient(key, element);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull Marker marker) {
context.getStructure().addIngredient(key, marker);
return this;
}
public GuiBuilder<G, C> addIngredient(char key, @NotNull Supplier<? extends Item> itemSupplier) {
context.getStructure().addIngredient(key, itemSupplier);
return this;
}
public GuiBuilder<G, C> addIngredientElementSupplier(char key, @NotNull Supplier<? extends SlotElement> elementSupplier) {
context.getStructure().addIngredientElementSupplier(key, elementSupplier);
return this;
}
public GuiBuilder<G, C> setBackground(@NotNull ItemProvider itemProvider) {
context.setBackground(itemProvider);
return this;
}
public GuiBuilder<G, C> setBackground(@NotNull ItemStack itemStack) {
context.setBackground(new ItemWrapper(itemStack));
return this;
}
public GuiBuilder<G, C> setContent(@NotNull List<C> content) {
context.setContent(content);
return this;
}
public GuiBuilder<G, C> addContent(@NotNull C content) {
if (context.getContent() == null)
context.setContent(new ArrayList<>());
context.getContent().add(content);
return this;
}
public @NotNull G build() {
if (context.getStructure() == null)
throw new IllegalStateException("GuiContext has not been set yet.");
return guiType.createGui(context);
}
} }

@ -1,45 +0,0 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.builder.guitype.GuiType;
import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.item.ItemProvider;
import java.util.List;
/**
* The {@link GuiContext} contains all information from the {@link GuiBuilder} to be passed to
* an instance of {@link GuiType} to create a new {@link Gui}.
*/
public class GuiContext<C> {
private Structure structure;
private ItemProvider background;
private List<C> content;
public Structure getStructure() {
return structure;
}
public void setStructure(@NotNull Structure structure) {
this.structure = structure;
}
public ItemProvider getBackground() {
return background;
}
public void setBackground(ItemProvider background) {
this.background = background;
}
public void setContent(@NotNull List<C> content) {
this.content = content;
}
public List<C> getContent() {
return content;
}
}

@ -0,0 +1,42 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.TabGui;
import xyz.xenondevs.invui.item.Item;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
import java.util.function.Consumer;
public interface GuiType<G extends Gui, B extends GuiBuilder<G>> {
GuiType<Gui, NormalGuiBuilder> NORMAL = NormalGuiBuilder::new;
GuiType<PagedGui<Item>, PagedItemsGuiBuilder> PAGED_ITEMS = PagedItemsGuiBuilder::new;
GuiType<PagedGui<Gui>, PagedNestedGuiBuilder> PAGED_GUIS = PagedNestedGuiBuilder::new;
GuiType<TabGui, TabGuiBuilder> TAB = TabGuiBuilder::new;
GuiType<ScrollGui<Item>, ScrollItemsGuiBuilder> SCROLL_ITEMS = ScrollItemsGuiBuilder::new;
GuiType<ScrollGui<Gui>, ScrollNestedGuiBuilder> SCROLL_GUIS = ScrollNestedGuiBuilder::new;
GuiType<ScrollGui<VirtualInventory>, ScrollInventoryGuiBuilder> SCROLL_INVENTORY = ScrollInventoryGuiBuilder::new;
/**
* Creates a new {@link GuiBuilder} for this {@link GuiType}.
*
* @return The created {@link GuiBuilder}.
*/
@NotNull B builder();
/**
* Creates a new {@link Gui} after modifying the {@link GuiBuilder} with the given {@link Consumer}.
*
* @param builderConsumer The {@link Consumer} which modifies the {@link GuiBuilder}.
* @return The new {@link Gui}.
*/
default @NotNull G createGui(@NotNull Consumer<B> builderConsumer) {
var builder = builder();
builderConsumer.accept(builder);
return builder.build();
}
}

@ -0,0 +1,33 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.impl.NormalGuiImpl;
public final class NormalGuiBuilder extends AbstractGuiBuilder<Gui, NormalGuiBuilder> {
NormalGuiBuilder() {
}
@SuppressWarnings("deprecation")
@Override
public @NotNull Gui build() {
if (structure == null)
throw new IllegalStateException("Structure is not defined.");
var gui = new NormalGuiImpl(structure);
applyModifiers(gui);
return gui;
}
@Override
protected NormalGuiBuilder getThis() {
return this;
}
@Override
public @NotNull NormalGuiBuilder clone() {
return (NormalGuiBuilder) super.clone();
}
}

@ -0,0 +1,34 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.impl.PagedItemsGuiImpl;
import xyz.xenondevs.invui.item.Item;
public final class PagedItemsGuiBuilder extends AbstractPagedGuiBuilder<Item, PagedItemsGuiBuilder> {
PagedItemsGuiBuilder() {
}
@SuppressWarnings("deprecation")
@Override
public @NotNull PagedGui<Item> build() {
if (structure == null)
throw new IllegalStateException("Structure is not defined.");
var gui = new PagedItemsGuiImpl(content, structure);
applyModifiers(gui);
return gui;
}
@Override
protected PagedItemsGuiBuilder getThis() {
return this;
}
@Override
public @NotNull PagedItemsGuiBuilder clone() {
return (PagedItemsGuiBuilder) super.clone();
}
}

@ -0,0 +1,34 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.impl.PagedNestedGuiImpl;
public final class PagedNestedGuiBuilder extends AbstractPagedGuiBuilder<Gui, PagedNestedGuiBuilder> {
PagedNestedGuiBuilder() {
}
@SuppressWarnings("deprecation")
@Override
public @NotNull PagedGui<Gui> build() {
if (structure == null)
throw new IllegalStateException("Structure is not defined.");
var gui = new PagedNestedGuiImpl(content, structure);
applyModifiers(gui);
return gui;
}
@Override
protected PagedNestedGuiBuilder getThis() {
return this;
}
@Override
public @NotNull PagedNestedGuiBuilder clone() {
return (PagedNestedGuiBuilder) super.clone();
}
}

@ -0,0 +1,34 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.impl.ScrollInventoryGuiImpl;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
public final class ScrollInventoryGuiBuilder extends AbstractScrollGuiBuilder<VirtualInventory, ScrollInventoryGuiBuilder> {
ScrollInventoryGuiBuilder() {
}
@SuppressWarnings("deprecation")
@Override
public @NotNull ScrollGui<VirtualInventory> build() {
if (structure == null)
throw new IllegalStateException("Structure is not defined.");
var gui = new ScrollInventoryGuiImpl(content, structure);
applyModifiers(gui);
return gui;
}
@Override
protected ScrollInventoryGuiBuilder getThis() {
return this;
}
@Override
public @NotNull ScrollInventoryGuiBuilder clone() {
return (ScrollInventoryGuiBuilder) super.clone();
}
}

@ -0,0 +1,34 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl;
import xyz.xenondevs.invui.item.Item;
public final class ScrollItemsGuiBuilder extends AbstractScrollGuiBuilder<Item, ScrollItemsGuiBuilder> {
ScrollItemsGuiBuilder() {
}
@SuppressWarnings("deprecation")
@Override
public @NotNull ScrollGui<Item> build() {
if (structure == null)
throw new IllegalStateException("Structure is not defined.");
var gui = new ScrollItemsGuiImpl(content, structure);
applyModifiers(gui);
return gui;
}
@Override
protected ScrollItemsGuiBuilder getThis() {
return this;
}
@Override
public @NotNull ScrollItemsGuiBuilder clone() {
return (ScrollItemsGuiBuilder) super.clone();
}
}

@ -0,0 +1,34 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl;
public final class ScrollNestedGuiBuilder extends AbstractScrollGuiBuilder<Gui, ScrollNestedGuiBuilder>{
ScrollNestedGuiBuilder() {
}
@SuppressWarnings("deprecation")
@Override
public @NotNull ScrollGui<Gui> build() {
if (structure == null)
throw new IllegalStateException("Structure is not defined.");
var gui = new ScrollNestedGuiImpl(content, structure);
applyModifiers(gui);
return gui;
}
@Override
protected ScrollNestedGuiBuilder getThis() {
return this;
}
@Override
public @NotNull ScrollNestedGuiBuilder clone() {
return (ScrollNestedGuiBuilder) super.clone();
}
}

@ -0,0 +1,83 @@
package xyz.xenondevs.invui.gui.builder;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.TabGui;
import xyz.xenondevs.invui.gui.impl.TabGuiImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
public final class TabGuiBuilder extends AbstractGuiBuilder<TabGui, TabGuiBuilder> {
private List<Gui> tabs;
private List<BiConsumer<Integer, Integer>> tabChangeHandlers;
TabGuiBuilder() {
}
@Contract("_ -> this")
public TabGuiBuilder setTabs(@NotNull List<@Nullable Gui> tabs) {
this.tabs = tabs;
return this;
}
@Contract("_ -> this")
public TabGuiBuilder addTab(@Nullable Gui tab) {
if (this.tabs == null)
this.tabs = new ArrayList<>();
this.tabs.add(tab);
return this;
}
@Contract("_ -> this")
public TabGuiBuilder addTabChangeHandler(@NotNull BiConsumer<Integer, Integer> handler) {
if (tabChangeHandlers == null)
tabChangeHandlers = new ArrayList<>(1);
tabChangeHandlers.add(handler);
return this;
}
@Contract("_ -> this")
public TabGuiBuilder setTabChangeHandlers(@NotNull List<@NotNull BiConsumer<Integer, Integer>> handlers) {
tabChangeHandlers = handlers;
return this;
}
@Override
protected void applyModifiers(@NotNull TabGui gui) {
super.applyModifiers(gui);
gui.setTabChangeHandlers(tabChangeHandlers);
}
@SuppressWarnings("deprecation")
@Override
public @NotNull TabGui build() {
if (structure == null)
throw new IllegalStateException("Structure is not defined.");
if (tabs == null)
throw new IllegalStateException("Tabs are not defined.");
var gui = new TabGuiImpl(tabs, structure);
applyModifiers(gui);
return gui;
}
@Override
protected TabGuiBuilder getThis() {
return this;
}
@Override
public @NotNull TabGuiBuilder clone() {
var clone = (TabGuiBuilder) super.clone();
clone.tabs = new ArrayList<>(tabs);
clone.tabChangeHandlers = new ArrayList<>(tabChangeHandlers);
return clone;
}
}

@ -1,40 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.TabGui;
import xyz.xenondevs.invui.gui.builder.GuiBuilder;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.item.Item;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
public interface GuiType<G extends Gui, C> {
GuiType<Gui, Void> NORMAL = new NormalGuiType();
GuiType<PagedGui<Item>, Item> PAGED_ITEMS = new PagedItemsGuiType();
GuiType<PagedGui<Gui>, Gui> PAGED_GUIS = new PagedGuisGuiType();
GuiType<TabGui, Gui> TAB = new TabGuiType();
GuiType<ScrollGui<Item>, Item> SCROLL_ITEMS = new ScrollItemsGuiType();
GuiType<ScrollGui<Gui>, Gui> SCROLL_GUIS = new ScrollGuisGuiType();
GuiType<ScrollGui<VirtualInventory>, VirtualInventory> SCROLL_INVENTORY = new ScrollVIGuiType();
/**
* Creates a {@link Gui} of type {@link G} with the given {@link GuiContext}.
*
* @param context The {@link GuiContext} to create the {@link Gui} from.
* @return The created {@link Gui}
*/
@NotNull G createGui(@NotNull GuiContext<C> context);
/**
* Creates a new {@link GuiBuilder} for this {@link GuiType}.
*
* @return The created {@link GuiBuilder}.
*/
default @NotNull GuiBuilder<G, C> builder() {
return new GuiBuilder<>(this);
}
}

@ -1,17 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.gui.impl.NormalGuiImpl;
class NormalGuiType implements GuiType<Gui, Void> {
@Override
public @NotNull NormalGuiImpl createGui(@NotNull GuiContext<Void> context) {
NormalGuiImpl gui = new NormalGuiImpl(context.getStructure());
gui.setBackground(context.getBackground());
return gui;
}
}

@ -1,18 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.gui.impl.PagedNestedGuiImpl;
class PagedGuisGuiType implements GuiType<PagedGui<Gui>, Gui> {
@Override
public @NotNull PagedNestedGuiImpl createGui(@NotNull GuiContext<Gui> context) {
PagedNestedGuiImpl gui = new PagedNestedGuiImpl(context.getContent(), context.getStructure());
gui.setBackground(context.getBackground());
return gui;
}
}

@ -1,18 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.gui.impl.PagedItemsGuiImpl;
import xyz.xenondevs.invui.item.Item;
class PagedItemsGuiType implements GuiType<PagedGui<Item>, Item> {
@Override
public @NotNull PagedItemsGuiImpl createGui(@NotNull GuiContext<Item> context) {
PagedItemsGuiImpl gui = new PagedItemsGuiImpl(context.getContent(), context.getStructure());
gui.setBackground(context.getBackground());
return gui;
}
}

@ -1,18 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl;
class ScrollGuisGuiType implements GuiType<ScrollGui<Gui>, Gui> {
@Override
public @NotNull ScrollNestedGuiImpl createGui(@NotNull GuiContext<Gui> context) {
ScrollNestedGuiImpl gui = new ScrollNestedGuiImpl(context.getContent(), context.getStructure());
gui.setBackground(gui.getBackground());
return gui;
}
}

@ -1,18 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl;
import xyz.xenondevs.invui.item.Item;
class ScrollItemsGuiType implements GuiType<ScrollGui<Item>, Item> {
@Override
public @NotNull ScrollItemsGuiImpl createGui(@NotNull GuiContext<Item> context) {
ScrollItemsGuiImpl gui = new ScrollItemsGuiImpl(context.getContent(), context.getStructure());
gui.setBackground(context.getBackground());
return gui;
}
}

@ -1,18 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.gui.impl.ScrollVIGuiImpl;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
class ScrollVIGuiType implements GuiType<ScrollGui<VirtualInventory>, VirtualInventory> {
@Override
public @NotNull ScrollVIGuiImpl createGui(@NotNull GuiContext<VirtualInventory> context) {
ScrollVIGuiImpl gui = new ScrollVIGuiImpl(context.getContent(), context.getStructure());
gui.setBackground(context.getBackground());
return gui;
}
}

@ -1,18 +0,0 @@
package xyz.xenondevs.invui.gui.builder.guitype;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.TabGui;
import xyz.xenondevs.invui.gui.builder.GuiContext;
import xyz.xenondevs.invui.gui.impl.TabGuiImpl;
class TabGuiType implements GuiType<TabGui, Gui> {
@Override
public @NotNull TabGuiImpl createGui(@NotNull GuiContext<Gui> context) {
TabGuiImpl gui = new TabGuiImpl(context.getContent(), context.getStructure());
gui.setBackground(context.getBackground());
return gui;
}
}

@ -5,7 +5,7 @@ import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.AbstractPagedGui; import xyz.xenondevs.invui.gui.AbstractPagedGui;
import xyz.xenondevs.invui.gui.PagedGui; import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.SlotElement; import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.builder.GuiBuilder; import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.Item;
@ -15,9 +15,9 @@ import java.util.function.BiConsumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* A {@link AbstractPagedGui} that is filled with {@link Item}s. * A {@link AbstractPagedGui} that is filled with {@link Item Items}.
* *
* @see GuiBuilder * @see GuiType
* @see PagedNestedGuiImpl * @see PagedNestedGuiImpl
*/ */
@SuppressWarnings("DeprecatedIsStillUsed") @SuppressWarnings("DeprecatedIsStillUsed")
@ -36,7 +36,7 @@ public final class PagedItemsGuiImpl extends AbstractPagedGui<Item> {
* @deprecated Use {@link PagedGui#ofItems(int, int, List, int...)} instead. * @deprecated Use {@link PagedGui#ofItems(int, int, List, int...)} instead.
*/ */
@Deprecated @Deprecated
public PagedItemsGuiImpl(int width, int height, @Nullable List<Item> items, int... contentListSlots) { public PagedItemsGuiImpl(int width, int height, @Nullable List<@NotNull Item> items, int... contentListSlots) {
super(width, height, false, contentListSlots); super(width, height, false, contentListSlots);
setContent(items); setContent(items);
} }
@ -49,7 +49,7 @@ public final class PagedItemsGuiImpl extends AbstractPagedGui<Item> {
* @deprecated Use {@link PagedGui#ofItems(Structure, List)} instead. * @deprecated Use {@link PagedGui#ofItems(Structure, List)} instead.
*/ */
@Deprecated @Deprecated
public PagedItemsGuiImpl(@Nullable List<Item> items, @NotNull Structure structure) { public PagedItemsGuiImpl(@Nullable List<@NotNull Item> items, @NotNull Structure structure) {
super(structure.getWidth(), structure.getHeight(), false, structure); super(structure.getWidth(), structure.getHeight(), false, structure);
setContent(items); setContent(items);
} }
@ -60,7 +60,7 @@ public final class PagedItemsGuiImpl extends AbstractPagedGui<Item> {
} }
@Override @Override
public void setContent(List<@Nullable Item> items) { public void setContent(@Nullable List<@NotNull Item> items) {
this.items = items != null ? items : new ArrayList<>(); this.items = items != null ? items : new ArrayList<>();
update(); update();
} }

@ -6,7 +6,7 @@ import xyz.xenondevs.invui.gui.AbstractPagedGui;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.PagedGui; import xyz.xenondevs.invui.gui.PagedGui;
import xyz.xenondevs.invui.gui.SlotElement; import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.builder.GuiBuilder; import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,7 +17,7 @@ import java.util.stream.IntStream;
/** /**
* A {@link AbstractPagedGui} where every page is its own {@link Gui}. * A {@link AbstractPagedGui} where every page is its own {@link Gui}.
* *
* @see GuiBuilder * @see GuiType
* @see PagedItemsGuiImpl * @see PagedItemsGuiImpl
*/ */
@SuppressWarnings("DeprecatedIsStillUsed") @SuppressWarnings("DeprecatedIsStillUsed")
@ -35,7 +35,7 @@ public final class PagedNestedGuiImpl extends AbstractPagedGui<Gui> {
* @deprecated Use {@link PagedGui#ofGuis(int, int, List, int...)} instead. * @deprecated Use {@link PagedGui#ofGuis(int, int, List, int...)} instead.
*/ */
@Deprecated @Deprecated
public PagedNestedGuiImpl(int width, int height, @Nullable List<Gui> guis, int... contentListSlots) { public PagedNestedGuiImpl(int width, int height, @Nullable List<@NotNull Gui> guis, int... contentListSlots) {
super(width, height, false, contentListSlots); super(width, height, false, contentListSlots);
setContent(guis); setContent(guis);
} }
@ -48,7 +48,7 @@ public final class PagedNestedGuiImpl extends AbstractPagedGui<Gui> {
* @deprecated Use {@link PagedGui#ofGuis(Structure, List)} instead. * @deprecated Use {@link PagedGui#ofGuis(Structure, List)} instead.
*/ */
@Deprecated @Deprecated
public PagedNestedGuiImpl(@Nullable List<Gui> guis, @NotNull Structure structure) { public PagedNestedGuiImpl(@Nullable List<@NotNull Gui> guis, @NotNull Structure structure) {
super(structure.getWidth(), structure.getHeight(), false, structure); super(structure.getWidth(), structure.getHeight(), false, structure);
setContent(guis); setContent(guis);
} }
@ -59,7 +59,7 @@ public final class PagedNestedGuiImpl extends AbstractPagedGui<Gui> {
} }
@Override @Override
public void setContent(@Nullable List<Gui> guis) { public void setContent(@Nullable List<@NotNull Gui> guis) {
this.guis = guis == null ? new ArrayList<>() : guis; this.guis = guis == null ? new ArrayList<>() : guis;
update(); update();
} }

@ -1,23 +1,32 @@
package xyz.xenondevs.invui.gui.impl; package xyz.xenondevs.invui.gui.impl;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.AbstractScrollGui; import xyz.xenondevs.invui.gui.AbstractScrollGui;
import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.SlotElement; import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.virtualinventory.VirtualInventory; import xyz.xenondevs.invui.virtualinventory.VirtualInventory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* A {@link AbstractScrollGui} that uses {@link VirtualInventory VirtualInventories} as content.
*
* @see GuiType
* @see ScrollItemsGuiImpl
* @see ScrollNestedGuiImpl
*/
@SuppressWarnings("DeprecatedIsStillUsed") @SuppressWarnings("DeprecatedIsStillUsed")
public final class ScrollVIGuiImpl extends AbstractScrollGui<VirtualInventory> { public final class ScrollInventoryGuiImpl extends AbstractScrollGui<VirtualInventory> {
private List<VirtualInventory> inventories; private List<VirtualInventory> inventories;
private List<SlotElement.VISlotElement> elements; private List<SlotElement.VISlotElement> elements;
/** /**
* Creates a new {@link ScrollVIGuiImpl}. * Creates a new {@link ScrollInventoryGuiImpl}.
* *
* @param width The width of this Gui. * @param width The width of this Gui.
* @param height The width of this Gui. * @param height The width of this Gui.
@ -26,26 +35,26 @@ public final class ScrollVIGuiImpl extends AbstractScrollGui<VirtualInventory> {
* @deprecated Use {@link ScrollGui#ofInventories(int, int, List, int...)} instead. * @deprecated Use {@link ScrollGui#ofInventories(int, int, List, int...)} instead.
*/ */
@Deprecated @Deprecated
public ScrollVIGuiImpl(int width, int height, @NotNull List<VirtualInventory> inventories, int... contentListSlots) { public ScrollInventoryGuiImpl(int width, int height, @Nullable List<@NotNull VirtualInventory> inventories, int... contentListSlots) {
super(width, height, false, contentListSlots); super(width, height, false, contentListSlots);
setContent(inventories); setContent(inventories);
} }
/** /**
* Creates a new {@link ScrollVIGuiImpl}. * Creates a new {@link ScrollInventoryGuiImpl}.
* *
* @param inventories The {@link VirtualInventory VirtualInventories} to use. * @param inventories The {@link VirtualInventory VirtualInventories} to use.
* @param structure The {@link Structure} to use. * @param structure The {@link Structure} to use.
* @deprecated Use {@link ScrollGui#ofInventories(Structure, List)} instead. * @deprecated Use {@link ScrollGui#ofInventories(Structure, List)} instead.
*/ */
@Deprecated @Deprecated
public ScrollVIGuiImpl(@NotNull List<VirtualInventory> inventories, @NotNull Structure structure) { public ScrollInventoryGuiImpl(@Nullable List<@NotNull VirtualInventory> inventories, @NotNull Structure structure) {
super(structure.getWidth(), structure.getHeight(), false, structure); super(structure.getWidth(), structure.getHeight(), false, structure);
setContent(inventories); setContent(inventories);
} }
@Override @Override
public void setContent(@NotNull List<VirtualInventory> inventories) { public void setContent(@Nullable List<@NotNull VirtualInventory> inventories) {
this.inventories = inventories != null ? inventories : new ArrayList<>(); this.inventories = inventories != null ? inventories : new ArrayList<>();
updateElements(); updateElements();
update(); update();

@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.AbstractScrollGui; import xyz.xenondevs.invui.gui.AbstractScrollGui;
import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.SlotElement; import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.Item;
@ -12,6 +13,13 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* A {@link AbstractScrollGui} that uses {@link Item Items} as content.
*
* @see GuiType
* @see ScrollInventoryGuiImpl
* @see ScrollNestedGuiImpl
*/
@SuppressWarnings("DeprecatedIsStillUsed") @SuppressWarnings("DeprecatedIsStillUsed")
public final class ScrollItemsGuiImpl extends AbstractScrollGui<Item> { public final class ScrollItemsGuiImpl extends AbstractScrollGui<Item> {
@ -27,7 +35,7 @@ public final class ScrollItemsGuiImpl extends AbstractScrollGui<Item> {
* @deprecated Use {@link ScrollGui#ofItems(int, int, List, int...)} instead. * @deprecated Use {@link ScrollGui#ofItems(int, int, List, int...)} instead.
*/ */
@Deprecated @Deprecated
public ScrollItemsGuiImpl(int width, int height, @Nullable List<Item> items, int... contentListSlots) { public ScrollItemsGuiImpl(int width, int height, @Nullable List<@NotNull Item> items, int... contentListSlots) {
super(width, height, false, contentListSlots); super(width, height, false, contentListSlots);
setContent(items); setContent(items);
} }
@ -40,13 +48,13 @@ public final class ScrollItemsGuiImpl extends AbstractScrollGui<Item> {
* @deprecated Use {@link ScrollGui#ofItems(Structure, List)} instead. * @deprecated Use {@link ScrollGui#ofItems(Structure, List)} instead.
*/ */
@Deprecated @Deprecated
public ScrollItemsGuiImpl(@Nullable List<Item> items, @NotNull Structure structure) { public ScrollItemsGuiImpl(@Nullable List<@NotNull Item> items, @NotNull Structure structure) {
super(structure.getWidth(), structure.getHeight(), false, structure); super(structure.getWidth(), structure.getHeight(), false, structure);
setContent(items); setContent(items);
} }
@Override @Override
public void setContent(@NotNull List<Item> items) { public void setContent(@Nullable List<@NotNull Item> items) {
this.items = items != null ? items : new ArrayList<>(); this.items = items != null ? items : new ArrayList<>();
update(); update();
} }

@ -6,11 +6,19 @@ import xyz.xenondevs.invui.gui.AbstractScrollGui;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.ScrollGui;
import xyz.xenondevs.invui.gui.SlotElement; import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* A {@link AbstractScrollGui} that uses {@link Gui Guis} as content.
*
* @see GuiType
* @see ScrollItemsGuiImpl
* @see ScrollInventoryGuiImpl
*/
@SuppressWarnings("DeprecatedIsStillUsed") @SuppressWarnings("DeprecatedIsStillUsed")
public final class ScrollNestedGuiImpl extends AbstractScrollGui<Gui> { public final class ScrollNestedGuiImpl extends AbstractScrollGui<Gui> {
@ -27,7 +35,7 @@ public final class ScrollNestedGuiImpl extends AbstractScrollGui<Gui> {
* @deprecated Use {@link ScrollGui#ofGuis(int, int, List, int...)} instead. * @deprecated Use {@link ScrollGui#ofGuis(int, int, List, int...)} instead.
*/ */
@Deprecated @Deprecated
public ScrollNestedGuiImpl(int width, int height, @Nullable List<Gui> guis, int... contentListSlots) { public ScrollNestedGuiImpl(int width, int height, @Nullable List<@NotNull Gui> guis, int... contentListSlots) {
super(width, height, false, contentListSlots); super(width, height, false, contentListSlots);
setContent(guis); setContent(guis);
} }
@ -40,13 +48,13 @@ public final class ScrollNestedGuiImpl extends AbstractScrollGui<Gui> {
* @deprecated Use {@link ScrollGui#ofGuis(Structure, List)} instead. * @deprecated Use {@link ScrollGui#ofGuis(Structure, List)} instead.
*/ */
@Deprecated @Deprecated
public ScrollNestedGuiImpl(@Nullable List<Gui> guis, @NotNull Structure structure) { public ScrollNestedGuiImpl(@Nullable List<@NotNull Gui> guis, @NotNull Structure structure) {
super(structure.getWidth(), structure.getHeight(), false, structure); super(structure.getWidth(), structure.getHeight(), false, structure);
setContent(guis); setContent(guis);
} }
@Override @Override
public void setContent(@NotNull List<Gui> guis) { public void setContent(@Nullable List<@NotNull Gui> guis) {
this.guis = guis != null ? guis : new ArrayList<>(); this.guis = guis != null ? guis : new ArrayList<>();
updateElements(); updateElements();
update(); update();

@ -6,7 +6,7 @@ import xyz.xenondevs.invui.gui.AbstractTabGui;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.SlotElement; import xyz.xenondevs.invui.gui.SlotElement;
import xyz.xenondevs.invui.gui.TabGui; import xyz.xenondevs.invui.gui.TabGui;
import xyz.xenondevs.invui.gui.builder.GuiBuilder; import xyz.xenondevs.invui.gui.builder.GuiType;
import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.gui.structure.Structure;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,7 +17,7 @@ import java.util.stream.Collectors;
/** /**
* A {@link Gui} that has multiple tabs with which users can switch between {@link Gui}s. * A {@link Gui} that has multiple tabs with which users can switch between {@link Gui}s.
* *
* @see GuiBuilder * @see GuiType
*/ */
@SuppressWarnings("DeprecatedIsStillUsed") @SuppressWarnings("DeprecatedIsStillUsed")
public final class TabGuiImpl extends AbstractTabGui { public final class TabGuiImpl extends AbstractTabGui {

@ -42,7 +42,7 @@ public abstract class AbstractWindow implements Window, GuiParent {
private final UUID viewerUUID; private final UUID viewerUUID;
private final boolean retain; private final boolean retain;
private final SlotElement[] elementsDisplayed; private final SlotElement[] elementsDisplayed;
private final ArrayList<Runnable> closeHandlers = new ArrayList<>(); private List<Runnable> closeHandlers;
private ComponentWrapper title; private ComponentWrapper title;
private boolean closeable; private boolean closeable;
private boolean removed; private boolean removed;
@ -180,7 +180,10 @@ public abstract class AbstractWindow implements Window, GuiParent {
} }
handleClosed(); handleClosed();
if (closeHandlers != null) {
closeHandlers.forEach(Runnable::run); closeHandlers.forEach(Runnable::run);
}
} else { } else {
if (player.equals(getViewer())) if (player.equals(getViewer()))
Bukkit.getScheduler().runTaskLater(InvUI.getInstance().getPlugin(), this::show, 0); Bukkit.getScheduler().runTaskLater(InvUI.getInstance().getPlugin(), this::show, 0);
@ -274,13 +277,22 @@ public abstract class AbstractWindow implements Window, GuiParent {
changeTitle(TextComponent.fromLegacyText(title)); changeTitle(TextComponent.fromLegacyText(title));
} }
@Override
public void setCloseHandlers(@NotNull List<@NotNull Runnable> closeHandlers) {
this.closeHandlers = closeHandlers;
}
@Override @Override
public void addCloseHandler(@NotNull Runnable closeHandler) { public void addCloseHandler(@NotNull Runnable closeHandler) {
if (closeHandlers == null)
closeHandlers = new ArrayList<>();
closeHandlers.add(closeHandler); closeHandlers.add(closeHandler);
} }
@Override @Override
public void removeCloseHandler(@NotNull Runnable closeHandler) { public void removeCloseHandler(@NotNull Runnable closeHandler) {
if (closeHandlers != null)
closeHandlers.remove(closeHandler); closeHandlers.remove(closeHandler);
} }

@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.invui.window.builder.WindowType; import xyz.xenondevs.invui.window.builder.WindowType;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -103,6 +104,13 @@ public interface Window {
*/ */
@NotNull UUID getViewerUUID(); @NotNull UUID getViewerUUID();
/**
* Replaces the currently registered close handlers with the given list.
*
* @param closeHandlers The new close handlers
*/
void setCloseHandlers(@NotNull List<@NotNull Runnable> closeHandlers);
/** /**
* Adds a close handler that will be called when this window gets closed. * Adds a close handler that will be called when this window gets closed.
* *

@ -1,5 +1,6 @@
package xyz.xenondevs.invui.window.builder; package xyz.xenondevs.invui.window.builder;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.builder.GuiBuilder; import xyz.xenondevs.invui.gui.builder.GuiBuilder;
@ -11,20 +12,22 @@ public abstract class AbstractSingleWindowBuilder<W extends Window, V, S extends
protected Supplier<Gui> guiSupplier; protected Supplier<Gui> guiSupplier;
@Contract("_ -> this")
public S setGui(@NotNull Supplier<Gui> guiSupplier) { public S setGui(@NotNull Supplier<Gui> guiSupplier) {
this.guiSupplier = guiSupplier; this.guiSupplier = guiSupplier;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setGui(@NotNull Gui gui) { public S setGui(@NotNull Gui gui) {
this.guiSupplier = () -> gui; this.guiSupplier = () -> gui;
return getThis(); return getThis();
} }
public S setGui(@NotNull GuiBuilder<?, ?> builder) { @Contract("_ -> this")
public S setGui(@NotNull GuiBuilder<?> builder) {
this.guiSupplier = builder::build; this.guiSupplier = builder::build;
return getThis(); return getThis();
} }
} }

@ -1,5 +1,6 @@
package xyz.xenondevs.invui.window.builder; package xyz.xenondevs.invui.window.builder;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.gui.builder.GuiBuilder; import xyz.xenondevs.invui.gui.builder.GuiBuilder;
@ -12,32 +13,38 @@ public abstract class AbstractSplitWindowBuilder<W extends Window, V, S extends
protected Supplier<Gui> upperGuiSupplier; protected Supplier<Gui> upperGuiSupplier;
protected Supplier<Gui> lowerGuiSupplier; protected Supplier<Gui> lowerGuiSupplier;
@Contract("_ -> this")
public S setUpperGui(@NotNull Supplier<Gui> guiSupplier) { public S setUpperGui(@NotNull Supplier<Gui> guiSupplier) {
this.upperGuiSupplier = guiSupplier; this.upperGuiSupplier = guiSupplier;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setUpperGui(@NotNull Gui gui) { public S setUpperGui(@NotNull Gui gui) {
this.upperGuiSupplier = () -> gui; this.upperGuiSupplier = () -> gui;
return getThis(); return getThis();
} }
public S setUpperGui(@NotNull GuiBuilder<?, ?> builder) { @Contract("_ -> this")
public S setUpperGui(@NotNull GuiBuilder<?> builder) {
this.upperGuiSupplier = builder::build; this.upperGuiSupplier = builder::build;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setLowerGui(@NotNull Supplier<Gui> guiSupplier) { public S setLowerGui(@NotNull Supplier<Gui> guiSupplier) {
this.lowerGuiSupplier = guiSupplier; this.lowerGuiSupplier = guiSupplier;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setLowerGui(@NotNull Gui gui) { public S setLowerGui(@NotNull Gui gui) {
this.lowerGuiSupplier = () -> gui; this.lowerGuiSupplier = () -> gui;
return getThis(); return getThis();
} }
public S setLowerGui(@NotNull GuiBuilder<?, ?> builder) { @Contract("_ -> this")
public S setLowerGui(@NotNull GuiBuilder<?> builder) {
this.lowerGuiSupplier = builder::build; this.lowerGuiSupplier = builder::build;
return getThis(); return getThis();
} }

@ -2,6 +2,7 @@ package xyz.xenondevs.invui.window.builder;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.component.BaseComponentWrapper; import xyz.xenondevs.inventoryaccess.component.BaseComponentWrapper;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
@ -9,6 +10,7 @@ import xyz.xenondevs.invui.window.Window;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
public abstract class AbstractWindowBuilder<W extends Window, V, S extends AbstractWindowBuilder<W, V, S>> implements WindowBuilder<W> { public abstract class AbstractWindowBuilder<W extends Window, V, S extends AbstractWindowBuilder<W, V, S>> implements WindowBuilder<W> {
@ -17,42 +19,51 @@ public abstract class AbstractWindowBuilder<W extends Window, V, S extends Abstr
protected boolean closeable = true; protected boolean closeable = true;
protected boolean retain = false; protected boolean retain = false;
protected List<Runnable> closeHandlers; protected List<Runnable> closeHandlers;
protected List<Consumer<Window>> modifiers;
@Contract("_ -> this")
public S setViewer(@NotNull V viewer) { public S setViewer(@NotNull V viewer) {
this.viewer = viewer; this.viewer = viewer;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setTitle(@NotNull ComponentWrapper title) { public S setTitle(@NotNull ComponentWrapper title) {
this.title = title; this.title = title;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setTitle(@NotNull BaseComponent @NotNull [] title) { public S setTitle(@NotNull BaseComponent @NotNull [] title) {
this.title = new BaseComponentWrapper(title); this.title = new BaseComponentWrapper(title);
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setTitle(@NotNull String title) { public S setTitle(@NotNull String title) {
this.title = new BaseComponentWrapper(TextComponent.fromLegacyText(title)); this.title = new BaseComponentWrapper(TextComponent.fromLegacyText(title));
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setCloseable(boolean closeable) { public S setCloseable(boolean closeable) {
this.closeable = closeable; this.closeable = closeable;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setRetain(boolean retain) { public S setRetain(boolean retain) {
this.retain = retain; this.retain = retain;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S setCloseHandlers(List<Runnable> closeHandlers) { public S setCloseHandlers(List<Runnable> closeHandlers) {
this.closeHandlers = closeHandlers; this.closeHandlers = closeHandlers;
return getThis(); return getThis();
} }
@Contract("_ -> this")
public S addCloseHandler(Runnable closeHandler) { public S addCloseHandler(Runnable closeHandler) {
if (closeHandlers == null) if (closeHandlers == null)
closeHandlers = new ArrayList<>(); closeHandlers = new ArrayList<>();
@ -61,12 +72,47 @@ public abstract class AbstractWindowBuilder<W extends Window, V, S extends Abstr
return getThis(); return getThis();
} }
protected void applyChanges(W window) { @Contract("_ -> this")
if (closeHandlers != null) { public S setModifiers(List<Consumer<Window>> modifiers) {
closeHandlers.forEach(window::addCloseHandler); this.modifiers = modifiers;
return getThis();
}
@Contract("_ -> this")
public S addModifier(Consumer<Window> modifier) {
if (modifiers == null)
modifiers = new ArrayList<>();
modifiers.add(modifier);
return getThis();
}
protected void applyModifiers(W window) {
if (closeHandlers != null)
window.setCloseHandlers(closeHandlers);
if (modifiers != null)
modifiers.forEach(modifier -> modifier.accept(window));
}
@SuppressWarnings("unchecked")
@Override
public @NotNull AbstractWindowBuilder<W, V, S> clone() {
try {
var clone = (AbstractWindowBuilder<W, V, S>) super.clone();
if (title != null)
clone.title = title.clone();
if (closeHandlers != null)
clone.closeHandlers = new ArrayList<>(closeHandlers);
if (modifiers != null)
clone.modifiers = new ArrayList<>(modifiers);
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
} }
} }
@Contract(value = "-> this", pure = true)
protected abstract S getThis(); protected abstract S getThis();
} }

@ -1,36 +1,55 @@
package xyz.xenondevs.invui.window.builder; package xyz.xenondevs.invui.window.builder;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.window.AnvilWindow; import xyz.xenondevs.invui.window.AnvilWindow;
import xyz.xenondevs.invui.window.impl.AnvilSingleWindowImpl; import xyz.xenondevs.invui.window.impl.AnvilSingleWindowImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
public final class AnvilSingleWindowBuilder extends AbstractSingleWindowBuilder<AnvilWindow, Player, AnvilSingleWindowBuilder> { public final class AnvilSingleWindowBuilder extends AbstractSingleWindowBuilder<AnvilWindow, Player, AnvilSingleWindowBuilder> {
private Consumer<String> renameHandler; private List<Consumer<String>> renameHandlers;
AnvilSingleWindowBuilder() { AnvilSingleWindowBuilder() {
} }
public void setRenameHandler(@NotNull Consumer<String> renameHandler) { @Contract("_ -> this")
this.renameHandler = renameHandler; public AnvilSingleWindowBuilder setRenameHandlers(@NotNull List<@NotNull Consumer<String>> renameHandlers) {
this.renameHandlers = renameHandlers;
return this;
}
@Contract("_ -> this")
public AnvilSingleWindowBuilder addRenameHandler(@NotNull Consumer<String> renameHandler) {
if (renameHandlers == null)
renameHandlers = new ArrayList<>();
renameHandlers.add(renameHandler);
return this;
} }
@Override @Override
public @NotNull AnvilWindow build() { public @NotNull AnvilWindow build() {
if (viewer == null)
throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null)
throw new IllegalStateException("Gui is not defined.");
var window = new AnvilSingleWindowImpl( var window = new AnvilSingleWindowImpl(
viewer, viewer,
title, title,
(AbstractGui) guiSupplier.get(), (AbstractGui) guiSupplier.get(),
renameHandler, renameHandlers,
closeable, closeable,
retain retain
); );
applyChanges(window); applyModifiers(window);
return window; return window;
} }
@ -40,4 +59,9 @@ public final class AnvilSingleWindowBuilder extends AbstractSingleWindowBuilder<
return null; return null;
} }
@Override
public @NotNull AnvilSingleWindowBuilder clone() {
return (AnvilSingleWindowBuilder) super.clone();
}
} }

@ -1,38 +1,58 @@
package xyz.xenondevs.invui.window.builder; package xyz.xenondevs.invui.window.builder;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.window.AnvilWindow; import xyz.xenondevs.invui.window.AnvilWindow;
import xyz.xenondevs.invui.window.impl.AnvilSplitWindowImpl; import xyz.xenondevs.invui.window.impl.AnvilSplitWindowImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
public final class AnvilSplitWindowBuilder extends AbstractSplitWindowBuilder<AnvilWindow, Player, AnvilSplitWindowBuilder> { public final class AnvilSplitWindowBuilder extends AbstractSplitWindowBuilder<AnvilWindow, Player, AnvilSplitWindowBuilder> {
private Consumer<String> renameHandler; private List<Consumer<String>> renameHandlers;
AnvilSplitWindowBuilder() { AnvilSplitWindowBuilder() {
} }
public AnvilSplitWindowBuilder setRenameHandler(@NotNull Consumer<String> renameHandler) { @Contract("_ -> this")
this.renameHandler = renameHandler; public AnvilSplitWindowBuilder setRenameHandlers(@NotNull List<@NotNull Consumer<String>> renameHandlers) {
this.renameHandlers = renameHandlers;
return this;
}
@Contract("_ -> this")
public AnvilSplitWindowBuilder addRenameHandler(@NotNull Consumer<String> renameHandler) {
if (renameHandlers == null)
renameHandlers = new ArrayList<>();
renameHandlers.add(renameHandler);
return this; return this;
} }
@Override @Override
public @NotNull AnvilWindow build() { public @NotNull AnvilWindow build() {
if (viewer == null)
throw new IllegalStateException("Viewer is not defined.");
if (upperGuiSupplier == null)
throw new IllegalStateException("Upper Gui is not defined.");
if (lowerGuiSupplier == null)
throw new IllegalStateException("Lower Gui is not defined.");
var window = new AnvilSplitWindowImpl( var window = new AnvilSplitWindowImpl(
viewer, viewer,
title, title,
(AbstractGui) upperGuiSupplier.get(), (AbstractGui) upperGuiSupplier.get(),
(AbstractGui) lowerGuiSupplier.get(), (AbstractGui) lowerGuiSupplier.get(),
renameHandler, renameHandlers,
closeable, closeable,
retain retain
); );
applyChanges(window); applyModifiers(window);
return window; return window;
} }
@ -42,4 +62,9 @@ public final class AnvilSplitWindowBuilder extends AbstractSplitWindowBuilder<An
return this; return this;
} }
@Override
public @NotNull AnvilSplitWindowBuilder clone() {
return (AnvilSplitWindowBuilder) super.clone();
}
} }

@ -13,6 +13,11 @@ public final class CartographySingleWindowBuilder extends AbstractSingleWindowBu
@Override @Override
public @NotNull CartographyWindow build() { public @NotNull CartographyWindow build() {
if (viewer == null)
throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null)
throw new IllegalStateException("Gui is not defined.");
var window = new CartographySingleWindowImpl( var window = new CartographySingleWindowImpl(
viewer, viewer,
title, title,
@ -21,7 +26,7 @@ public final class CartographySingleWindowBuilder extends AbstractSingleWindowBu
retain retain
); );
applyChanges(window); applyModifiers(window);
return window; return window;
} }
@ -31,4 +36,9 @@ public final class CartographySingleWindowBuilder extends AbstractSingleWindowBu
return this; return this;
} }
@Override
public @NotNull CartographySingleWindowBuilder clone() {
return (CartographySingleWindowBuilder) super.clone();
}
} }

@ -13,6 +13,11 @@ public final class CartographySplitWindowBuilder extends AbstractSplitWindowBuil
@Override @Override
public @NotNull CartographyWindow build() { public @NotNull CartographyWindow build() {
if (viewer == null)
throw new IllegalStateException("Viewer is not defined.");
if (upperGuiSupplier == null)
throw new IllegalStateException("Upper Gui is not defined.");
var window = new CartographySplitWindowImpl( var window = new CartographySplitWindowImpl(
viewer, viewer,
title, title,
@ -22,7 +27,7 @@ public final class CartographySplitWindowBuilder extends AbstractSplitWindowBuil
retain retain
); );
applyChanges(window); applyModifiers(window);
return window; return window;
} }
@ -32,4 +37,9 @@ public final class CartographySplitWindowBuilder extends AbstractSplitWindowBuil
return this; return this;
} }
@Override
public @NotNull CartographySplitWindowBuilder clone() {
return (CartographySplitWindowBuilder) super.clone();
}
} }

@ -13,6 +13,11 @@ public final class NormalMergedWindowBuilder extends AbstractSingleWindowBuilder
@Override @Override
public @NotNull Window build() { public @NotNull Window build() {
if (viewer == null)
throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null)
throw new IllegalStateException("Gui is not defined.");
var window = new NormalMergedWindowImpl( var window = new NormalMergedWindowImpl(
viewer, viewer,
title, title,
@ -21,7 +26,7 @@ public final class NormalMergedWindowBuilder extends AbstractSingleWindowBuilder
retain retain
); );
applyChanges(window); applyModifiers(window);
return window; return window;
} }
@ -31,4 +36,9 @@ public final class NormalMergedWindowBuilder extends AbstractSingleWindowBuilder
return this; return this;
} }
@Override
public @NotNull NormalMergedWindowBuilder clone() {
return (NormalMergedWindowBuilder) super.clone();
}
} }

@ -1,6 +1,7 @@
package xyz.xenondevs.invui.window.builder; package xyz.xenondevs.invui.window.builder;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.window.Window; import xyz.xenondevs.invui.window.Window;
@ -13,6 +14,7 @@ public final class NormalSingleWindowBuilder extends AbstractSingleWindowBuilder
NormalSingleWindowBuilder() { NormalSingleWindowBuilder() {
} }
@Contract("_ -> this")
public NormalSingleWindowBuilder setViewer(@NotNull OfflinePlayer player) { public NormalSingleWindowBuilder setViewer(@NotNull OfflinePlayer player) {
setViewer(player.getUniqueId()); setViewer(player.getUniqueId());
return this; return this;
@ -20,6 +22,11 @@ public final class NormalSingleWindowBuilder extends AbstractSingleWindowBuilder
@Override @Override
public @NotNull Window build() { public @NotNull Window build() {
if (viewer == null)
throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null)
throw new IllegalStateException("Gui is not defined.");
var window = new NormalSingleWindowImpl( var window = new NormalSingleWindowImpl(
viewer, viewer,
title, title,
@ -28,7 +35,7 @@ public final class NormalSingleWindowBuilder extends AbstractSingleWindowBuilder
retain retain
); );
applyChanges(window); applyModifiers(window);
return window; return window;
} }
@ -38,4 +45,9 @@ public final class NormalSingleWindowBuilder extends AbstractSingleWindowBuilder
return this; return this;
} }
@Override
public @NotNull NormalSingleWindowBuilder clone() {
return (NormalSingleWindowBuilder) super.clone();
}
} }

@ -13,6 +13,13 @@ public final class NormalSplitWindowBuilder extends AbstractSplitWindowBuilder<W
@Override @Override
public @NotNull Window build() { public @NotNull Window build() {
if (viewer == null)
throw new IllegalStateException("Viewer is not defined.");
if (upperGuiSupplier == null)
throw new IllegalStateException("Upper Gui is not defined.");
if (lowerGuiSupplier == null)
throw new IllegalStateException("Lower Gui is not defined.");
var window = new NormalSplitWindowImpl( var window = new NormalSplitWindowImpl(
viewer, viewer,
title, title,
@ -22,7 +29,7 @@ public final class NormalSplitWindowBuilder extends AbstractSplitWindowBuilder<W
retain retain
); );
applyChanges(window); applyModifiers(window);
return window; return window;
} }
@ -32,4 +39,9 @@ public final class NormalSplitWindowBuilder extends AbstractSplitWindowBuilder<W
return this; return this;
} }
@Override
public @NotNull NormalSplitWindowBuilder clone() {
return (NormalSplitWindowBuilder) super.clone();
}
} }

@ -1,10 +1,15 @@
package xyz.xenondevs.invui.window.builder; package xyz.xenondevs.invui.window.builder;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.window.Window; import xyz.xenondevs.invui.window.Window;
public interface WindowBuilder<W extends Window> { public interface WindowBuilder<W extends Window> extends Cloneable {
@Contract("-> new")
@NotNull W build(); @NotNull W build();
@Contract("-> new")
@NotNull WindowBuilder<W> clone();
} }

@ -2,6 +2,8 @@ package xyz.xenondevs.invui.window.impl;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.InventoryAccess; import xyz.xenondevs.inventoryaccess.InventoryAccess;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
@ -9,15 +11,23 @@ import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.window.AbstractSingleWindow; import xyz.xenondevs.invui.window.AbstractSingleWindow;
import xyz.xenondevs.invui.window.AnvilWindow; import xyz.xenondevs.invui.window.AnvilWindow;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
public final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilWindow { public final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilWindow {
private final AnvilInventory anvilInventory; private final AnvilInventory anvilInventory;
public AnvilSingleWindowImpl(Player player, ComponentWrapper title, AbstractGui gui, Consumer<String> renameHandler, boolean closable, boolean retain) { public AnvilSingleWindowImpl(
@NotNull Player player,
@Nullable ComponentWrapper title,
@NotNull AbstractGui gui,
@Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers,
boolean closable,
boolean retain
) {
super(player.getUniqueId(), title, gui, null, false, closable, retain); super(player.getUniqueId(), title, gui, null, false, closable, retain);
anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandler); anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandlers);
inventory = anvilInventory.getBukkitInventory(); inventory = anvilInventory.getBukkitInventory();
initItems(); initItems();

@ -2,6 +2,8 @@ package xyz.xenondevs.invui.window.impl;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.InventoryAccess; import xyz.xenondevs.inventoryaccess.InventoryAccess;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
@ -9,16 +11,25 @@ import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.window.AbstractSplitWindow; import xyz.xenondevs.invui.window.AbstractSplitWindow;
import xyz.xenondevs.invui.window.AnvilWindow; import xyz.xenondevs.invui.window.AnvilWindow;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
public final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWindow { public final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWindow {
private final AnvilInventory anvilInventory; private final AnvilInventory anvilInventory;
public AnvilSplitWindowImpl(Player player, ComponentWrapper title, AbstractGui upperGui, AbstractGui lowerGui, Consumer<String> renameHandler, boolean closeable, boolean retain) { public AnvilSplitWindowImpl(
@NotNull Player player,
@Nullable ComponentWrapper title,
@NotNull AbstractGui upperGui,
@NotNull AbstractGui lowerGui,
@Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers,
boolean closeable,
boolean retain
) {
super(player, title, upperGui, lowerGui, null, false, closeable, retain); super(player, title, upperGui, lowerGui, null, false, closeable, retain);
anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandler); anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandlers);
upperInventory = anvilInventory.getBukkitInventory(); upperInventory = anvilInventory.getBukkitInventory();
initUpperItems(); initUpperItems();

@ -5,6 +5,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta; import org.bukkit.inventory.meta.MapMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.InventoryAccess; import xyz.xenondevs.inventoryaccess.InventoryAccess;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.CartographyInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.CartographyInventory;
@ -18,13 +19,18 @@ import xyz.xenondevs.invui.window.CartographyWindow;
import java.util.List; import java.util.List;
@SuppressWarnings("deprecation")
public final class CartographySingleWindowImpl extends AbstractSingleWindow implements CartographyWindow { public final class CartographySingleWindowImpl extends AbstractSingleWindow implements CartographyWindow {
private final CartographyInventory cartographyInventory; private final CartographyInventory cartographyInventory;
private int mapId; private int mapId;
public CartographySingleWindowImpl(Player player, ComponentWrapper title, AbstractGui gui, boolean closeable, boolean retain) { public CartographySingleWindowImpl(
@NotNull Player player,
@Nullable ComponentWrapper title,
@NotNull AbstractGui gui,
boolean closeable,
boolean retain
) {
super(player.getUniqueId(), title, gui, null, false, closeable, retain); super(player.getUniqueId(), title, gui, null, false, closeable, retain);
if (gui.getWidth() != 2 || gui.getHeight() != 1) throw new IllegalArgumentException("Gui has to be 2x1"); if (gui.getWidth() != 2 || gui.getHeight() != 1) throw new IllegalArgumentException("Gui has to be 2x1");
@ -41,7 +47,7 @@ public final class CartographySingleWindowImpl extends AbstractSingleWindow impl
InventoryAccess.getPlayerUtils().sendMapUpdate(getViewer(), mapId, (byte) 0, false, patch, icons); InventoryAccess.getPlayerUtils().sendMapUpdate(getViewer(), mapId, (byte) 0, false, patch, icons);
} }
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "DuplicatedCode"})
@Override @Override
public void resetMap() { public void resetMap() {
mapId = -MathUtils.RANDOM.nextInt(Integer.MAX_VALUE); mapId = -MathUtils.RANDOM.nextInt(Integer.MAX_VALUE);

@ -4,6 +4,7 @@ import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta; import org.bukkit.inventory.meta.MapMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.InventoryAccess; import xyz.xenondevs.inventoryaccess.InventoryAccess;
import xyz.xenondevs.inventoryaccess.abstraction.inventory.CartographyInventory; import xyz.xenondevs.inventoryaccess.abstraction.inventory.CartographyInventory;
@ -24,7 +25,14 @@ public final class CartographySplitWindowImpl extends AbstractSplitWindow implem
private final CartographyInventory cartographyInventory; private final CartographyInventory cartographyInventory;
private int mapId; private int mapId;
public CartographySplitWindowImpl(Player player, ComponentWrapper title, AbstractGui upperGui, AbstractGui lowerGui, boolean closeable, boolean retain) { public CartographySplitWindowImpl(
@NotNull Player player,
@Nullable ComponentWrapper title,
@NotNull AbstractGui upperGui,
@NotNull AbstractGui lowerGui,
boolean closeable,
boolean retain
) {
super(player, title, createWrappingGui(upperGui), lowerGui, null, false, closeable, retain); super(player, title, createWrappingGui(upperGui), lowerGui, null, false, closeable, retain);
cartographyInventory = InventoryAccess.createCartographyInventory(player, title); cartographyInventory = InventoryAccess.createCartographyInventory(player, title);
@ -35,6 +43,7 @@ public final class CartographySplitWindowImpl extends AbstractSplitWindow implem
register(); register();
} }
@SuppressWarnings("deprecation")
private static AbstractGui createWrappingGui(Gui upperGui) { private static AbstractGui createWrappingGui(Gui upperGui) {
if (upperGui.getWidth() != 2 || upperGui.getHeight() != 1) if (upperGui.getWidth() != 2 || upperGui.getHeight() != 1)
throw new IllegalArgumentException("Gui has to be 2x1"); throw new IllegalArgumentException("Gui has to be 2x1");
@ -50,7 +59,7 @@ public final class CartographySplitWindowImpl extends AbstractSplitWindow implem
} }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "DuplicatedCode"})
public void resetMap() { public void resetMap() {
mapId = -MathUtils.RANDOM.nextInt(Integer.MAX_VALUE); mapId = -MathUtils.RANDOM.nextInt(Integer.MAX_VALUE);
ItemStack map = new ItemStack(Material.FILLED_MAP); ItemStack map = new ItemStack(Material.FILLED_MAP);

@ -3,6 +3,8 @@ package xyz.xenondevs.invui.window.impl;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
@ -10,7 +12,13 @@ import xyz.xenondevs.invui.window.AbstractMergedWindow;
public final class NormalMergedWindowImpl extends AbstractMergedWindow { public final class NormalMergedWindowImpl extends AbstractMergedWindow {
public NormalMergedWindowImpl(Player player, ComponentWrapper title, AbstractGui gui, boolean closeable, boolean retain) { public NormalMergedWindowImpl(
@NotNull Player player,
@Nullable ComponentWrapper title,
@NotNull AbstractGui gui,
boolean closeable,
boolean retain
) {
super(player, title, gui, createInventory(gui), closeable, retain); super(player, title, gui, createInventory(gui), closeable, retain);
register(); register();
} }

@ -1,5 +1,7 @@
package xyz.xenondevs.invui.window.impl; package xyz.xenondevs.invui.window.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.util.InventoryUtils; import xyz.xenondevs.invui.util.InventoryUtils;
@ -9,7 +11,13 @@ import java.util.UUID;
public final class NormalSingleWindowImpl extends AbstractSingleWindow { public final class NormalSingleWindowImpl extends AbstractSingleWindow {
public NormalSingleWindowImpl(UUID viewerUUID, ComponentWrapper title, AbstractGui gui, boolean closeable, boolean retain) { public NormalSingleWindowImpl(
@NotNull UUID viewerUUID,
@Nullable ComponentWrapper title,
@NotNull AbstractGui gui,
boolean closeable,
boolean retain
) {
super(viewerUUID, title, gui, InventoryUtils.createMatchingInventory(gui, ""), true, closeable, retain); super(viewerUUID, title, gui, InventoryUtils.createMatchingInventory(gui, ""), true, closeable, retain);
register(); register();
} }

@ -1,6 +1,8 @@
package xyz.xenondevs.invui.window.impl; package xyz.xenondevs.invui.window.impl;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.util.InventoryUtils; import xyz.xenondevs.invui.util.InventoryUtils;
@ -8,7 +10,14 @@ import xyz.xenondevs.invui.window.AbstractSplitWindow;
public final class NormalSplitWindowImpl extends AbstractSplitWindow { public final class NormalSplitWindowImpl extends AbstractSplitWindow {
public NormalSplitWindowImpl(Player player, ComponentWrapper title, AbstractGui upperGui, AbstractGui lowerGui, boolean closeable, boolean retain) { public NormalSplitWindowImpl(
@NotNull Player player,
@Nullable ComponentWrapper title,
@NotNull AbstractGui upperGui,
@NotNull AbstractGui lowerGui,
boolean closeable,
boolean retain
) {
super(player, title, upperGui, lowerGui, InventoryUtils.createMatchingInventory(upperGui, ""), true, closeable, retain); super(player, title, upperGui, lowerGui, InventoryUtils.createMatchingInventory(upperGui, ""), true, closeable, retain);
register(); register();
} }