diff --git a/src/main/java/de/studiocode/invui/gui/GUI.java b/src/main/java/de/studiocode/invui/gui/GUI.java index 689c57d..ea44771 100644 --- a/src/main/java/de/studiocode/invui/gui/GUI.java +++ b/src/main/java/de/studiocode/invui/gui/GUI.java @@ -203,6 +203,17 @@ public interface GUI extends GUIParent { */ void handleItemShift(InventoryClickEvent event); + /** + * A method called when an {@link ItemStack} has been dragged over the {@link GUI}. + * + * @param player The player that is responsible for this action + * @param slot The slot index + * @param oldStack The {@link ItemStack} that was previously on that slot + * @param newStack The new {@link ItemStack} that would be there if the action isn't cancelled + * @return If the action has been cancelled + */ + boolean handleItemDrag(Player player, int slot, ItemStack oldStack, ItemStack newStack); + /** * Adds a {@link GUIParent} to the set of {@link GUIParent}s. * diff --git a/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java b/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java index facb144..39ffd8c 100644 --- a/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java +++ b/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java @@ -14,6 +14,7 @@ import de.studiocode.invui.virtualinventory.VirtualInventory; import de.studiocode.invui.virtualinventory.event.ItemUpdateEvent; import de.studiocode.invui.window.Window; import de.studiocode.invui.window.WindowManager; +import de.studiocode.invui.window.impl.merged.MergedWindow; import de.studiocode.invui.window.impl.merged.combined.CombinedWindow; import de.studiocode.invui.window.impl.merged.split.SplitWindow; import org.bukkit.Bukkit; @@ -108,22 +109,30 @@ abstract class IndexedGUI implements GUI { cancelled = virtualInventory.setToMaxAmount(player, index); break; + case SWAP_WITH_CURSOR: + cancelled = virtualInventory.setItemStack(player, index, event.getCursor()); + break; + case MOVE_TO_OTHER_INVENTORY: event.setCancelled(true); Window window = WindowManager.getInstance().findOpenWindow(player).orElse(null); if (window instanceof CombinedWindow) break; // can't move if there is no other gui ItemStack invStack = virtualInventory.getItemStack(index); - ItemUpdateEvent updateEvent = new ItemUpdateEvent(virtualInventory, player, invStack, - index, invStack.getAmount(), -1); + ItemUpdateEvent updateEvent = new ItemUpdateEvent(virtualInventory, index, player, invStack, null); Bukkit.getPluginManager().callEvent(updateEvent); if (!updateEvent.isCancelled()) { int leftOverAmount; - if (window instanceof SplitWindow) { - SplitWindow splitWindow = (SplitWindow) window; - GUI[] guis = splitWindow.getGuis(); - GUI otherGui = guis[0] == this ? guis[1] : guis[0]; + if (window instanceof MergedWindow) { + GUI otherGui; + if (window instanceof SplitWindow) { + SplitWindow splitWindow = (SplitWindow) window; + GUI[] guis = splitWindow.getGuis(); + otherGui = guis[0] == this ? guis[1] : guis[0]; + } else { + otherGui = this; + } leftOverAmount = ((IndexedGUI) otherGui).putIntoVirtualInventories(player, invStack, virtualInventory); } else { @@ -146,6 +155,22 @@ abstract class IndexedGUI implements GUI { } else event.setCancelled(true); } + @Override + public boolean handleItemDrag(Player player, int slot, ItemStack oldStack, ItemStack newStack) { + SlotElement element = getSlotElement(slot); + if (element != null) element = element.getHoldingElement(); + if (element instanceof VISlotElement) { + VISlotElement viSlotElement = ((VISlotElement) element); + VirtualInventory virtualInventory = viSlotElement.getVirtualInventory(); + int viIndex = viSlotElement.getIndex(); + if (virtualInventory.isSynced(viIndex, oldStack)) { + return virtualInventory.setItemStack(player, viIndex, newStack); + } + } + + return true; + } + @Override public void handleItemShift(InventoryClickEvent event) { event.setCancelled(true); diff --git a/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java b/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java index 9cb90cd..7fa0dcc 100644 --- a/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java +++ b/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java @@ -100,13 +100,24 @@ public class VirtualInventory implements ConfigurationSerializable { /** * Sets an {@link ItemStack} on a specific slot. - * + * + * @param player The player that did this or null if it wasn't a player. * @param index The slot index * @param itemStack The {@link ItemStack} that should be put on that slot + * + * @return If the action has been cancelled */ - public void setItem(int index, ItemStack itemStack) { - items[index] = itemStack.clone(); - notifyWindows(); + public boolean setItemStack(Player player, int index, ItemStack itemStack) { + ItemStack newStack = itemStack.clone(); + ItemUpdateEvent event = createAndCallEvent(index, player, items[index], newStack); + if (!event.isCancelled()) { + items[index] = newStack; + notifyWindows(); + + return false; + } + + return true; } /** @@ -125,7 +136,7 @@ public class VirtualInventory implements ConfigurationSerializable { * @param index The slot index * @return If there is an {@link ItemStack} on that slot */ - public boolean hasItem(int index) { + public boolean hasItemStack(int index) { return items[index] != null; } @@ -139,19 +150,20 @@ public class VirtualInventory implements ConfigurationSerializable { * @return If the action has been cancelled */ public boolean place(Player player, int index, ItemStack itemStack) { - ItemStack there = items[index]; - int currentAmount = there == null ? 0 : there.getAmount(); + ItemStack currentStack = items[index]; - ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, - currentAmount + itemStack.getAmount()); + ItemStack newStack; + if (currentStack == null) { + newStack = itemStack.clone(); + } else { + newStack = currentStack.clone(); + newStack.setAmount(newStack.getAmount() + itemStack.getAmount()); + } + ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack); if (!event.isCancelled()) { - if (there == null) { - setItem(index, itemStack); - } else { - there.setAmount(currentAmount + itemStack.getAmount()); - notifyWindows(); - } + items[index] = newStack; + notifyWindows(); return false; } @@ -169,21 +181,21 @@ public class VirtualInventory implements ConfigurationSerializable { * @return If the action has been cancelled */ public boolean placeOne(Player player, int index, ItemStack itemStack) { - ItemStack there = items[index]; - int currentAmount = there == null ? 0 : there.getAmount(); + ItemStack currentStack = items[index]; - ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, - currentAmount, currentAmount + 1); + ItemStack newStack; + if (currentStack == null) { + newStack = itemStack.clone(); + newStack.setAmount(1); + } else { + newStack = currentStack.clone(); + newStack.setAmount(newStack.getAmount() + 1); + } + ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack); if (!event.isCancelled()) { - if (there == null) { - ItemStack single = itemStack.clone(); - single.setAmount(1); - setItem(index, single); - } else { - there.setAmount(currentAmount + 1); - notifyWindows(); - } + items[index] = newStack; + notifyWindows(); return false; } @@ -198,10 +210,10 @@ public class VirtualInventory implements ConfigurationSerializable { * @param amount The new amount */ public void setAmountSilently(int index, int amount) { - ItemStack itemStack = items[index]; - if (itemStack != null) { + ItemStack currentStack = items[index]; + if (currentStack != null) { if (amount == 0) items[index] = null; - else itemStack.setAmount(amount); + else currentStack.setAmount(amount); notifyWindows(); } } @@ -215,20 +227,21 @@ public class VirtualInventory implements ConfigurationSerializable { * @return If the action has been cancelled */ public boolean setToMaxAmount(Player player, int index) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - int currentAmount = itemStack.getAmount(); - int newAmount = itemStack.getMaxStackSize(); - - ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, - currentAmount, newAmount); + ItemStack currentStack = items[index]; + if (currentStack != null) { + ItemStack newStack = currentStack.clone(); + newStack.setAmount(newStack.getMaxStackSize()); + ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack); if (!event.isCancelled()) { - itemStack.setAmount(newAmount); + items[index] = newStack; notifyWindows(); - } else return true; + + return false; + } } - return false; + + return true; } /** @@ -240,19 +253,19 @@ public class VirtualInventory implements ConfigurationSerializable { * @return If the action has been cancelled */ public boolean removeItem(Player player, int index) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - - ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, - itemStack.getAmount(), 0); + ItemStack currentStack = items[index]; + if (currentStack != null) { + ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, null); if (!event.isCancelled()) { items[index] = null; notifyWindows(); - } else return true; + + return false; + } } - return false; + return true; } /** @@ -263,22 +276,25 @@ public class VirtualInventory implements ConfigurationSerializable { * @return If the action has been cancelled */ public boolean removeOne(Player player, int index) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - int currentAmount = itemStack.getAmount(); - int newAmount = currentAmount - 1; + ItemStack currentStack = items[index]; + if (currentStack != null) { + int newAmount = currentStack.getAmount() - 1; - ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, newAmount); - - if (!event.isCancelled()) { - if (newAmount > 0) itemStack.setAmount(newAmount); - else items[index] = null; + if (newAmount > 0) { + ItemStack newStack = currentStack.clone(); + newStack.setAmount(newAmount); - notifyWindows(); - } else return true; + ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack); + if (!event.isCancelled()) { + items[index] = newStack; + notifyWindows(); + + return false; + } + } else return removeItem(player, index); } - return false; + return true; } /** @@ -289,21 +305,26 @@ public class VirtualInventory implements ConfigurationSerializable { * @return If the action has been cancelled */ public boolean removeHalf(Player player, int index) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - int currentAmount = itemStack.getAmount(); - int newAmount = itemStack.getAmount() / 2; + ItemStack currentStack = items[index]; + if (currentStack != null) { + int newAmount = currentStack.getAmount() / 2; - ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, newAmount); - - if (!event.isCancelled()) { - if (newAmount > 0) itemStack.setAmount(newAmount); - else items[index] = null; - notifyWindows(); - } else return true; + if (newAmount > 0) { + ItemStack newStack = currentStack.clone(); + newStack.setAmount(newAmount); + + ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack); + if (!event.isCancelled()) { + items[index] = newStack; + notifyWindows(); + + return false; + } + + } else return removeItem(player, index); } - return false; + return true; } /** @@ -359,10 +380,13 @@ public class VirtualInventory implements ConfigurationSerializable { int currentAmount = itemStack.getAmount(); int newAmount = currentAmount + maxAddable; - ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, newAmount); + ItemStack newStack = itemStack.clone(); + newStack.setAmount(newAmount); + ItemUpdateEvent event = createAndCallEvent(index, player, itemStack, newStack); if (!event.isCancelled()) { - itemStack.setAmount(itemStack.getAmount() + maxAddable); + items[index] = newStack; + notifyWindows(); return amount - maxAddable; } else return amount; } @@ -392,8 +416,8 @@ public class VirtualInventory implements ConfigurationSerializable { windows.forEach(window -> window.handleVirtualInventoryUpdate(this))); } - private ItemUpdateEvent createAndCallEvent(Player player, ItemStack itemStack, int index, int previousAmount, int newAmount) { - ItemUpdateEvent event = new ItemUpdateEvent(this, player, itemStack, index, previousAmount, newAmount); + private ItemUpdateEvent createAndCallEvent(int index, Player player, ItemStack previousItemStack, ItemStack newItemStack) { + ItemUpdateEvent event = new ItemUpdateEvent(this, index, player, previousItemStack, newItemStack); Bukkit.getPluginManager().callEvent(event); return event; diff --git a/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java b/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java index 2b7af58..acaf801 100644 --- a/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java +++ b/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java @@ -17,34 +17,30 @@ public class ItemUpdateEvent extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); private final VirtualInventory virtualInventory; - private final ItemStack itemStack; + private final ItemStack previousItemStack; + private final ItemStack newItemStack; private final Player player; private final int slot; - private final int previousAmount; - private final int newAmount; private boolean cancelled; /** * Creates a new {@link ItemUpdateEvent}. * - * @param virtualInventory The {@link VirtualInventory} where this action takes place. - * @param player The {@link Player} who changed the {@link ItemStack} or null - * if it wasn't a {@link Player} - * @param itemStack The {@link ItemStack} that is affected - * @param slot The slot that is affected - * @param previousAmount The previous amount of the {@link ItemStack} - * @param newAmount The amount that the {@link ItemStack} will have if the event is not being - * cancelled or -1 if not known + * @param virtualInventory The {@link VirtualInventory} where this action takes place. + * @param player The {@link Player} who changed the {@link ItemStack} or null + * if it wasn't a {@link Player} + * @param slot The slot that is affected + * @param previousItemStack The {@link ItemStack} that was there previously + * @param newItemStack The {@link ItemStack} that will be there if the event isn't cancelled */ - public ItemUpdateEvent(@NotNull VirtualInventory virtualInventory, @Nullable Player player, @NotNull ItemStack itemStack, int slot, int previousAmount, - int newAmount) { + public ItemUpdateEvent(@NotNull VirtualInventory virtualInventory, int slot, @Nullable Player player, + @Nullable ItemStack previousItemStack, @Nullable ItemStack newItemStack) { this.virtualInventory = virtualInventory; - this.player = player; - this.itemStack = itemStack; this.slot = slot; - this.previousAmount = previousAmount; - this.newAmount = newAmount; + this.player = player; + this.previousItemStack = previousItemStack; + this.newItemStack = newItemStack; } /** @@ -76,12 +72,21 @@ public class ItemUpdateEvent extends Event implements Cancellable { } /** - * Gets the {@link ItemStack} involved in this action. + * Gets the {@link ItemStack} that was there previously. * * @return The {@link ItemStack} */ - public ItemStack getItemStack() { - return itemStack; + public ItemStack getPreviousItemStack() { + return previousItemStack; + } + + /** + * The new {@link ItemStack} that will be there if the event isn't cancelled. + * + * @return The new {@link ItemStack} + */ + public ItemStack getNewItemStack() { + return newItemStack; } /** @@ -93,25 +98,6 @@ public class ItemUpdateEvent extends Event implements Cancellable { return slot; } - /** - * Gets the previous amount of the {@link ItemStack} - * - * @return The previous amount - */ - public int getPreviousAmount() { - return previousAmount; - } - - /** - * Gets the new amount of the {@link ItemStack} if the event - * isn't being cancelled or -1 if not unknown. - * - * @return The new amount - */ - public int getNewAmount() { - return newAmount; - } - @Override public boolean isCancelled() { return cancelled; diff --git a/src/main/java/de/studiocode/invui/window/Window.java b/src/main/java/de/studiocode/invui/window/Window.java index bb13555..d2e8c84 100644 --- a/src/main/java/de/studiocode/invui/window/Window.java +++ b/src/main/java/de/studiocode/invui/window/Window.java @@ -11,6 +11,7 @@ import de.studiocode.invui.window.impl.single.SimpleWindow; import org.bukkit.entity.Player; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -42,7 +43,7 @@ public interface Window extends GUIParent { GUI[] getGuis(); /** - * A method called by the {@link WindowManager} to notify the Window + * A method called by the {@link WindowManager} to notify the {@link Window} * that one of its {@link Item}s has been clicked. * * @param event The {@link InventoryClickEvent} associated with this action. @@ -50,7 +51,15 @@ public interface Window extends GUIParent { void handleClick(InventoryClickEvent event); /** - * A method called by the {@link WindowManager} to notify the Window + * A method called by the {@link WindowManager} to notify the {@link Window} + * that {@link ItemStack}s have been dragged inside it. + * + * @param event The {@link InventoryDragEvent} associated with this action. + */ + void handleDrag(InventoryDragEvent event); + + /** + * A method called by the {@link WindowManager} to notify the {@link Window} * that {@link ItemStack}s have been shift-clicked from the lower * {@link Inventory} to this {@link Window} * @@ -59,7 +68,7 @@ public interface Window extends GUIParent { void handleItemShift(InventoryClickEvent event); /** - * A method called by the {@link WindowManager} to notify the Window + * A method called by the {@link WindowManager} to notify the {@link Window} * that its underlying {@link Inventory} is being opened. * * @param event The {@link InventoryOpenEvent} associated with this action. @@ -67,7 +76,7 @@ public interface Window extends GUIParent { void handleOpen(InventoryOpenEvent event); /** - * A method called by the {@link WindowManager} to notify the Window + * A method called by the {@link WindowManager} to notify the {@link Window} * that its underlying {@link Inventory} is being closed. * * @param player The {@link Player} who closed this inventory. @@ -75,7 +84,7 @@ public interface Window extends GUIParent { void handleClose(Player player); /** - * A method called by the {@link WindowManager} to notify the Window + * A method called by the {@link WindowManager} to notify the {@link Window} * that it's viewer has died. * * @param event The {@link PlayerDeathEvent} associated with this action. @@ -83,7 +92,7 @@ public interface Window extends GUIParent { void handleViewerDeath(PlayerDeathEvent event); /** - * A method called by the {@link Item} itself to notify the Window + * A method called by the {@link Item} itself to notify the {@link Window} * that its {@link ItemBuilder} has been updated and the {@link ItemStack} * in the {@link Inventory} should be replaced. * @@ -93,7 +102,7 @@ public interface Window extends GUIParent { /** * A method called by the {@link VirtualInventory} to notify the - * Window that one if it's contents has been updated and the {@link ItemStack}'s + * {@link Window} that one if it's contents has been updated and the {@link ItemStack}'s * displayed in the {@link Inventory} should be replaced. * * @param virtualInventory The {@link VirtualInventory} @@ -155,9 +164,9 @@ public interface Window extends GUIParent { Player getCurrentViewer(); /** - * Gets the viewer's UUID or null if there is no viewer. + * Gets the viewer's {@link UUID} * - * @return The viewer's UUID or null if there is now viewer. + * @return The viewer's {@link UUID} */ UUID getViewerUUID(); diff --git a/src/main/java/de/studiocode/invui/window/WindowManager.java b/src/main/java/de/studiocode/invui/window/WindowManager.java index 73941b8..b85bfcc 100644 --- a/src/main/java/de/studiocode/invui/window/WindowManager.java +++ b/src/main/java/de/studiocode/invui/window/WindowManager.java @@ -124,8 +124,7 @@ public class WindowManager implements Listener { @EventHandler public void handleInventoryDrag(InventoryDragEvent event) { - // currently, dragging items is not supported - findWindow(event.getInventory()).ifPresent(w -> event.setCancelled(true)); + findWindow(event.getInventory()).ifPresent(window -> window.handleDrag(event)); } @EventHandler(priority = EventPriority.HIGHEST) diff --git a/src/main/java/de/studiocode/invui/window/impl/BaseWindow.java b/src/main/java/de/studiocode/invui/window/impl/BaseWindow.java index 8097f78..4e7cd99 100644 --- a/src/main/java/de/studiocode/invui/window/impl/BaseWindow.java +++ b/src/main/java/de/studiocode/invui/window/impl/BaseWindow.java @@ -2,17 +2,21 @@ package de.studiocode.invui.window.impl; import de.studiocode.inventoryaccess.api.version.InventoryAccess; import de.studiocode.invui.InvUI; +import de.studiocode.invui.gui.GUI; import de.studiocode.invui.gui.SlotElement; import de.studiocode.invui.gui.SlotElement.ItemSlotElement; import de.studiocode.invui.gui.SlotElement.VISlotElement; import de.studiocode.invui.item.Item; import de.studiocode.invui.util.ArrayUtils; +import de.studiocode.invui.util.Pair; import de.studiocode.invui.virtualinventory.VirtualInventory; import de.studiocode.invui.window.Window; import de.studiocode.invui.window.WindowManager; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.inventory.ItemStack; @@ -36,6 +40,10 @@ public abstract class BaseWindow implements Window { WindowManager.getInstance().addWindow(this); } + protected void redrawItem(int index) { + redrawItem(index, getSlotElement(index), false); + } + protected void redrawItem(int index, SlotElement element, boolean setItem) { // put ItemStack in inventory ItemStack itemStack = element == null ? null : element.getItemStack(viewerUUID); @@ -73,6 +81,36 @@ public abstract class BaseWindow implements Window { } } + @Override + public void handleDrag(InventoryDragEvent event) { + Player player = ((Player) event.getWhoClicked()).getPlayer(); + Map newItems = event.getNewItems(); + + int itemsLeft = event.getCursor() == null ? 0 : event.getCursor().getAmount(); + for (int rawSlot : event.getRawSlots()) { // loop over all affected slots + ItemStack currentStack = event.getView().getItem(rawSlot); + if (currentStack != null && currentStack.getType() == Material.AIR) currentStack = null; + + // get the GUI at that index and ask for permission to drag an Item there + Pair pair = getGuiAt(rawSlot); + if (pair != null && pair.getFirst().handleItemDrag(player, pair.getSecond(), currentStack, newItems.get(rawSlot))) { + // the drag was cancelled + int currentAmount = currentStack == null ? 0 : currentStack.getAmount(); + int newAmount = newItems.get(rawSlot).getAmount(); + + itemsLeft += newAmount - currentAmount; + + // Redraw cancelled items after the event so there won't be any Items that aren't actually there + Bukkit.getScheduler().runTask(InvUI.getInstance().getPlugin(), () -> redrawItem(rawSlot)); + } + } + + // update the amount on the cursor + ItemStack cursorStack = event.getOldCursor(); + cursorStack.setAmount(itemsLeft); + event.setCursor(cursorStack); + } + @Override public void handleOpen(InventoryOpenEvent event) { if (!event.getPlayer().equals(getViewer())) @@ -183,6 +221,10 @@ public abstract class BaseWindow implements Window { protected abstract void setInvItem(int slot, ItemStack itemStack); + protected abstract SlotElement getSlotElement(int index); + + protected abstract Pair getGuiAt(int index); + protected abstract void handleOpened(); protected abstract void handleClosed(); diff --git a/src/main/java/de/studiocode/invui/window/impl/merged/combined/CombinedWindow.java b/src/main/java/de/studiocode/invui/window/impl/merged/combined/CombinedWindow.java index 7896699..3ee08ff 100644 --- a/src/main/java/de/studiocode/invui/window/impl/merged/combined/CombinedWindow.java +++ b/src/main/java/de/studiocode/invui/window/impl/merged/combined/CombinedWindow.java @@ -44,6 +44,11 @@ public abstract class CombinedWindow extends MergedWindow { return new Pair<>(gui, clickedIndex); } + @Override + protected Pair getGuiAt(int index) { + return index < gui.getSize() ? new Pair<>(gui, index) : null; + } + @Override public GUI[] getGuis() { return new GUI[] {gui}; diff --git a/src/main/java/de/studiocode/invui/window/impl/merged/split/SplitWindow.java b/src/main/java/de/studiocode/invui/window/impl/merged/split/SplitWindow.java index a18b21c..bf98206 100644 --- a/src/main/java/de/studiocode/invui/window/impl/merged/split/SplitWindow.java +++ b/src/main/java/de/studiocode/invui/window/impl/merged/split/SplitWindow.java @@ -51,6 +51,13 @@ public abstract class SplitWindow extends MergedWindow { } } + @Override + protected Pair getGuiAt(int index) { + if (index < upperGui.getSize()) return new Pair<>(upperGui, index); + else if (index < (upperGui.getSize() + lowerGui.getSize())) return new Pair<>(lowerGui, index - upperGui.getSize()); + else return null; + } + @Override public GUI[] getGuis() { return new GUI[] {upperGui, lowerGui}; diff --git a/src/main/java/de/studiocode/invui/window/impl/single/SingleWindow.java b/src/main/java/de/studiocode/invui/window/impl/single/SingleWindow.java index 7e1ddaf..7e083a0 100644 --- a/src/main/java/de/studiocode/invui/window/impl/single/SingleWindow.java +++ b/src/main/java/de/studiocode/invui/window/impl/single/SingleWindow.java @@ -2,6 +2,7 @@ package de.studiocode.invui.window.impl.single; import de.studiocode.invui.gui.GUI; import de.studiocode.invui.gui.SlotElement; +import de.studiocode.invui.util.Pair; import de.studiocode.invui.window.Window; import de.studiocode.invui.window.impl.BaseWindow; import org.bukkit.entity.Player; @@ -63,6 +64,16 @@ public abstract class SingleWindow extends BaseWindow { gui.handleClick(event.getSlot(), (Player) event.getWhoClicked(), event.getClick(), event); } + @Override + protected Pair getGuiAt(int index) { + return index < gui.getSize() ? new Pair<>(gui, index) : null; + } + + @Override + protected SlotElement getSlotElement(int index) { + return gui.getSlotElement(index); + } + @Override public void handleItemShift(InventoryClickEvent event) { gui.handleItemShift(event);