CombinedWindow

This commit is contained in:
NichtStudioCode 2021-01-31 16:24:38 +01:00
parent e6c4af7765
commit 5eb859e6c9
19 changed files with 464 additions and 165 deletions

@ -6,7 +6,6 @@ import de.studiocode.invgui.gui.GUI;
import de.studiocode.invgui.util.SlotUtils;
import de.studiocode.invgui.window.Window;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.NotNull;
@ -14,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
@ -71,7 +71,7 @@ public abstract class BaseAnimation implements Animation {
public void start() {
task = Bukkit.getScheduler().runTaskTimer(InvGui.getInstance().getPlugin(), () -> {
// if there are no viewers for more than 3 ticks, the animation can be cancelled
if (getViewers().isEmpty()) {
if (getCurrentViewers().isEmpty()) {
noViewerTicks++;
if (noViewerTicks > 3) {
gui.cancelAnimation();
@ -120,14 +120,11 @@ public abstract class BaseAnimation implements Animation {
return height;
}
public List<Player> getViewers() {
public Set<Player> getCurrentViewers() {
return windows.stream()
.map(window -> {
List<HumanEntity> viewers = window.getInventory().getViewers();
return (Player) (viewers.isEmpty() ? null : viewers.get(0));
})
.map(Window::getCurrentViewer)
.filter(Objects::nonNull)
.collect(Collectors.toList());
.collect(Collectors.toSet());
}
}

@ -13,7 +13,7 @@ public class ColumnAnimation extends SoundAnimation {
boolean showedSomething = false;
while (!showedSomething || column == getWidth() - 1) {
for (int y = 0; y != getHeight(); y++) {
for (int y = 0; y < getHeight(); y++) {
int index = convToIndex(column, y);
if (getSlots().contains(index)) {
show(index);

@ -13,7 +13,7 @@ public class RowAnimation extends SoundAnimation {
boolean showedSomething = false;
while (!showedSomething || row == getHeight() - 1) {
for (int x = 0; x != getWidth(); x++) {
for (int x = 0; x < getWidth(); x++) {
int index = convToIndex(x, row);
if (getSlots().contains(index)) {
show(index);

@ -7,7 +7,7 @@ public abstract class SoundAnimation extends BaseAnimation {
public SoundAnimation(int tickDelay, boolean sound) {
super(tickDelay);
if (sound) addShowHandler((frame, index) -> getViewers().forEach(player ->
if (sound) addShowHandler((frame, index) -> getCurrentViewers().forEach(player ->
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, 1, 1)));
}

@ -34,7 +34,7 @@ import java.util.function.Predicate;
* @see SimplePagedItemsGUI
* @see SimplePagedGUIs
*/
public interface GUI {
public interface GUI extends GUIParent {
/**
* Gets the size of the {@link GUI}.
@ -243,7 +243,7 @@ public interface GUI {
*
* @return The list of {@link Player}s that are currently seeing this {@link Window}
*/
List<Player> findAllViewers();
Set<Player> findAllCurrentViewers();
/**
* Plays an {@link Animation}.

@ -23,8 +23,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
abstract class IndexedGUI implements GUI, GUIParent {
abstract class IndexedGUI implements GUI {
private final int size;
private final SlotElement[] slotElements;
@ -219,13 +220,11 @@ abstract class IndexedGUI implements GUI, GUIParent {
}
@Override
public List<Player> findAllViewers() {
List<Player> players = new ArrayList<>();
findAllWindows().stream()
.flatMap(window -> window.getInventory().getViewers().stream())
.forEach(humanEntity -> players.add((Player) humanEntity));
return players;
public Set<Player> findAllCurrentViewers() {
return findAllWindows().stream()
.map(Window::getCurrentViewer)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
@Override

@ -41,4 +41,14 @@ public class SlotUtils {
return y * width + x;
}
public static int translatePlayerInvToGui(int slot) {
if (slot > 8) return slot - 9;
else return slot + 27;
}
public static int translateGuiToPlayerInv(int slot) {
if (slot > 26) return slot - 27;
else return slot + 9;
}
}

@ -1,14 +1,15 @@
package de.studiocode.invgui.window;
import de.studiocode.invgui.gui.GUI;
import de.studiocode.invgui.gui.GUIParent;
import de.studiocode.invgui.item.Item;
import de.studiocode.invgui.item.itembuilder.ItemBuilder;
import de.studiocode.invgui.virtualinventory.VirtualInventory;
import de.studiocode.invgui.window.impl.BaseWindow;
import de.studiocode.invgui.window.impl.DropperWindow;
import de.studiocode.invgui.window.impl.HopperWindow;
import de.studiocode.invgui.window.impl.NormalInventoryWindow;
import de.studiocode.invgui.window.impl.combined.combinedgui.SimpleCombinedGUIWindow;
import de.studiocode.invgui.window.impl.combined.splitgui.SimpleSplitGUIWindow;
import de.studiocode.invgui.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.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
@ -20,26 +21,25 @@ import java.util.UUID;
* A window is the way to show a player a GUI.
* Windows can only have one viewer.
*
* @see BaseWindow
* @see NormalInventoryWindow
* @see HopperWindow
* @see DropperWindow
* @see SimpleWindow
* @see SimpleCombinedGUIWindow
* @see SimpleSplitGUIWindow
*/
public interface Window {
public interface Window extends GUIParent {
/**
* Gets the underlying {@link Inventory}.
* Gets the underlying {@link Inventory}s.
*
* @return The underlying {@link Inventory}.
* @return The underlying {@link Inventory}s.
*/
Inventory getInventory();
Inventory[] getInventories();
/**
* Gets the underlying {@link GUI}.
* Gets the underlying {@link GUI}s.
*
* @return The underlying {@link GUI}.
* @return The underlying {@link GUI}s.
*/
GUI getGui();
GUI[] getGuis();
/**
* A method called by the {@link WindowManager} to notify the Window
@ -72,6 +72,14 @@ public interface Window {
*/
void handleClose(Player player);
/**
* A method called by the {@link WindowManager} to notify the Window
* that it's viewer has died.
*
* @param event The {@link PlayerDeathEvent} associated with this action.
*/
void handleViewerDeath(PlayerDeathEvent event);
/**
* A method called by the {@link Item} itself to notify the Window
* that its {@link ItemBuilder} has been updated and the {@link ItemStack}
@ -132,10 +140,18 @@ public interface Window {
/**
* Gets the viewer of this {@link Window}
*
* @return The viewer of this window, can be null.
* @return The viewer of this window.
*/
Player getViewer();
/**
* Gets a the current {@link Player} that is viewing this
* {@link Window} or null of there isn't one.
*
* @return The current viewer of this {@link Window} (can be null)
*/
Player getCurrentViewer();
/**
* Gets the viewer's UUID or null if there is no viewer.
*

@ -6,11 +6,13 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
@ -27,7 +29,7 @@ public class WindowManager implements Listener {
private WindowManager() {
Bukkit.getPluginManager().registerEvents(this, InvGui.getInstance().getPlugin());
InvGui.getInstance().addDisableHandler(() -> windows.forEach(w -> w.close(true)));
InvGui.getInstance().addDisableHandler(() -> windows.forEach(window -> window.close(true)));
}
/**
@ -67,7 +69,7 @@ public class WindowManager implements Listener {
*/
public Optional<Window> findWindow(Inventory inventory) {
return windows.stream()
.filter(w -> w.getInventory() == inventory)
.filter(w -> Arrays.stream(w.getInventories()).anyMatch(inv -> inv == inventory))
.findFirst();
}
@ -87,13 +89,12 @@ public class WindowManager implements Listener {
* Finds the {@link Window} the {@link Player} has currently open.
*
* @param player The {@link Player}
* @return The {@link Window} the {@link Player} has currently open or <code>null</code>
* if there isn't one.
* @return The {@link Window} the {@link Player} has currently open
*/
public Window findWindow(Player player) {
public Optional<Window> findOpenWindow(Player player) {
return windows.stream()
.filter(w -> w.getInventory().getViewers().contains(player))
.findFirst().orElse(null);
.filter(w -> w.getCurrentViewer().equals(player))
.findFirst();
}
/**
@ -139,4 +140,9 @@ public class WindowManager implements Listener {
findWindow(event.getPlayer().getOpenInventory().getTopInventory()).ifPresent(window -> window.handleClose(event.getPlayer()));
}
@EventHandler
public void handlePlayerDeath(PlayerDeathEvent event) {
findWindows(event.getEntity()).forEach(window -> window.handleViewerDeath(event));
}
}

@ -1,8 +1,6 @@
package de.studiocode.invgui.window.impl;
import de.studiocode.invgui.InvGui;
import de.studiocode.invgui.gui.GUI;
import de.studiocode.invgui.gui.GUIParent;
import de.studiocode.invgui.gui.SlotElement.ItemSlotElement;
import de.studiocode.invgui.gui.SlotElement.ItemStackHolder;
import de.studiocode.invgui.gui.SlotElement.VISlotElement;
@ -14,50 +12,33 @@ import de.studiocode.invgui.window.WindowManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.*;
public abstract class BaseWindow implements Window, GUIParent {
public abstract class BaseWindow implements Window {
private final GUI gui;
private final int size;
private final UUID viewerUUID;
private final Inventory inventory;
private final boolean closeOnEvent;
private final ItemStackHolder[] itemsDisplayed;
private boolean closeable;
private boolean closed;
public BaseWindow(UUID viewerUUID, GUI gui, Inventory inventory, boolean closeable, boolean closeOnEvent) {
this.gui = gui;
this.size = gui.getSize();
public BaseWindow(UUID viewerUUID, int size, boolean closeable, boolean closeOnEvent) {
this.viewerUUID = viewerUUID;
this.inventory = inventory;
this.closeable = closeable;
this.closeOnEvent = closeOnEvent;
this.itemsDisplayed = new ItemStackHolder[size];
gui.addParent(this);
initItems();
WindowManager.getInstance().addWindow(this);
}
private void initItems() {
for (int i = 0; i < size; i++) {
ItemStackHolder holder = gui.getItemStackHolder(i);
if (holder != null) redrawItem(i, holder, true);
}
}
private void redrawItem(int index, ItemStackHolder holder, boolean setItem) {
protected void redrawItem(int index, ItemStackHolder holder, boolean setItem) {
// put ItemStack in inventory
ItemStack itemStack = holder == null ? null : holder.getItemStack(viewerUUID);
inventory.setItem(index, itemStack);
setInvItem(index, itemStack);
if (setItem) {
// tell the previous item (if there is one) that this is no longer its window
@ -91,35 +72,22 @@ public abstract class BaseWindow implements Window, GUIParent {
}
}
@Override
public void handleSlotElementUpdate(GUI child, int slotIndex) {
redrawItem(slotIndex, gui.getItemStackHolder(slotIndex), true);
}
@Override
public void handleClick(InventoryClickEvent event) {
gui.handleClick(event.getSlot(), (Player) event.getWhoClicked(), event.getClick(), event);
}
@Override
public void handleItemShift(InventoryClickEvent event) {
gui.handleItemShift(event);
}
@Override
public void handleOpen(InventoryOpenEvent event) {
if (!event.getPlayer().equals(getViewer()))
event.setCancelled(true);
else handleOpened();
}
@Override
public void handleClose(Player player) {
if (closeable) {
if (closeOnEvent) close(false);
handleClosed();
} else {
if (player.equals(getViewer()))
Bukkit.getScheduler().runTaskLater(InvGui.getInstance().getPlugin(),
() -> player.openInventory(inventory), 0);
() -> player.openInventory(getInventories()[0]), 0);
}
}
@ -135,12 +103,12 @@ public abstract class BaseWindow implements Window, GUIParent {
redrawItem(index, slotElement, false));
}
private Map<Integer, ItemStackHolder> getItemSlotElements(Item item) {
protected Map<Integer, ItemStackHolder> getItemSlotElements(Item item) {
return ArrayUtils.findAllOccurrences(itemsDisplayed, holder -> holder instanceof ItemSlotElement
&& ((ItemSlotElement) holder).getItem() == item);
}
private Map<Integer, ItemStackHolder> getVISlotElements(VirtualInventory virtualInventory) {
protected Map<Integer, ItemStackHolder> getVISlotElements(VirtualInventory virtualInventory) {
return ArrayUtils.findAllOccurrences(itemsDisplayed, holder -> holder instanceof VISlotElement
&& ((VISlotElement) holder).getVirtualInventory() == virtualInventory);
}
@ -157,7 +125,8 @@ public abstract class BaseWindow implements Window, GUIParent {
.map(holder -> ((ItemSlotElement) holder).getItem())
.forEach(item -> item.removeWindow(this));
gui.removeParent(this);
Arrays.stream(getGuis())
.forEach(gui -> gui.removeParent(this));
if (closeForViewer) closeForViewer();
}
@ -166,7 +135,9 @@ public abstract class BaseWindow implements Window, GUIParent {
public void closeForViewer() {
closeable = true;
// clone list to prevent ConcurrentModificationException
new ArrayList<>(inventory.getViewers()).forEach(HumanEntity::closeInventory);
new ArrayList<>(getInventories()[0].getViewers()).forEach(HumanEntity::closeInventory);
handleClosed();
}
@Override
@ -175,7 +146,13 @@ public abstract class BaseWindow implements Window, GUIParent {
Player viewer = getViewer();
if (viewer == null) throw new IllegalStateException("The player is not online.");
viewer.openInventory(inventory);
viewer.openInventory(getInventories()[0]);
}
@Override
public Player getCurrentViewer() {
List<HumanEntity> viewers = getInventories()[0].getViewers();
return viewers.isEmpty() ? null : (Player) viewers.get(0);
}
@Override
@ -188,16 +165,6 @@ public abstract class BaseWindow implements Window, GUIParent {
return viewerUUID;
}
@Override
public Inventory getInventory() {
return inventory;
}
@Override
public GUI getGui() {
return gui;
}
@Override
public boolean isCloseable() {
return closeable;
@ -213,4 +180,10 @@ public abstract class BaseWindow implements Window, GUIParent {
return closed;
}
protected abstract void setInvItem(int slot, ItemStack itemStack);
protected abstract void handleOpened();
protected abstract void handleClosed();
}

@ -1,27 +0,0 @@
package de.studiocode.invgui.window.impl;
import de.studiocode.invgui.gui.GUI;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import java.util.UUID;
public class DropperWindow extends BaseWindow {
public DropperWindow(UUID viewerUUID, GUI gui, String title, boolean closeable, boolean closeOnEvent) {
super(viewerUUID, gui, createInventory(gui, title), closeable, closeOnEvent);
}
public DropperWindow(Player player, GUI gui, String title, boolean closeable, boolean closeOnEvent) {
this(player.getUniqueId(), gui, title, closeable, closeOnEvent);
}
private static Inventory createInventory(GUI gui, String title) {
if (gui.getWidth() != 3 || gui.getHeight() != 3)
throw new IllegalArgumentException("GUI width and height have to be 3.");
return Bukkit.createInventory(null, InventoryType.DROPPER, title);
}
}

@ -1,27 +0,0 @@
package de.studiocode.invgui.window.impl;
import de.studiocode.invgui.gui.GUI;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import java.util.UUID;
public class HopperWindow extends BaseWindow {
public HopperWindow(UUID viewerUUID, GUI gui, String title, boolean closeable, boolean closeOnEvent) {
super(viewerUUID, gui, createInventory(gui, title), closeable, closeOnEvent);
}
public HopperWindow(Player player, GUI gui, String title, boolean closeable, boolean closeOnEvent) {
this(player.getUniqueId(), gui, title, closeable, closeOnEvent);
}
private static Inventory createInventory(GUI gui, String title) {
if (gui.getWidth() != 5 || gui.getHeight() != 1)
throw new IllegalArgumentException("GUI width has to be 5, height 1.");
return Bukkit.createInventory(null, InventoryType.HOPPER, title);
}
}

@ -0,0 +1,125 @@
package de.studiocode.invgui.window.impl.combined;
import de.studiocode.invgui.gui.SlotElement.ItemStackHolder;
import de.studiocode.invgui.gui.SlotElement.VISlotElement;
import de.studiocode.invgui.util.SlotUtils;
import de.studiocode.invgui.window.impl.BaseWindow;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public abstract class BaseCombinedWindow extends BaseWindow {
private final Inventory upperInventory;
private final Inventory playerInventory;
private final ItemStack[] playerItems = new ItemStack[36];
private boolean isCurrentlyOpened;
public BaseCombinedWindow(Player player, int size, Inventory upperInventory, boolean closeable, boolean closeOnEvent) {
super(player.getUniqueId(), size, closeable, closeOnEvent);
this.upperInventory = upperInventory;
this.playerInventory = player.getInventory();
}
protected void initUpperItems() {
for (int i = 0; i < upperInventory.getSize(); i++) {
ItemStackHolder holder = getItemStackHolder(i);
if (holder != null) redrawItem(i, holder, true);
}
}
private void initPlayerItems() {
for (int i = upperInventory.getSize(); i < upperInventory.getSize() + 36; i++) {
ItemStackHolder holder = getItemStackHolder(i);
if (holder != null) redrawItem(i, holder, true);
}
}
private void clearPlayerInventory() {
Inventory inventory = getViewer().getInventory();
for (int i = 0; i < 36; i++) {
playerItems[i] = inventory.getItem(i);
inventory.setItem(i, null);
}
}
private void restorePlayerInventory() {
Inventory inventory = getViewer().getInventory();
for (int i = 0; i < 36; i++) {
inventory.setItem(i, playerItems[i]);
}
}
@Override
protected void redrawItem(int index, ItemStackHolder holder, boolean setItem) {
if (holder instanceof VISlotElement)
throw new IllegalArgumentException("VirtualInventories are not allowed in CombinedWindows");
super.redrawItem(index, holder, setItem);
}
@Override
protected void setInvItem(int slot, ItemStack itemStack) {
if (slot >= upperInventory.getSize()) {
if (isCurrentlyOpened) {
int invSlot = SlotUtils.translateGuiToPlayerInv(slot - upperInventory.getSize());
playerInventory.setItem(invSlot, itemStack);
}
} else upperInventory.setItem(slot, itemStack);
}
@Override
public void handleViewerDeath(PlayerDeathEvent event) {
if (isCurrentlyOpened) {
List<ItemStack> drops = event.getDrops();
if (!event.getKeepInventory()) {
drops.clear();
Arrays.stream(playerItems)
.filter(Objects::nonNull)
.forEach(drops::add);
}
}
}
@Override
protected void handleOpened() {
isCurrentlyOpened = true;
clearPlayerInventory();
initPlayerItems();
}
@Override
protected void handleClosed() {
isCurrentlyOpened = false;
restorePlayerInventory();
}
@Override
public void handleItemShift(InventoryClickEvent event) {
event.setCancelled(true);
}
@Override
public Inventory[] getInventories() {
return isCurrentlyOpened ? new Inventory[] {upperInventory, playerInventory} : new Inventory[] {upperInventory};
}
public Inventory getUpperInventory() {
return upperInventory;
}
public Inventory getPlayerInventory() {
return playerInventory;
}
protected abstract ItemStackHolder getItemStackHolder(int index);
}

@ -0,0 +1,47 @@
package de.studiocode.invgui.window.impl.combined.combinedgui;
import de.studiocode.invgui.gui.GUI;
import de.studiocode.invgui.gui.SlotElement.ItemStackHolder;
import de.studiocode.invgui.util.SlotUtils;
import de.studiocode.invgui.window.impl.combined.BaseCombinedWindow;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
public abstract class CombinedGUIWindow extends BaseCombinedWindow {
private final GUI gui;
public CombinedGUIWindow(Player player, GUI gui, Inventory upperInventory, boolean closeable, boolean closeOnEvent) {
super(player, gui.getSize(), upperInventory, closeable, closeOnEvent);
this.gui = gui;
gui.addParent(this);
initUpperItems();
}
@Override
public void handleSlotElementUpdate(GUI child, int slotIndex) {
redrawItem(slotIndex, gui.getItemStackHolder(slotIndex), true);
}
@Override
public void handleClick(InventoryClickEvent event) {
Inventory clicked = event.getClickedInventory();
int guiSlot = clicked == getUpperInventory() ? event.getSlot()
: getUpperInventory().getSize() + SlotUtils.translatePlayerInvToGui(event.getSlot());
gui.handleClick(guiSlot, (Player) event.getWhoClicked(), event.getClick(), event);
}
@Override
protected ItemStackHolder getItemStackHolder(int index) {
return gui.getItemStackHolder(index);
}
@Override
public GUI[] getGuis() {
return new GUI[] {gui};
}
}

@ -0,0 +1,23 @@
package de.studiocode.invgui.window.impl.combined.combinedgui;
import de.studiocode.invgui.gui.GUI;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
public class SimpleCombinedGUIWindow extends CombinedGUIWindow {
public SimpleCombinedGUIWindow(Player player, String title, GUI gui, boolean closeable, boolean closeOnEvent) {
super(player, gui, createInventory(gui, title), closeable, closeOnEvent);
}
private static Inventory createInventory(GUI gui, String title) {
if (gui.getWidth() != 9)
throw new IllegalArgumentException("GUI width has to be 9");
if (gui.getHeight() <= 4)
throw new IllegalArgumentException("GUI height has to be bigger than 4");
return Bukkit.createInventory(null, gui.getSize() - 36, title);
}
}

@ -0,0 +1,21 @@
package de.studiocode.invgui.window.impl.combined.splitgui;
import de.studiocode.invgui.gui.GUI;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
public class SimpleSplitGUIWindow extends SplitGUIWindow {
public SimpleSplitGUIWindow(Player player, String title, GUI upperGui, GUI lowerGui, boolean closeable, boolean closeOnEvent) {
super(player, upperGui, lowerGui, createInventory(upperGui, title), closeable, closeOnEvent);
}
private static Inventory createInventory(GUI gui, String title) {
if (gui.getWidth() != 9)
throw new IllegalArgumentException("GUI width has to be 9");
return Bukkit.createInventory(null, gui.getSize(), title);
}
}

@ -0,0 +1,54 @@
package de.studiocode.invgui.window.impl.combined.splitgui;
import de.studiocode.invgui.gui.GUI;
import de.studiocode.invgui.gui.SlotElement.ItemStackHolder;
import de.studiocode.invgui.util.SlotUtils;
import de.studiocode.invgui.window.impl.combined.BaseCombinedWindow;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
public abstract class SplitGUIWindow extends BaseCombinedWindow {
private final GUI upperGui;
private final GUI lowerGui;
public SplitGUIWindow(Player player, GUI upperGui, GUI lowerGui, Inventory upperInventory, boolean closeable, boolean closeOnEvent) {
super(player, upperGui.getSize() + lowerGui.getSize(), upperInventory, closeable, closeOnEvent);
this.upperGui = upperGui;
this.lowerGui = lowerGui;
upperGui.addParent(this);
lowerGui.addParent(this);
initUpperItems();
}
@Override
public void handleSlotElementUpdate(GUI child, int slotIndex) {
redrawItem(child == upperGui ? slotIndex : upperGui.getSize() + slotIndex,
child.getItemStackHolder(slotIndex), true);
}
@Override
public void handleClick(InventoryClickEvent event) {
Inventory clicked = event.getClickedInventory();
if (clicked == getUpperInventory()) {
upperGui.handleClick(event.getSlot(), (Player) event.getWhoClicked(), event.getClick(), event);
} else {
int index = SlotUtils.translatePlayerInvToGui(event.getSlot());
lowerGui.handleClick(index, (Player) event.getWhoClicked(), event.getClick(), event);
}
}
@Override
public ItemStackHolder getItemStackHolder(int index) {
if (index >= upperGui.getSize()) return lowerGui.getItemStackHolder(index - upperGui.getSize());
else return upperGui.getItemStackHolder(index);
}
@Override
public GUI[] getGuis() {
return new GUI[] {upperGui, lowerGui};
}
}

@ -1,4 +1,4 @@
package de.studiocode.invgui.window.impl;
package de.studiocode.invgui.window.impl.single;
import de.studiocode.invgui.gui.GUI;
import org.bukkit.Bukkit;
@ -7,14 +7,14 @@ import org.bukkit.inventory.Inventory;
import java.util.UUID;
public final class NormalInventoryWindow extends BaseWindow {
public final class SimpleWindow extends SingleWindow {
public NormalInventoryWindow(UUID viewerUUID, GUI gui, String title, boolean closeable, boolean closeOnEvent) {
public SimpleWindow(UUID viewerUUID, String title, GUI gui, boolean closeable, boolean closeOnEvent) {
super(viewerUUID, gui, createInventory(gui, title), closeable, closeOnEvent);
}
public NormalInventoryWindow(Player player, GUI gui, String title, boolean closeable, boolean closeOnEvent) {
this(player.getUniqueId(), gui, title, closeable, closeOnEvent);
public SimpleWindow(Player player, String title, GUI gui, boolean closeable, boolean closeOnEvent) {
this(player.getUniqueId(), title, gui, closeable, closeOnEvent);
}
private static Inventory createInventory(GUI gui, String title) {

@ -0,0 +1,82 @@
package de.studiocode.invgui.window.impl.single;
import de.studiocode.invgui.gui.GUI;
import de.studiocode.invgui.gui.SlotElement.ItemStackHolder;
import de.studiocode.invgui.window.impl.BaseWindow;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
public abstract class SingleWindow extends BaseWindow {
private final GUI gui;
private final int size;
private final Inventory inventory;
public SingleWindow(UUID viewerUUID, GUI gui, Inventory inventory, boolean closeable, boolean closeOnEvent) {
super(viewerUUID, gui.getSize(), closeable, closeOnEvent);
this.gui = gui;
this.size = gui.getSize();
this.inventory = inventory;
gui.addParent(this);
initItems();
}
private void initItems() {
for (int i = 0; i < size; i++) {
ItemStackHolder holder = gui.getItemStackHolder(i);
if (holder != null) redrawItem(i, holder, true);
}
}
@Override
protected void setInvItem(int slot, ItemStack itemStack) {
inventory.setItem(slot, itemStack);
}
@Override
protected void handleOpened() {
// empty
}
@Override
protected void handleClosed() {
// empty
}
@Override
public void handleSlotElementUpdate(GUI child, int slotIndex) {
redrawItem(slotIndex, gui.getItemStackHolder(slotIndex), true);
}
@Override
public void handleClick(InventoryClickEvent event) {
gui.handleClick(event.getSlot(), (Player) event.getWhoClicked(), event.getClick(), event);
}
@Override
public void handleItemShift(InventoryClickEvent event) {
gui.handleItemShift(event);
}
@Override
public void handleViewerDeath(PlayerDeathEvent event) {
// empty
}
@Override
public Inventory[] getInventories() {
return new Inventory[] {inventory};
}
@Override
public GUI[] getGuis() {
return new GUI[] {gui};
}
}