Improved window building

- Removed the "retain" parameter from Windows - all Windows can now be closed and reopened
- Added open handlers to Windows
- Added quick build methods Window.Builder.build(Player) and Window.Builder.show(Player)
- Added some NotNull annotations
This commit is contained in:
NichtStudioCode 2023-03-03 17:36:07 +01:00
parent 62e1a2c591
commit 3d4e062901
17 changed files with 251 additions and 264 deletions

@ -14,4 +14,4 @@ import xyz.xenondevs.invui.window.Window
* @return This Window Builder * @return This Window Builder
*/ */
@Contract("_ -> this") @Contract("_ -> this")
fun <B : Window.Builder<*, *, B>> B.setTitle(title: Component): B = setTitle(AdventureComponentWrapper(title)) fun <B : Window.Builder<*, B>> B.setTitle(title: Component): B = setTitle(AdventureComponentWrapper(title))

@ -24,34 +24,33 @@ public abstract class AbstractDoubleWindow extends AbstractWindow {
private final Inventory playerInventory; private final Inventory playerInventory;
private final ItemStack[] playerItems = new ItemStack[36]; private final ItemStack[] playerItems = new ItemStack[36];
protected Inventory upperInventory; protected Inventory upperInventory;
private boolean isCurrentlyOpened;
public AbstractDoubleWindow(Player player, ComponentWrapper title, int size, Inventory upperInventory, boolean closeable, boolean retain) { public AbstractDoubleWindow(Player player, ComponentWrapper title, int size, Inventory upperInventory, boolean closeable) {
super(player.getUniqueId(), title, size, closeable, retain); super(player.getUniqueId(), title, size, closeable);
this.upperInventory = upperInventory; this.upperInventory = upperInventory;
this.playerInventory = player.getInventory(); this.playerInventory = player.getInventory();
} }
protected void initUpperItems() { @Override
protected void initItems() {
// init upper inventory
for (int i = 0; i < upperInventory.getSize(); i++) { for (int i = 0; i < upperInventory.getSize(); i++) {
SlotElement element = getSlotElement(i); SlotElement element = getSlotElement(i);
redrawItem(i, element, true); redrawItem(i, element, true);
} }
}
// store and clear player inventory
private void initPlayerItems() {
for (int i = upperInventory.getSize(); i < upperInventory.getSize() + 36; i++) {
SlotElement element = getSlotElement(i);
redrawItem(i, element, true);
}
}
private void clearPlayerInventory() {
Inventory inventory = getViewer().getInventory(); Inventory inventory = getViewer().getInventory();
for (int i = 0; i < 36; i++) { for (int i = 0; i < 36; i++) {
playerItems[i] = inventory.getItem(i); playerItems[i] = inventory.getItem(i);
inventory.setItem(i, null); inventory.setItem(i, null);
} }
// init player inventory
for (int i = upperInventory.getSize(); i < upperInventory.getSize() + 36; i++) {
SlotElement element = getSlotElement(i);
redrawItem(i, element, true);
}
} }
private void restorePlayerInventory() { private void restorePlayerInventory() {
@ -71,7 +70,7 @@ public abstract class AbstractDoubleWindow extends AbstractWindow {
@Override @Override
protected void setInvItem(int slot, ItemStack itemStack) { protected void setInvItem(int slot, ItemStack itemStack) {
if (slot >= upperInventory.getSize()) { if (slot >= upperInventory.getSize()) {
if (isCurrentlyOpened) { if (isOpen()) {
int invSlot = SlotUtils.translateGuiToPlayerInv(slot - upperInventory.getSize()); int invSlot = SlotUtils.translateGuiToPlayerInv(slot - upperInventory.getSize());
setPlayerInvItem(invSlot, itemStack); setPlayerInvItem(invSlot, itemStack);
} }
@ -88,7 +87,7 @@ public abstract class AbstractDoubleWindow extends AbstractWindow {
@Override @Override
public void handleViewerDeath(PlayerDeathEvent event) { public void handleViewerDeath(PlayerDeathEvent event) {
if (isCurrentlyOpened) { if (isOpen()) {
List<ItemStack> drops = event.getDrops(); List<ItemStack> drops = event.getDrops();
if (!event.getKeepInventory()) { if (!event.getKeepInventory()) {
drops.clear(); drops.clear();
@ -103,15 +102,10 @@ public abstract class AbstractDoubleWindow extends AbstractWindow {
protected void handleOpened() { protected void handleOpened() {
// Prevent players from receiving advancements from UI items // Prevent players from receiving advancements from UI items
InventoryAccess.getPlayerUtils().stopAdvancementListening(getViewer()); InventoryAccess.getPlayerUtils().stopAdvancementListening(getViewer());
isCurrentlyOpened = true;
clearPlayerInventory();
initPlayerItems();
} }
@Override @Override
protected void handleClosed() { protected void handleClosed() {
isCurrentlyOpened = false;
restorePlayerInventory(); restorePlayerInventory();
// Start the advancement listeners again // Start the advancement listeners again
@ -136,7 +130,7 @@ public abstract class AbstractDoubleWindow extends AbstractWindow {
@Override @Override
public Inventory[] getInventories() { public Inventory[] getInventories() {
return isCurrentlyOpened ? new Inventory[] {upperInventory, playerInventory} : new Inventory[] {upperInventory}; return isOpen() ? new Inventory[] {upperInventory, playerInventory} : new Inventory[] {upperInventory};
} }
public Inventory getUpperInventory() { public Inventory getUpperInventory() {
@ -147,8 +141,6 @@ public abstract class AbstractDoubleWindow extends AbstractWindow {
return playerInventory; return playerInventory;
} }
protected abstract SlotElement getSlotElement(int index);
protected abstract Pair<AbstractGui, Integer> getWhereClicked(InventoryClickEvent event); protected abstract Pair<AbstractGui, Integer> getWhereClicked(InventoryClickEvent event);
} }

@ -17,12 +17,11 @@ public abstract class AbstractMergedWindow extends AbstractDoubleWindow {
private final AbstractGui gui; private final AbstractGui gui;
public AbstractMergedWindow(Player player, ComponentWrapper title, AbstractGui gui, Inventory upperInventory, boolean closeable, boolean retain) { public AbstractMergedWindow(Player player, ComponentWrapper title, AbstractGui gui, Inventory upperInventory, boolean closeable) {
super(player, title, gui.getSize(), upperInventory, closeable, retain); super(player, title, gui.getSize(), upperInventory, closeable);
this.gui = gui; this.gui = gui;
gui.addParent(this); gui.addParent(this);
initUpperItems();
} }
@Override @Override

@ -25,16 +25,16 @@ public abstract class AbstractSingleWindow extends AbstractWindow {
private final int size; private final int size;
protected Inventory inventory; protected Inventory inventory;
public AbstractSingleWindow(UUID viewerUUID, ComponentWrapper title, AbstractGui gui, Inventory inventory, boolean initItems, boolean closeable, boolean retain) { public AbstractSingleWindow(UUID viewerUUID, ComponentWrapper title, AbstractGui gui, Inventory inventory, boolean closeable) {
super(viewerUUID, title, gui.getSize(), closeable, retain); super(viewerUUID, title, gui.getSize(), closeable);
this.gui = gui; this.gui = gui;
this.size = gui.getSize(); this.size = gui.getSize();
this.inventory = inventory; this.inventory = inventory;
gui.addParent(this); gui.addParent(this);
if (initItems) initItems();
} }
@Override
protected void initItems() { protected void initItems() {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
SlotElement element = gui.getSlotElement(i); SlotElement element = gui.getSlotElement(i);
@ -109,27 +109,27 @@ public abstract class AbstractSingleWindow extends AbstractWindow {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public abstract static class AbstractBuilder<W extends Window, V, S extends Builder.Single<W, V, S>> public abstract static class AbstractBuilder<W extends Window, S extends Builder.Single<W, S>>
extends AbstractWindow.AbstractBuilder<W, V, S> extends AbstractWindow.AbstractBuilder<W, S>
implements Builder.Single<W, V, S> implements Builder.Single<W, S>
{ {
protected Supplier<Gui> guiSupplier; protected Supplier<Gui> guiSupplier;
@Override @Override
public S setGui(@NotNull Supplier<Gui> guiSupplier) { public @NotNull S setGui(@NotNull Supplier<Gui> guiSupplier) {
this.guiSupplier = guiSupplier; this.guiSupplier = guiSupplier;
return (S) this; return (S) this;
} }
@Override @Override
public S setGui(@NotNull Gui gui) { public @NotNull S setGui(@NotNull Gui gui) {
this.guiSupplier = () -> gui; this.guiSupplier = () -> gui;
return (S) this; return (S) this;
} }
@Override @Override
public S setGui(@NotNull Gui.Builder<?, ?> builder) { public @NotNull S setGui(@NotNull Gui.Builder<?, ?> builder) {
this.guiSupplier = builder::build; this.guiSupplier = builder::build;
return (S) this; return (S) this;
} }

@ -21,14 +21,13 @@ public abstract class AbstractSplitWindow extends AbstractDoubleWindow {
private final AbstractGui upperGui; private final AbstractGui upperGui;
private final AbstractGui lowerGui; private final AbstractGui lowerGui;
public AbstractSplitWindow(Player player, ComponentWrapper title, AbstractGui upperGui, AbstractGui lowerGui, Inventory upperInventory, boolean initItems, boolean closeable, boolean retain) { public AbstractSplitWindow(Player player, ComponentWrapper title, AbstractGui upperGui, AbstractGui lowerGui, Inventory upperInventory, boolean closeable) {
super(player, title, upperGui.getSize() + lowerGui.getSize(), upperInventory, closeable, retain); super(player, title, upperGui.getSize() + lowerGui.getSize(), upperInventory, closeable);
this.upperGui = upperGui; this.upperGui = upperGui;
this.lowerGui = lowerGui; this.lowerGui = lowerGui;
upperGui.addParent(this); upperGui.addParent(this);
lowerGui.addParent(this); lowerGui.addParent(this);
if (initItems) initUpperItems();
} }
@Override @Override
@ -68,46 +67,46 @@ public abstract class AbstractSplitWindow extends AbstractDoubleWindow {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static abstract class AbstractBuilder<W extends Window, V, S extends Window.Builder.Double<W, V, S>> public static abstract class AbstractBuilder<W extends Window, S extends Window.Builder.Double<W, S>>
extends AbstractWindow.AbstractBuilder<W, V, S> extends AbstractWindow.AbstractBuilder<W, S>
implements Window.Builder.Double<W, V, S> implements Window.Builder.Double<W, S>
{ {
protected Supplier<Gui> upperGuiSupplier; protected Supplier<Gui> upperGuiSupplier;
protected Supplier<Gui> lowerGuiSupplier; protected Supplier<Gui> lowerGuiSupplier;
@Override @Override
public S setUpperGui(@NotNull Supplier<Gui> guiSupplier) { public @NotNull S setUpperGui(@NotNull Supplier<Gui> guiSupplier) {
this.upperGuiSupplier = guiSupplier; this.upperGuiSupplier = guiSupplier;
return (S) this; return (S) this;
} }
@Override @Override
public S setUpperGui(@NotNull Gui gui) { public @NotNull S setUpperGui(@NotNull Gui gui) {
this.upperGuiSupplier = () -> gui; this.upperGuiSupplier = () -> gui;
return (S) this; return (S) this;
} }
@Override @Override
public S setUpperGui(@NotNull Gui.Builder<?, ?> builder) { public @NotNull S setUpperGui(@NotNull Gui.Builder<?, ?> builder) {
this.upperGuiSupplier = builder::build; this.upperGuiSupplier = builder::build;
return (S) this; return (S) this;
} }
@Override @Override
public S setLowerGui(@NotNull Supplier<Gui> guiSupplier) { public @NotNull S setLowerGui(@NotNull Supplier<Gui> guiSupplier) {
this.lowerGuiSupplier = guiSupplier; this.lowerGuiSupplier = guiSupplier;
return (S) this; return (S) this;
} }
@Override @Override
public S setLowerGui(@NotNull Gui gui) { public @NotNull S setLowerGui(@NotNull Gui gui) {
this.lowerGuiSupplier = () -> gui; this.lowerGuiSupplier = () -> gui;
return (S) this; return (S) this;
} }
@Override @Override
public S setLowerGui(@NotNull Gui.Builder<?, ?> builder) { public @NotNull S setLowerGui(@NotNull Gui.Builder<?, ?> builder) {
this.lowerGuiSupplier = builder::build; this.lowerGuiSupplier = builder::build;
return (S) this; return (S) this;
} }

@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.InventoryAccess; import xyz.xenondevs.inventoryaccess.InventoryAccess;
import xyz.xenondevs.inventoryaccess.component.BaseComponentWrapper; import xyz.xenondevs.inventoryaccess.component.BaseComponentWrapper;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.inventoryaccess.component.i18n.Languages;
import xyz.xenondevs.invui.InvUI; import xyz.xenondevs.invui.InvUI;
import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.AbstractGui;
import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Gui;
@ -41,25 +42,20 @@ public abstract class AbstractWindow implements Window, GuiParent {
private static final NamespacedKey SLOT_KEY = new NamespacedKey(InvUI.getInstance().getPlugin(), "slot"); private static final NamespacedKey SLOT_KEY = new NamespacedKey(InvUI.getInstance().getPlugin(), "slot");
private final UUID viewerUUID; private final UUID viewerUUID;
private final boolean retain;
private final SlotElement[] elementsDisplayed; private final SlotElement[] elementsDisplayed;
private List<Runnable> openHandlers;
private List<Runnable> closeHandlers; private List<Runnable> closeHandlers;
private ComponentWrapper title; private ComponentWrapper title;
private boolean closeable; private boolean closeable;
private boolean removed; private boolean currentlyOpen;
public AbstractWindow(UUID viewerUUID, ComponentWrapper title, int size, boolean closeable, boolean retain) { public AbstractWindow(UUID viewerUUID, ComponentWrapper title, int size, boolean closeable) {
this.viewerUUID = viewerUUID; this.viewerUUID = viewerUUID;
this.title = title; this.title = title;
this.closeable = closeable; this.closeable = closeable;
this.retain = retain;
this.elementsDisplayed = new SlotElement[size]; this.elementsDisplayed = new SlotElement[size];
} }
protected void register() {
WindowManager.getInstance().addWindow(this);
}
protected void redrawItem(int index) { protected void redrawItem(int index) {
redrawItem(index, getSlotElement(index), false); redrawItem(index, getSlotElement(index), false);
} }
@ -168,18 +164,29 @@ public abstract class AbstractWindow implements Window, GuiParent {
event.setCursor(cursorStack); event.setCursor(cursorStack);
} }
public void handleOpen(InventoryOpenEvent event) { public void handleOpenEvent(InventoryOpenEvent event) {
if (!event.getPlayer().equals(getViewer())) if (!event.getPlayer().equals(getViewer())) {
event.setCancelled(true); event.setCancelled(true);
else handleOpened(); } else {
if (currentlyOpen)
throw new IllegalStateException("Window is already opened!");
currentlyOpen = true;
handleOpened();
if (openHandlers != null) {
openHandlers.forEach(Runnable::run);
}
}
} }
public void handleClose(Player player) { public void handleCloseEvent(Player player) {
if (closeable) { if (closeable) {
if (!retain) { if (!currentlyOpen)
remove(false); throw new IllegalStateException("Window is already closed!");
}
currentlyOpen = false;
remove(false);
handleClosed(); handleClosed();
if (closeHandlers != null) { if (closeHandlers != null) {
@ -211,15 +218,7 @@ public abstract class AbstractWindow implements Window, GuiParent {
&& ((SlotElement.VISlotElement) element).getVirtualInventory() == virtualInventory); && ((SlotElement.VISlotElement) element).getVirtualInventory() == virtualInventory);
} }
public void remove() {
remove(true);
}
public void remove(boolean closeForViewer) { public void remove(boolean closeForViewer) {
if (removed)
return;
removed = true;
WindowManager.getInstance().removeWindow(this); WindowManager.getInstance().removeWindow(this);
Arrays.stream(elementsDisplayed) Arrays.stream(elementsDisplayed)
@ -252,14 +251,20 @@ public abstract class AbstractWindow implements Window, GuiParent {
@Override @Override
public void show() { public void show() {
if (removed) throw new IllegalStateException("The Window has already been closed.");
Player viewer = getViewer(); Player viewer = getViewer();
if (viewer == null) throw new IllegalStateException("The player is not online."); if (viewer == null)
throw new IllegalStateException("The player is not online.");
initItems();
WindowManager.getInstance().addWindow(this);
openInventory(viewer);
}
protected void openInventory(@NotNull Player viewer) {
InventoryAccess.getInventoryUtils().openCustomInventory( InventoryAccess.getInventoryUtils().openCustomInventory(
viewer, viewer,
getInventories()[0], getInventories()[0],
title.localized(viewer.getLocale()) title.localized(viewer)
); );
} }
@ -270,7 +275,7 @@ public abstract class AbstractWindow implements Window, GuiParent {
if (currentViewer != null) { if (currentViewer != null) {
InventoryAccess.getInventoryUtils().updateOpenInventoryTitle( InventoryAccess.getInventoryUtils().updateOpenInventoryTitle(
currentViewer, currentViewer,
title.localized(currentViewer.getLocale()) title.localized(currentViewer)
); );
} }
} }
@ -285,6 +290,19 @@ public abstract class AbstractWindow implements Window, GuiParent {
changeTitle(TextComponent.fromLegacyText(title)); changeTitle(TextComponent.fromLegacyText(title));
} }
@Override
public void setOpenHandlers(@NotNull List<@NotNull Runnable> openHandlers) {
this.openHandlers = openHandlers;
}
@Override
public void addOpenHandler(@NotNull Runnable openHandler) {
if (openHandlers == null)
openHandlers = new ArrayList<>();
openHandlers.add(openHandler);
}
@Override @Override
public void setCloseHandlers(@NotNull List<@NotNull Runnable> closeHandlers) { public void setCloseHandlers(@NotNull List<@NotNull Runnable> closeHandlers) {
this.closeHandlers = closeHandlers; this.closeHandlers = closeHandlers;
@ -321,7 +339,7 @@ public abstract class AbstractWindow implements Window, GuiParent {
if (player == null) if (player == null)
throw new IllegalStateException("Tried to receive the language from a viewer that is not online."); throw new IllegalStateException("Tried to receive the language from a viewer that is not online.");
return player.getLocale(); return Languages.getInstance().getLanguage(player);
} }
@Override @Override
@ -340,8 +358,8 @@ public abstract class AbstractWindow implements Window, GuiParent {
} }
@Override @Override
public boolean isRemoved() { public boolean isOpen() {
return removed; return currentlyOpen;
} }
protected abstract void setInvItem(int slot, ItemStack itemStack); protected abstract void setInvItem(int slot, ItemStack itemStack);
@ -354,6 +372,8 @@ public abstract class AbstractWindow implements Window, GuiParent {
protected abstract Inventory[] getInventories(); protected abstract Inventory[] getInventories();
protected abstract void initItems();
protected abstract void handleOpened(); protected abstract void handleOpened();
protected abstract void handleClosed(); protected abstract void handleClosed();
@ -367,59 +387,68 @@ public abstract class AbstractWindow implements Window, GuiParent {
public abstract void handleViewerDeath(PlayerDeathEvent event); public abstract void handleViewerDeath(PlayerDeathEvent event);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static abstract class AbstractBuilder<W extends Window, V, S extends Window.Builder<W, V, S>> implements Window.Builder<W, V, S> { public static abstract class AbstractBuilder<W extends Window, S extends Window.Builder<W, S>> implements Window.Builder<W, S> {
protected V viewer; protected Player viewer;
protected ComponentWrapper title; protected ComponentWrapper title;
protected boolean closeable = true; protected boolean closeable = true;
protected boolean retain = false; protected List<Runnable> openHandlers;
protected List<Runnable> closeHandlers; protected List<Runnable> closeHandlers;
protected List<Consumer<Window>> modifiers; protected List<Consumer<Window>> modifiers;
@Override @Override
public S setViewer(@NotNull V viewer) { public @NotNull S setViewer(@NotNull Player viewer) {
this.viewer = viewer; this.viewer = viewer;
return (S) this; return (S) this;
} }
@Override @Override
public S setTitle(@NotNull ComponentWrapper title) { public @NotNull S setTitle(@NotNull ComponentWrapper title) {
this.title = title; this.title = title;
return (S) this; return (S) this;
} }
@Override @Override
public S setTitle(@NotNull BaseComponent @NotNull [] title) { public @NotNull S setTitle(@NotNull BaseComponent @NotNull [] title) {
this.title = new BaseComponentWrapper(title); this.title = new BaseComponentWrapper(title);
return (S) this; return (S) this;
} }
@Override @Override
public S setTitle(@NotNull String title) { public @NotNull S setTitle(@NotNull String title) {
this.title = new BaseComponentWrapper(TextComponent.fromLegacyText(title)); this.title = new BaseComponentWrapper(TextComponent.fromLegacyText(title));
return (S) this; return (S) this;
} }
@Override @Override
public S setCloseable(boolean closeable) { public @NotNull S setCloseable(boolean closeable) {
this.closeable = closeable; this.closeable = closeable;
return (S) this; return (S) this;
} }
@Override @Override
public S setRetain(boolean retain) { public @NotNull S setOpenHandlers(List<Runnable> openHandlers) {
this.retain = retain; this.openHandlers = openHandlers;
return (S) this; return (S) this;
} }
@Override @Override
public S setCloseHandlers(List<Runnable> closeHandlers) { public @NotNull S addOpenHandler(Runnable openHandler) {
if (openHandlers == null)
openHandlers = new ArrayList<>();
openHandlers.add(openHandler);
return (S) this;
}
@Override
public @NotNull S setCloseHandlers(List<Runnable> closeHandlers) {
this.closeHandlers = closeHandlers; this.closeHandlers = closeHandlers;
return (S) this; return (S) this;
} }
@Override @Override
public S addCloseHandler(Runnable closeHandler) { public @NotNull S addCloseHandler(Runnable closeHandler) {
if (closeHandlers == null) if (closeHandlers == null)
closeHandlers = new ArrayList<>(); closeHandlers = new ArrayList<>();
@ -428,13 +457,13 @@ public abstract class AbstractWindow implements Window, GuiParent {
} }
@Override @Override
public S setModifiers(List<Consumer<Window>> modifiers) { public @NotNull S setModifiers(List<Consumer<Window>> modifiers) {
this.modifiers = modifiers; this.modifiers = modifiers;
return (S) this; return (S) this;
} }
@Override @Override
public S addModifier(Consumer<Window> modifier) { public @NotNull S addModifier(Consumer<Window> modifier) {
if (modifiers == null) if (modifiers == null)
modifiers = new ArrayList<>(); modifiers = new ArrayList<>();
@ -450,11 +479,21 @@ public abstract class AbstractWindow implements Window, GuiParent {
modifiers.forEach(modifier -> modifier.accept(window)); modifiers.forEach(modifier -> modifier.accept(window));
} }
@Override
public @NotNull W build() {
return build(viewer);
}
@Override
public void show(Player viewer) {
build(viewer).show();
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public @NotNull S clone() { public @NotNull S clone() {
try { try {
var clone = (AbstractBuilder<W, V, S>) super.clone(); var clone = (AbstractBuilder<W, S>) super.clone();
if (title != null) if (title != null)
clone.title = title.clone(); clone.title = title.clone();
if (closeHandlers != null) if (closeHandlers != null)
@ -469,5 +508,4 @@ public abstract class AbstractWindow implements Window, GuiParent {
} }
} }

@ -22,15 +22,11 @@ final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilW
@Nullable ComponentWrapper title, @Nullable ComponentWrapper title,
@NotNull AbstractGui gui, @NotNull AbstractGui gui,
@Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers, @Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers,
boolean closable, boolean closable
boolean retain
) { ) {
super(player.getUniqueId(), title, gui, null, false, closable, retain); super(player.getUniqueId(), title, gui, null, closable);
anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandlers); anvilInventory = InventoryAccess.createAnvilInventory(player, title.localized(player), renameHandlers);
inventory = anvilInventory.getBukkitInventory(); inventory = anvilInventory.getBukkitInventory();
initItems();
register();
} }
@Override @Override
@ -39,11 +35,7 @@ final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilW
} }
@Override @Override
public void show() { protected void openInventory(@NotNull Player viewer) {
if (isRemoved()) throw new IllegalStateException("The Window has already been closed.");
Player viewer = getViewer();
if (viewer == null) throw new IllegalStateException("The player is not online.");
anvilInventory.open(); anvilInventory.open();
} }
@ -53,7 +45,7 @@ final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilW
} }
public static final class BuilderImpl public static final class BuilderImpl
extends AbstractSingleWindow.AbstractBuilder<AnvilWindow, Player, AnvilWindow.Builder.Single> extends AbstractSingleWindow.AbstractBuilder<AnvilWindow, AnvilWindow.Builder.Single>
implements AnvilWindow.Builder.Single implements AnvilWindow.Builder.Single
{ {
@ -75,7 +67,7 @@ final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilW
} }
@Override @Override
public @NotNull AnvilWindow build() { public @NotNull AnvilWindow build(Player viewer) {
if (viewer == null) if (viewer == null)
throw new IllegalStateException("Viewer is not defined."); throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null) if (guiSupplier == null)
@ -86,8 +78,7 @@ final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilW
title, title,
(AbstractGui) guiSupplier.get(), (AbstractGui) guiSupplier.get(),
renameHandlers, renameHandlers,
closeable, closeable
retain
); );
applyModifiers(window); applyModifiers(window);

@ -23,16 +23,12 @@ final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWin
@NotNull AbstractGui upperGui, @NotNull AbstractGui upperGui,
@NotNull AbstractGui lowerGui, @NotNull AbstractGui lowerGui,
@Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers, @Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers,
boolean closeable, boolean closeable
boolean retain
) { ) {
super(player, title, upperGui, lowerGui, null, false, closeable, retain); super(player, title, upperGui, lowerGui, null, closeable);
anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandlers); anvilInventory = InventoryAccess.createAnvilInventory(player, title.localized(player), renameHandlers);
upperInventory = anvilInventory.getBukkitInventory(); upperInventory = anvilInventory.getBukkitInventory();
initUpperItems();
register();
} }
@Override @Override
@ -41,11 +37,7 @@ final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWin
} }
@Override @Override
public void show() { protected void openInventory(@NotNull Player viewer) {
if (isRemoved()) throw new IllegalStateException("The Window has already been closed.");
Player viewer = getViewer();
if (viewer == null) throw new IllegalStateException("The player is not online.");
anvilInventory.open(); anvilInventory.open();
} }
@ -55,7 +47,7 @@ final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWin
} }
public static final class BuilderImpl public static final class BuilderImpl
extends AbstractSplitWindow.AbstractBuilder<AnvilWindow, Player, AnvilWindow.Builder.Split> extends AbstractSplitWindow.AbstractBuilder<AnvilWindow, AnvilWindow.Builder.Split>
implements AnvilWindow.Builder.Split implements AnvilWindow.Builder.Split
{ {
@ -77,7 +69,7 @@ final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWin
} }
@Override @Override
public @NotNull AnvilWindow build() { public @NotNull AnvilWindow build(Player viewer) {
if (viewer == null) if (viewer == null)
throw new IllegalStateException("Viewer is not defined."); throw new IllegalStateException("Viewer is not defined.");
if (upperGuiSupplier == null) if (upperGuiSupplier == null)
@ -91,8 +83,7 @@ final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWin
(AbstractGui) upperGuiSupplier.get(), (AbstractGui) upperGuiSupplier.get(),
(AbstractGui) lowerGuiSupplier.get(), (AbstractGui) lowerGuiSupplier.get(),
renameHandlers, renameHandlers,
closeable, closeable
retain
); );
applyModifiers(window); applyModifiers(window);

@ -65,7 +65,7 @@ public interface AnvilWindow extends Window {
* @see Window.Builder.Normal * @see Window.Builder.Normal
* @see CartographyWindow.Builder * @see CartographyWindow.Builder
*/ */
interface Builder<S extends Builder<S>> extends Window.Builder<AnvilWindow, Player, S> { interface Builder<S extends Builder<S>> extends Window.Builder<AnvilWindow, S> {
/** /**
* Sets the rename handlers of the {@link AnvilWindow}. * Sets the rename handlers of the {@link AnvilWindow}.
@ -90,7 +90,7 @@ public interface AnvilWindow extends Window {
* @see Window.Builder.Normal.Single * @see Window.Builder.Normal.Single
* @see CartographyWindow.Builder.Single * @see CartographyWindow.Builder.Single
*/ */
interface Single extends Builder<Single>, Window.Builder.Single<AnvilWindow, Player, Single> {} interface Single extends Builder<Single>, Window.Builder.Single<AnvilWindow, Single> {}
/** /**
* A split {@link AnvilWindow} builder. Combines both {@link AnvilWindow.Builder} and {@link Window.Builder.Double} * A split {@link AnvilWindow} builder. Combines both {@link AnvilWindow.Builder} and {@link Window.Builder.Double}
@ -100,7 +100,7 @@ public interface AnvilWindow extends Window {
* @see Window.Builder.Normal.Split * @see Window.Builder.Normal.Split
* @see CartographyWindow.Builder.Split * @see CartographyWindow.Builder.Split
*/ */
interface Split extends Builder<Split>, Window.Builder.Double<AnvilWindow, Player, Split> {} interface Split extends Builder<Split>, Window.Builder.Double<AnvilWindow, Split> {}
} }

@ -26,18 +26,15 @@ final class CartographySingleWindowImpl extends AbstractSingleWindow implements
@NotNull Player player, @NotNull Player player,
@Nullable ComponentWrapper title, @Nullable ComponentWrapper title,
@NotNull AbstractGui gui, @NotNull AbstractGui gui,
boolean closeable, boolean closeable
boolean retain
) { ) {
super(player.getUniqueId(), title, gui, null, false, closeable, retain); super(player.getUniqueId(), title, gui, null, closeable);
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");
cartographyInventory = InventoryAccess.createCartographyInventory(player, title); cartographyInventory = InventoryAccess.createCartographyInventory(player, title.localized(player));
inventory = cartographyInventory.getBukkitInventory(); inventory = cartographyInventory.getBukkitInventory();
initItems();
resetMap(); resetMap();
register();
} }
@Override @Override
@ -71,23 +68,17 @@ final class CartographySingleWindowImpl extends AbstractSingleWindow implements
} }
@Override @Override
public void show() { protected void openInventory(@NotNull Player viewer) {
if (isRemoved())
throw new IllegalStateException("The Window has already been closed.");
Player viewer = getViewer();
if (viewer == null)
throw new IllegalStateException("The player is not online.");
cartographyInventory.open(); cartographyInventory.open();
} }
public static final class BuilderImpl public static final class BuilderImpl
extends AbstractSingleWindow.AbstractBuilder<CartographyWindow, Player, CartographyWindow.Builder.Single> extends AbstractSingleWindow.AbstractBuilder<CartographyWindow, CartographyWindow.Builder.Single>
implements CartographyWindow.Builder.Single implements CartographyWindow.Builder.Single
{ {
@Override @Override
public @NotNull CartographyWindow build() { public @NotNull CartographyWindow build(Player viewer) {
if (viewer == null) if (viewer == null)
throw new IllegalStateException("Viewer is not defined."); throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null) if (guiSupplier == null)
@ -97,8 +88,7 @@ final class CartographySingleWindowImpl extends AbstractSingleWindow implements
viewer, viewer,
title, title,
(AbstractGui) guiSupplier.get(), (AbstractGui) guiSupplier.get(),
closeable, closeable
retain
); );
applyModifiers(window); applyModifiers(window);

@ -27,17 +27,14 @@ final class CartographySplitWindowImpl extends AbstractSplitWindow implements Ca
@Nullable ComponentWrapper title, @Nullable ComponentWrapper title,
@NotNull AbstractGui upperGui, @NotNull AbstractGui upperGui,
@NotNull AbstractGui lowerGui, @NotNull AbstractGui lowerGui,
boolean closeable, boolean closeable
boolean retain
) { ) {
super(player, title, createWrappingGui(upperGui), lowerGui, null, false, closeable, retain); super(player, title, createWrappingGui(upperGui), lowerGui, null, closeable);
cartographyInventory = InventoryAccess.createCartographyInventory(player, title); cartographyInventory = InventoryAccess.createCartographyInventory(player, title.localized(player));
upperInventory = cartographyInventory.getBukkitInventory(); upperInventory = cartographyInventory.getBukkitInventory();
initUpperItems();
resetMap(); resetMap();
register();
} }
private static AbstractGui createWrappingGui(Gui upperGui) { private static AbstractGui createWrappingGui(Gui upperGui) {
@ -66,23 +63,17 @@ final class CartographySplitWindowImpl extends AbstractSplitWindow implements Ca
} }
@Override @Override
public void show() { protected void openInventory(@NotNull Player viewer) {
if (isRemoved())
throw new IllegalStateException("The Window has already been closed.");
Player viewer = getViewer();
if (viewer == null)
throw new IllegalStateException("The player is not online.");
cartographyInventory.open(); cartographyInventory.open();
} }
public static final class BuilderImpl public static final class BuilderImpl
extends AbstractSplitWindow.AbstractBuilder<CartographyWindow, Player, CartographyWindow.Builder.Split> extends AbstractSplitWindow.AbstractBuilder<CartographyWindow, CartographyWindow.Builder.Split>
implements CartographyWindow.Builder.Split implements CartographyWindow.Builder.Split
{ {
@Override @Override
public @NotNull CartographyWindow build() { public @NotNull CartographyWindow build(Player viewer) {
if (viewer == null) if (viewer == null)
throw new IllegalStateException("Viewer is not defined."); throw new IllegalStateException("Viewer is not defined.");
if (upperGuiSupplier == null) if (upperGuiSupplier == null)
@ -93,8 +84,7 @@ final class CartographySplitWindowImpl extends AbstractSplitWindow implements Ca
title, title,
(AbstractGui) upperGuiSupplier.get(), (AbstractGui) upperGuiSupplier.get(),
(AbstractGui) lowerGuiSupplier.get(), (AbstractGui) lowerGuiSupplier.get(),
closeable, closeable
retain
); );
applyModifiers(window); applyModifiers(window);

@ -95,21 +95,21 @@ public interface CartographyWindow extends Window {
* @see Window.Builder.Normal * @see Window.Builder.Normal
* @see Window.Builder * @see Window.Builder
*/ */
interface Builder<S extends Builder<S>> extends Window.Builder<CartographyWindow, Player, S> { interface Builder<S extends Builder<S>> extends Window.Builder<CartographyWindow, S> {
/** /**
* A single {@link CartographyWindow} builder. Combines both {@link CartographyWindow.Builder} an * A single {@link CartographyWindow} builder. Combines both {@link CartographyWindow.Builder} an
* {@link Window.Builder.Single} for a {@link CartographyWindow} with only one {@link Gui} that does not * {@link Window.Builder.Single} for a {@link CartographyWindow} with only one {@link Gui} that does not
* access the {@link Player Player's} inventory. * access the {@link Player Player's} inventory.
*/ */
interface Single extends Builder<Single>, Window.Builder.Single<CartographyWindow, Player, Single> {} interface Single extends Builder<Single>, Window.Builder.Single<CartographyWindow, Single> {}
/** /**
* A split {@link CartographyWindow} builder. Combines both {@link CartographyWindow.Builder} an * A split {@link CartographyWindow} builder. Combines both {@link CartographyWindow.Builder} an
* {@link Window.Builder.Double} for a {@link CartographyWindow} with two {@link Gui Guis}, where the lower * {@link Window.Builder.Double} for a {@link CartographyWindow} with two {@link Gui Guis}, where the lower
* {@link Gui} is used to fill the {@link Player Player's} inventory. * {@link Gui} is used to fill the {@link Player Player's} inventory.
*/ */
interface Split extends Builder<Split>, Window.Builder.Double<CartographyWindow, Player, Split> {} interface Split extends Builder<Split>, Window.Builder.Double<CartographyWindow, Split> {}
} }

@ -15,11 +15,9 @@ final class NormalMergedWindowImpl extends AbstractMergedWindow {
@NotNull Player player, @NotNull Player player,
@Nullable ComponentWrapper title, @Nullable ComponentWrapper title,
@NotNull AbstractGui gui, @NotNull AbstractGui gui,
boolean closeable, boolean closeable
boolean retain
) { ) {
super(player, title, gui, createInventory(gui), closeable, retain); super(player, title, gui, createInventory(gui), closeable);
register();
} }
private static Inventory createInventory(Gui gui) { private static Inventory createInventory(Gui gui) {
@ -32,12 +30,12 @@ final class NormalMergedWindowImpl extends AbstractMergedWindow {
} }
public static final class BuilderImpl public static final class BuilderImpl
extends AbstractSingleWindow.AbstractBuilder<Window, Player, Window.Builder.Normal.Merged> extends AbstractSingleWindow.AbstractBuilder<Window, Window.Builder.Normal.Merged>
implements Window.Builder.Normal.Merged implements Window.Builder.Normal.Merged
{ {
@Override @Override
public @NotNull Window build() { public @NotNull Window build(Player viewer) {
if (viewer == null) if (viewer == null)
throw new IllegalStateException("Viewer is not defined."); throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null) if (guiSupplier == null)
@ -47,8 +45,7 @@ final class NormalMergedWindowImpl extends AbstractMergedWindow {
viewer, viewer,
title, title,
(AbstractGui) guiSupplier.get(), (AbstractGui) guiSupplier.get(),
closeable, closeable
retain
); );
applyModifiers(window); applyModifiers(window);

@ -1,41 +1,30 @@
package xyz.xenondevs.invui.window; package xyz.xenondevs.invui.window;
import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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;
import java.util.UUID;
final class NormalSingleWindowImpl extends AbstractSingleWindow { final class NormalSingleWindowImpl extends AbstractSingleWindow {
public NormalSingleWindowImpl( public NormalSingleWindowImpl(
@NotNull UUID viewerUUID, @NotNull Player player,
@Nullable ComponentWrapper title, @Nullable ComponentWrapper title,
@NotNull AbstractGui gui, @NotNull AbstractGui gui,
boolean closeable, boolean closeable
boolean retain
) { ) {
super(viewerUUID, title, gui, InventoryUtils.createMatchingInventory(gui, ""), true, closeable, retain); super(player.getUniqueId(), title, gui, InventoryUtils.createMatchingInventory(gui, ""), closeable);
register();
} }
public static final class BuilderImpl public static final class BuilderImpl
extends AbstractSingleWindow.AbstractBuilder<Window, UUID, Window.Builder.Normal.Single> extends AbstractSingleWindow.AbstractBuilder<Window, Window.Builder.Normal.Single>
implements Window.Builder.Normal.Single implements Window.Builder.Normal.Single
{ {
@Contract("_ -> this")
public BuilderImpl setViewer(@NotNull OfflinePlayer player) {
setViewer(player.getUniqueId());
return this;
}
@Override @Override
public @NotNull Window build() { public @NotNull Window build(Player viewer) {
if (viewer == null) if (viewer == null)
throw new IllegalStateException("Viewer is not defined."); throw new IllegalStateException("Viewer is not defined.");
if (guiSupplier == null) if (guiSupplier == null)
@ -45,8 +34,7 @@ final class NormalSingleWindowImpl extends AbstractSingleWindow {
viewer, viewer,
title, title,
(AbstractGui) guiSupplier.get(), (AbstractGui) guiSupplier.get(),
closeable, closeable
retain
); );
applyModifiers(window); applyModifiers(window);

@ -14,20 +14,18 @@ final class NormalSplitWindowImpl extends AbstractSplitWindow {
@Nullable ComponentWrapper title, @Nullable ComponentWrapper title,
@NotNull AbstractGui upperGui, @NotNull AbstractGui upperGui,
@NotNull AbstractGui lowerGui, @NotNull AbstractGui lowerGui,
boolean closeable, boolean closeable
boolean retain
) { ) {
super(player, title, upperGui, lowerGui, InventoryUtils.createMatchingInventory(upperGui, ""), true, closeable, retain); super(player, title, upperGui, lowerGui, InventoryUtils.createMatchingInventory(upperGui, ""), closeable);
register();
} }
public static final class BuilderImpl public static final class BuilderImpl
extends AbstractSplitWindow.AbstractBuilder<Window, Player, Window.Builder.Normal.Split> extends AbstractSplitWindow.AbstractBuilder<Window, Window.Builder.Normal.Split>
implements Window.Builder.Normal.Split implements Window.Builder.Normal.Split
{ {
@Override @Override
public @NotNull Window build() { public @NotNull Window build(Player viewer) {
if (viewer == null) if (viewer == null)
throw new IllegalStateException("Viewer is not defined."); throw new IllegalStateException("Viewer is not defined.");
if (upperGuiSupplier == null) if (upperGuiSupplier == null)
@ -40,8 +38,7 @@ final class NormalSplitWindowImpl extends AbstractSplitWindow {
title, title,
(AbstractGui) upperGuiSupplier.get(), (AbstractGui) upperGuiSupplier.get(),
(AbstractGui) lowerGuiSupplier.get(), (AbstractGui) lowerGuiSupplier.get(),
closeable, closeable
retain
); );
applyModifiers(window); applyModifiers(window);

@ -1,7 +1,6 @@
package xyz.xenondevs.invui.window; package xyz.xenondevs.invui.window;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
@ -113,17 +112,11 @@ public interface Window {
void close(); void close();
/** /**
* Gets if the {@link Window} is closed and can't be shown again. * Gets if the viewer is currently viewing this {@link Window}.
* *
* @return If the {@link Window} is closed. * @return If the {@link Window} is currently open.
*/ */
boolean isRemoved(); boolean isOpen();
/**
* Removes the {@link Window} from the {@link WindowManager} list.
* If this method is called, the {@link Window} can't be shown again.
*/
void remove();
/** /**
* Changes the title of the {@link Inventory}. * Changes the title of the {@link Inventory}.
@ -168,6 +161,20 @@ public interface Window {
*/ */
@NotNull UUID getViewerUUID(); @NotNull UUID getViewerUUID();
/**
* Replaces the currently registered open handlers with the given list.
*
* @param openHandlers The new open handlers
*/
void setOpenHandlers(@NotNull List<@NotNull Runnable> openHandlers);
/**
* Adds an open handler that will be called when this window gets opened.
*
* @param openHandler The close handler to add
*/
void addOpenHandler(@NotNull Runnable openHandler);
/** /**
* Replaces the currently registered close handlers with the given list. * Replaces the currently registered close handlers with the given list.
* *
@ -193,10 +200,9 @@ public interface Window {
* A {@link Window} builder. * A {@link Window} builder.
* *
* @param <W> The window type * @param <W> The window type
* @param <V> The viewer type
* @param <S> The builder type * @param <S> The builder type
*/ */
interface Builder<W extends Window, V, S extends Builder<W, V, S>> extends Cloneable { interface Builder<W extends Window, S extends Builder<W, S>> extends Cloneable {
/** /**
* Sets the viewer of the {@link Window}. * Sets the viewer of the {@link Window}.
@ -205,7 +211,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setViewer(@NotNull V viewer); @NotNull S setViewer(@NotNull Player viewer);
/** /**
* Sets the title of the {@link Window}. * Sets the title of the {@link Window}.
@ -214,7 +220,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setTitle(@NotNull ComponentWrapper title); @NotNull S setTitle(@NotNull ComponentWrapper title);
/** /**
* Sets the title of the {@link Window}. * Sets the title of the {@link Window}.
@ -223,7 +229,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setTitle(@NotNull BaseComponent @NotNull [] title); @NotNull S setTitle(@NotNull BaseComponent @NotNull [] title);
/** /**
* Sets the title of the {@link Window}. * Sets the title of the {@link Window}.
@ -232,7 +238,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setTitle(@NotNull String title); @NotNull S setTitle(@NotNull String title);
/** /**
* Configures if the {@link Window} is closeable. * Configures if the {@link Window} is closeable.
@ -241,16 +247,25 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setCloseable(boolean closeable); @NotNull S setCloseable(boolean closeable);
/** /**
* Configures if the {@link Window} should be retained after it has been closed. * Sets the open handlers of the {@link Window}.
* *
* @param retain If the {@link Window} should be retained * @param openHandlers The open handlers of the {@link Window}
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setRetain(boolean retain); @NotNull S setOpenHandlers(List<Runnable> openHandlers);
/**
* Adds an open handler to the {@link Window}.
*
* @param openHandler The open handler to add
* @return This {@link Builder Window Builder}
*/
@Contract("_ -> this")
@NotNull S addOpenHandler(Runnable openHandler);
/** /**
* Sets the close handlers of the {@link Window}. * Sets the close handlers of the {@link Window}.
@ -259,7 +274,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setCloseHandlers(List<Runnable> closeHandlers); @NotNull S setCloseHandlers(List<Runnable> closeHandlers);
/** /**
* Adds a close handler to the {@link Window}. * Adds a close handler to the {@link Window}.
@ -268,7 +283,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S addCloseHandler(Runnable closeHandler); @NotNull S addCloseHandler(Runnable closeHandler);
/** /**
* Sets the modifiers of the {@link Window}. * Sets the modifiers of the {@link Window}.
@ -277,7 +292,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setModifiers(List<Consumer<Window>> modifiers); @NotNull S setModifiers(List<Consumer<Window>> modifiers);
/** /**
* Adds a modifier to the {@link Window}. * Adds a modifier to the {@link Window}.
@ -286,7 +301,7 @@ public interface Window {
* @return This {@link Builder Window Builder} * @return This {@link Builder Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S addModifier(Consumer<Window> modifier); @NotNull S addModifier(Consumer<Window> modifier);
/** /**
* Builds the {@link Window}. * Builds the {@link Window}.
@ -296,6 +311,23 @@ public interface Window {
@Contract("-> new") @Contract("-> new")
@NotNull W build(); @NotNull W build();
/**
* Builds the {@link Window} with the specified viewer.
* If this method is used, the viewer does not need to be set using {@link #setViewer(Player)}.
*
* @param viewer The {@link Player} to build the {@link Window} for.
*/
@Contract("_ -> new")
@NotNull W build(Player viewer);
/**
* Builds and shows the {@link Window} to the specified viewer.
* If this method is used, the viewer does not need to be set using {@link #setViewer(Player)}.
*
* @param viewer The {@link Player} to show the {@link Window} to.
*/
void show(Player viewer);
/** /**
* Clones the {@link Builder Window Builder}. * Clones the {@link Builder Window Builder}.
* *
@ -308,15 +340,13 @@ public interface Window {
* A single {@link Window} builder. Single Windows only have on {@link Gui}. * A single {@link Window} builder. Single Windows only have on {@link Gui}.
* *
* @param <W> The window type * @param <W> The window type
* @param <V> The viewer type
* @param <S> The builder type * @param <S> The builder type
*
* @see Window.Builder.Normal.Single * @see Window.Builder.Normal.Single
* @see Window.Builder.Normal.Merged * @see Window.Builder.Normal.Merged
* @see AnvilWindow.Builder.Single * @see AnvilWindow.Builder.Single
* @see CartographyWindow.Builder.Single * @see CartographyWindow.Builder.Single
*/ */
interface Single<W extends Window, V, S extends Single<W, V, S>> extends Builder<W, V, S> { interface Single<W extends Window, S extends Single<W, S>> extends Builder<W, S> {
/** /**
* Sets the {@link Gui} of the {@link Window}. * Sets the {@link Gui} of the {@link Window}.
@ -325,7 +355,7 @@ public interface Window {
* @return This {@link Single Window Builder} * @return This {@link Single Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setGui(@NotNull Gui gui); @NotNull S setGui(@NotNull Gui gui);
/** /**
* Sets the {@link Gui.Builder} for this {@link Single Window Builder}. * Sets the {@link Gui.Builder} for this {@link Single Window Builder}.
@ -335,7 +365,7 @@ public interface Window {
* @return This {@link Single Window Builder} * @return This {@link Single Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setGui(@NotNull Gui.Builder<?, ?> builder); @NotNull S setGui(@NotNull Gui.Builder<?, ?> builder);
/** /**
* Sets the {@link Gui} {@link Supplier} for this {@link Single Window Builder}. * Sets the {@link Gui} {@link Supplier} for this {@link Single Window Builder}.
@ -345,7 +375,7 @@ public interface Window {
* @return This {@link Single Window Builder} * @return This {@link Single Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setGui(@NotNull Supplier<Gui> guiSupplier); @NotNull S setGui(@NotNull Supplier<Gui> guiSupplier);
} }
@ -353,14 +383,12 @@ public interface Window {
* A double {@link Window} builder. Double Windows have two {@link Gui Guis}. * A double {@link Window} builder. Double Windows have two {@link Gui Guis}.
* *
* @param <W> The window type * @param <W> The window type
* @param <V> The viewer type
* @param <S> The builder type * @param <S> The builder type
*
* @see Window.Builder.Normal.Split * @see Window.Builder.Normal.Split
* @see AnvilWindow.Builder.Split * @see AnvilWindow.Builder.Split
* @see CartographyWindow.Builder.Split * @see CartographyWindow.Builder.Split
*/ */
interface Double<W extends Window, V, S extends Builder.Double<W, V, S>> extends Builder<W, V, S> { interface Double<W extends Window, S extends Builder.Double<W, S>> extends Builder<W, S> {
/** /**
* Sets the upper {@link Gui} of the {@link Window}. * Sets the upper {@link Gui} of the {@link Window}.
@ -369,7 +397,7 @@ public interface Window {
* @return This {@link Double Window Builder} * @return This {@link Double Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setUpperGui(@NotNull Gui gui); @NotNull S setUpperGui(@NotNull Gui gui);
/** /**
* Sets the {@link Gui.Builder} for the upper {@link Gui} of this {@link Double Window Builder}. * Sets the {@link Gui.Builder} for the upper {@link Gui} of this {@link Double Window Builder}.
@ -379,7 +407,7 @@ public interface Window {
* @return This {@link Double Window Builder} * @return This {@link Double Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setUpperGui(@NotNull Gui.Builder<?, ?> builder); @NotNull S setUpperGui(@NotNull Gui.Builder<?, ?> builder);
/** /**
* Sets the {@link Gui} {@link Supplier} for the upper {@link Gui} of this {@link Double Window Builder}. * Sets the {@link Gui} {@link Supplier} for the upper {@link Gui} of this {@link Double Window Builder}.
@ -389,7 +417,7 @@ public interface Window {
* @return This {@link Double Window Builder} * @return This {@link Double Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setUpperGui(@NotNull Supplier<Gui> guiSupplier); @NotNull S setUpperGui(@NotNull Supplier<Gui> guiSupplier);
/** /**
* Sets the lower {@link Gui} of the {@link Window}. * Sets the lower {@link Gui} of the {@link Window}.
@ -398,7 +426,7 @@ public interface Window {
* @return This {@link Double Window Builder} * @return This {@link Double Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setLowerGui(@NotNull Gui gui); @NotNull S setLowerGui(@NotNull Gui gui);
/** /**
* Sets the {@link Gui.Builder} for the lower {@link Gui} of this {@link Double Window Builder}. * Sets the {@link Gui.Builder} for the lower {@link Gui} of this {@link Double Window Builder}.
@ -408,7 +436,7 @@ public interface Window {
* @return This {@link Double Window Builder} * @return This {@link Double Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setLowerGui(@NotNull Gui.Builder<?, ?> builder); @NotNull S setLowerGui(@NotNull Gui.Builder<?, ?> builder);
/** /**
* Sets the {@link Gui} {@link Supplier} for the lower {@link Gui} of this {@link Double Window Builder}. * Sets the {@link Gui} {@link Supplier} for the lower {@link Gui} of this {@link Double Window Builder}.
@ -418,7 +446,7 @@ public interface Window {
* @return This {@link Double Window Builder} * @return This {@link Double Window Builder}
*/ */
@Contract("_ -> this") @Contract("_ -> this")
S setLowerGui(@NotNull Supplier<Gui> guiSupplier); @NotNull S setLowerGui(@NotNull Supplier<Gui> guiSupplier);
} }
@ -426,50 +454,37 @@ public interface Window {
* A normal {@link Window} builder for {@link Window Windows} of inventories with no special functionality, such * A normal {@link Window} builder for {@link Window Windows} of inventories with no special functionality, such
* as chests, hoppers and droppers. * as chests, hoppers and droppers.
* *
* @param <V> The viewer type
* @param <S> The builder type * @param <S> The builder type
*
* @see AnvilWindow.Builder * @see AnvilWindow.Builder
* @see CartographyWindow.Builder * @see CartographyWindow.Builder
*/ */
interface Normal<V, S extends Normal<V, S>> extends Builder<Window, V, S> { interface Normal<V, S extends Normal<V, S>> extends Builder<Window, S> {
/** /**
* A normal single {@link Window} builder. Combines both {@link Builder.Single} and {@link Builder.Normal} * A normal single {@link Window} builder. Combines both {@link Builder.Single} and {@link Builder.Normal}
* for a normal {@link Window} with only one {@link Gui} that does not access the {@link Player Player's} inventory. * for a normal {@link Window} with only one {@link Gui} that does not access the {@link Player Player's} inventory.
* *
* @see AnvilWindow.Builder.Single * @see AnvilWindow.Builder.Single
* @see CartographyWindow.Builder.Single * @see CartographyWindow.Builder.Single
*/ */
interface Single extends Builder.Normal<UUID, Single>, Builder.Single<Window, UUID, Single> { interface Single extends Builder.Normal<UUID, Single>, Builder.Single<Window, Single> {}
/**
* Sets the viewer of the {@link Window}.
*
* @param viewer The viewer of the {@link Window}
* @return This {@link Normal.Single Window Builder}
*/
@Contract("_ -> this")
Normal.Single setViewer(@NotNull OfflinePlayer viewer);
}
/** /**
* A normal split {@link Window} builder. Combines both {@link Builder.Double} and {@link Builder.Normal} * A normal split {@link Window} builder. Combines both {@link Builder.Double} and {@link Builder.Normal}
* for a normal {@link Window} with two {@link Gui Guis}, where the lower {@link Gui} is used to fill the * for a normal {@link Window} with two {@link Gui Guis}, where the lower {@link Gui} is used to fill the
* {@link Player Player's} inventory. * {@link Player Player's} inventory.
* *
* @see AnvilWindow.Builder.Split * @see AnvilWindow.Builder.Split
* @see CartographyWindow.Builder.Split * @see CartographyWindow.Builder.Split
*/ */
interface Split extends Builder.Normal<Player, Split>, Builder.Double<Window, Player, Split> {} interface Split extends Builder.Normal<Player, Split>, Builder.Double<Window, Split> {}
/** /**
* A normal merged {@link Window} builder. Combines both {@link Builder.Single} and {@link Builder.Normal} * A normal merged {@link Window} builder. Combines both {@link Builder.Single} and {@link Builder.Normal}
* for a normal {@link Window} with one {@link Gui}, which fills both the upper inventory and the * for a normal {@link Window} with one {@link Gui}, which fills both the upper inventory and the
* {@link Player Player's} inventory. * {@link Player Player's} inventory.
*/ */
interface Merged extends Builder.Normal<Player, Merged>, Builder.Single<Window, Player, Merged> {} interface Merged extends Builder.Normal<Player, Merged>, Builder.Single<Window, Merged> {}
} }

@ -152,7 +152,7 @@ public class WindowManager implements Listener {
AbstractWindow window = (AbstractWindow) getWindow(event.getInventory()); AbstractWindow window = (AbstractWindow) getWindow(event.getInventory());
if (window != null) if (window != null)
window.handleClose(player); window.handleCloseEvent(player);
openWindows.remove(player); openWindows.remove(player);
} }
@ -161,7 +161,7 @@ public class WindowManager implements Listener {
private void handleInventoryOpen(InventoryOpenEvent event) { private void handleInventoryOpen(InventoryOpenEvent event) {
AbstractWindow window = (AbstractWindow) getWindow(event.getInventory()); AbstractWindow window = (AbstractWindow) getWindow(event.getInventory());
if (window != null) { if (window != null) {
window.handleOpen(event); window.handleOpenEvent(event);
openWindows.put((Player) event.getPlayer(), window); openWindows.put((Player) event.getPlayer(), window);
} }
} }
@ -171,7 +171,7 @@ public class WindowManager implements Listener {
Player player = event.getPlayer(); Player player = event.getPlayer();
AbstractWindow window = (AbstractWindow) getOpenWindow(player); AbstractWindow window = (AbstractWindow) getOpenWindow(player);
if (window != null) { if (window != null) {
window.handleClose(player); window.handleCloseEvent(player);
openWindows.remove(player); openWindows.remove(player);
} }
} }