166 lines
3.8 KiB
Java
166 lines
3.8 KiB
Java
package com.songoda.epicheads.menu.ui;
|
|
|
|
import com.songoda.epicheads.EpicHeads;
|
|
import com.songoda.epicheads.menu.ui.element.Container;
|
|
import com.songoda.epicheads.menu.ui.element.Element;
|
|
import com.songoda.epicheads.menu.ui.item.Button;
|
|
import com.songoda.epicheads.util.Checks;
|
|
import com.songoda.epicheads.util.Stringify;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
import org.bukkit.inventory.Inventory;
|
|
import org.bukkit.inventory.InventoryHolder;
|
|
import org.bukkit.inventory.InventoryView;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
public class InventoryMenu implements InventoryHolder {
|
|
|
|
private final Player player;
|
|
public final Bounds bounds;
|
|
|
|
private final List<Element> elements = new ArrayList<>();
|
|
|
|
private Container container;
|
|
private Inventory inventory;
|
|
private String title;
|
|
private Inventory newInventory;
|
|
private String newTitle;
|
|
|
|
public InventoryMenu(Player player, String title, int rows) {
|
|
Checks.ensureNonNull(player, "player");
|
|
|
|
this.player = player;
|
|
this.bounds = new Bounds(Position.ZERO, 9, rows);
|
|
this.container = new Container(bounds);
|
|
|
|
setTitle(title);
|
|
}
|
|
|
|
public Player getPlayer() {
|
|
return player;
|
|
}
|
|
|
|
@Override
|
|
public Inventory getInventory() {
|
|
return inventory;
|
|
}
|
|
|
|
public boolean hasMenuOpen() {
|
|
InventoryView view = player.getOpenInventory();
|
|
|
|
if (view == null || view.getTopInventory() == null)
|
|
return false;
|
|
|
|
InventoryHolder holder = view.getTopInventory().getHolder();
|
|
|
|
return holder != null && holder.equals(this);
|
|
}
|
|
|
|
public void removeElement(Element element) {
|
|
Checks.ensureNonNull(element, "element");
|
|
|
|
elements.remove(element);
|
|
}
|
|
|
|
public void addElement(Element element) {
|
|
Checks.ensureNonNull(element, "element");
|
|
Checks.ensureTrue(bounds.inBounds(element.bounds), "element's bounds is not within the bounds of the menu");
|
|
|
|
elements.add(element);
|
|
}
|
|
|
|
public List<Element> getElements() {
|
|
return elements;
|
|
}
|
|
|
|
public void open() {
|
|
updateMenu();
|
|
player.openInventory(inventory);
|
|
}
|
|
|
|
public void setTitle(String title) {
|
|
Checks.ensureNonNull(title, "title");
|
|
|
|
if (inventory != null && title.equals(this.title))
|
|
return;
|
|
|
|
title = (title.length() > 32 ? title.substring(0, 32) : title);
|
|
this.title = title;
|
|
|
|
this.newInventory = Bukkit.createInventory(this, bounds.getVolume(), title);
|
|
}
|
|
|
|
private boolean swapToNewInventory() {
|
|
if (newInventory == null)
|
|
return false;
|
|
|
|
inventory = newInventory;
|
|
title = newTitle;
|
|
newInventory = null;
|
|
|
|
return true;
|
|
}
|
|
|
|
public void layoutElements() {
|
|
container.clear();
|
|
|
|
elements.forEach(container::addElement);
|
|
}
|
|
|
|
public void updateMenu() {
|
|
boolean newInventory = swapToNewInventory();
|
|
|
|
layoutElements();
|
|
|
|
Button[] items = container.getItems();
|
|
ItemStack[] contents = new ItemStack[items.length];
|
|
|
|
for (int index = 0; index < contents.length; index++) {
|
|
Button item = items[index];
|
|
|
|
if (item != null) {
|
|
contents[index] = item.getItem();
|
|
}
|
|
}
|
|
|
|
inventory.setContents(contents);
|
|
|
|
if (newInventory && hasMenuOpen()) {
|
|
player.openInventory(inventory);
|
|
}
|
|
}
|
|
|
|
public void onClick(InventoryClickEvent event) {
|
|
event.setCancelled(true);
|
|
|
|
// Make sure the player's inventory is up to date after the event is cancelled
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHeads.getInstance(), player::updateInventory, 1);
|
|
|
|
int slot = event.getRawSlot();
|
|
|
|
MenuResponse response = container.handleClick(slot);
|
|
|
|
switch (response) {
|
|
case CLOSE:
|
|
player.closeInventory();
|
|
break;
|
|
case UPDATE:
|
|
updateMenu();
|
|
break;
|
|
case NONE:
|
|
break;
|
|
default:
|
|
throw new IllegalStateException("Unknown MenuResponse value " + response);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return Stringify.builder().previous(super.toString()).entry("inventory", inventory).entry("player", player).toString();
|
|
}
|
|
|
|
} |