mirror of
https://github.com/zDevelopers/ImageOnMap.git
synced 2024-11-29 05:26:18 +01:00
Separated the Inventory GUI from the common GUI.
* NEW: Added new InventoryGui class. This class only manages inventory-based GUI. * NEW: Gui: Added the registerListener() method, which allows any Gui subclass to lazily register their own GUI Listeners.
This commit is contained in:
parent
f29e972be6
commit
48dbdbd9d4
@ -20,7 +20,6 @@ package fr.moribus.imageonmap.gui.list;
|
||||
|
||||
import fr.moribus.imageonmap.gui.core.AbstractGui;
|
||||
import fr.moribus.imageonmap.gui.core.GuiManager;
|
||||
import fr.moribus.imageonmap.guiproko.core.Gui;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.moribus.imageonmap.ui.MapItemManager;
|
||||
|
@ -39,7 +39,7 @@ import java.util.*;
|
||||
*
|
||||
* @author ProkopyL (main) and Amaury Carrade
|
||||
*/
|
||||
abstract public class ActionGui extends Gui
|
||||
abstract public class ActionGui extends InventoryGui
|
||||
{
|
||||
/**
|
||||
* The prefix for action handlers.
|
||||
|
@ -18,109 +18,45 @@
|
||||
|
||||
package fr.moribus.imageonmap.guiproko.core;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.*;
|
||||
import org.bukkit.event.inventory.*;
|
||||
import org.bukkit.inventory.*;
|
||||
import org.bukkit.plugin.*;
|
||||
import fr.moribus.imageonmap.PluginLogger;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.HashMap;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class provides the basic needs for chest-type GUIs.
|
||||
* It allows you to create custom GUIs by simply providing an inventory
|
||||
* to fill, as well as rerouting basic events to it.
|
||||
*/
|
||||
abstract public class Gui
|
||||
{
|
||||
static protected final int INVENTORY_ROW_SIZE = 9;
|
||||
static protected final int MAX_INVENTORY_COLUMN_SIZE = 6;
|
||||
static protected final int MAX_INVENTORY_SIZE = INVENTORY_ROW_SIZE * MAX_INVENTORY_COLUMN_SIZE;
|
||||
|
||||
/**
|
||||
* The player this Gui instance is associated to.
|
||||
*/
|
||||
private Player player;
|
||||
|
||||
/**
|
||||
* The size of the inventory.
|
||||
*/
|
||||
private int size = 0;
|
||||
|
||||
/**
|
||||
* The title of the inventory.
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* The current Bukkit inventory.
|
||||
*/
|
||||
private Inventory inventory;
|
||||
|
||||
/**
|
||||
* If the inventory is currently open.
|
||||
*/
|
||||
private boolean open = false;
|
||||
|
||||
|
||||
private void open(Player player)
|
||||
{
|
||||
this.player = player;
|
||||
openGuis.put(player, this);
|
||||
this.update();
|
||||
player.openInventory(inventory);
|
||||
this.open = true;
|
||||
}
|
||||
|
||||
|
||||
/* ===== Public API ===== */
|
||||
|
||||
/**
|
||||
* Asks the GUI to update its data, and refresh its view accordingly.
|
||||
* The inventory may be regenerated when calling this method.
|
||||
*/
|
||||
public void update()
|
||||
{
|
||||
onUpdate();
|
||||
onAfterUpdate();
|
||||
|
||||
//If inventory does not need to be regenerated
|
||||
if(inventory != null && inventory.getTitle().equals(title) && inventory.getSize() == size)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
inventory = Bukkit.createInventory(player, size, title);
|
||||
populate(inventory);
|
||||
|
||||
if(isOpen()) // Reopening the inventory
|
||||
{
|
||||
player.closeInventory();
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the GUI to recreate its view.
|
||||
* The inventory is cleared, but never regenerated when calling this method.
|
||||
*/
|
||||
public void refresh()
|
||||
{
|
||||
inventory.clear();
|
||||
populate(inventory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this inventory.
|
||||
*/
|
||||
public void close()
|
||||
{
|
||||
this.open = false;
|
||||
player.closeInventory();
|
||||
openGuis.remove(player);
|
||||
setClosed();
|
||||
}
|
||||
|
||||
|
||||
/* ===== Public API ===== */
|
||||
|
||||
/**
|
||||
* Asks the GUI to update its data, and refresh its view accordingly.
|
||||
*/
|
||||
public void update()
|
||||
{
|
||||
onUpdate();
|
||||
onAfterUpdate();
|
||||
}
|
||||
|
||||
/* ===== Protected API ===== */
|
||||
@ -137,108 +73,30 @@ abstract public class Gui
|
||||
*/
|
||||
protected void onAfterUpdate() {}
|
||||
|
||||
/**
|
||||
* Called when the inventory needs to be (re)populated.
|
||||
*
|
||||
* @param inventory The inventory to populate
|
||||
*/
|
||||
abstract protected void populate(Inventory inventory);
|
||||
|
||||
/**
|
||||
* Raised when an action is performed on an item in the inventory.
|
||||
*
|
||||
* @param event The click event data.
|
||||
*/
|
||||
abstract protected void onClick(InventoryClickEvent event);
|
||||
|
||||
|
||||
/**
|
||||
* Raised when an drag is performed on the inventory.
|
||||
* The default behaviour is to cancel any event that affects the GUI.
|
||||
*
|
||||
* @param event The drag event data.
|
||||
*/
|
||||
protected void onDrag(InventoryDragEvent event)
|
||||
protected final void setClosed()
|
||||
{
|
||||
if(affectsGui(event)) event.setCancelled(true);
|
||||
if(open == false) return;
|
||||
open = false;
|
||||
openGuis.remove(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given event affects the GUI's inventory.
|
||||
*
|
||||
* @param event The event to test
|
||||
* @return {@code true} if the event's slot is in the GUI's inventory,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
static protected boolean affectsGui(InventoryClickEvent event)
|
||||
protected void open(Player player)
|
||||
{
|
||||
return event.getRawSlot() < event.getInventory().getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given event affects the GUI's inventory.
|
||||
*
|
||||
* @param event The event to test
|
||||
* @return true if any of the event's slots is in the GUI's inventory,
|
||||
* false otherwise.
|
||||
*/
|
||||
static protected boolean affectsGui(InventoryDragEvent event)
|
||||
{
|
||||
for(int slot : event.getRawSlots())
|
||||
{
|
||||
if(slot < event.getInventory().getSize())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
this.player = player;
|
||||
openGuis.put(player, this);
|
||||
update();
|
||||
open = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Raised when the GUI is being closed.
|
||||
* Use this method to cleanup data.
|
||||
*/
|
||||
protected void onClose() {}
|
||||
|
||||
|
||||
/* ===== Getters & Setters ===== */
|
||||
|
||||
/** @return If the GUI is currently open or not. */
|
||||
public boolean isOpen() { return open; }
|
||||
public final boolean isOpen() { return open; }
|
||||
|
||||
/** @return The player this Gui instance is associated to. */
|
||||
protected Player getPlayer() { return player; }
|
||||
protected final Player getPlayer() { return player; }
|
||||
|
||||
/** @return The size of the inventory. */
|
||||
protected int getSize() { return size; }
|
||||
|
||||
/**
|
||||
* Sets the new size of the inventory.
|
||||
* The given value is raised to be a multiple of the size of an inventory's
|
||||
* row, and is capped to the maximal size of an inventory.
|
||||
* It will be applied on the next GUI update.
|
||||
* @param size The new size of the inventory.
|
||||
*/
|
||||
protected void setSize(int size)
|
||||
{
|
||||
this.size = Math.min(((int)(Math.ceil((double) size / INVENTORY_ROW_SIZE))) * INVENTORY_ROW_SIZE, MAX_INVENTORY_SIZE);
|
||||
}
|
||||
|
||||
/** @return The title of the inventory. */
|
||||
protected String getTitle() { return title; }
|
||||
|
||||
/**
|
||||
* Sets the new title of the inventory.
|
||||
* It will be applied on the next GUI update.
|
||||
* @param title The new title of the inventory
|
||||
*/
|
||||
protected void setTitle(String title){this.title = title;}
|
||||
|
||||
/** @return The underlying inventory, or null if the Gui has not been opened yet. */
|
||||
public Inventory getInventory() { return inventory; }
|
||||
|
||||
|
||||
/* ===== Static API ===== */
|
||||
|
||||
/**
|
||||
@ -248,20 +106,25 @@ abstract public class Gui
|
||||
static private HashMap<Player, Gui> openGuis = null;
|
||||
|
||||
/**
|
||||
* The Bukkit listener for all GUI-related events.
|
||||
* A map of all the currently registered GUIs listeners.
|
||||
*/
|
||||
static private GuiListener listener = null;
|
||||
static private HashMap<Class<? extends Listener>, Listener> guiListeners = null;
|
||||
|
||||
/**
|
||||
* The plugin that uses the GUI API.
|
||||
*/
|
||||
static private Plugin plugin = null;
|
||||
|
||||
/**
|
||||
* Initializes the GUI listeners.
|
||||
* This method must be called on plugin enabling.
|
||||
* @param plugin The plugin the GUI listeners will be registered on
|
||||
*/
|
||||
static public void init(Plugin plugin)
|
||||
static public final void init(Plugin plugin)
|
||||
{
|
||||
openGuis = new HashMap<>();
|
||||
listener = new GuiListener();
|
||||
plugin.getServer().getPluginManager().registerEvents(listener, plugin);
|
||||
guiListeners = new HashMap<>();
|
||||
Gui.plugin = plugin;
|
||||
GuiUtils.init();
|
||||
}
|
||||
|
||||
@ -269,11 +132,31 @@ abstract public class Gui
|
||||
* Cleans up the GUI states.
|
||||
* This method must be called on plugin disabling.
|
||||
*/
|
||||
static public void exit()
|
||||
static public final void exit()
|
||||
{
|
||||
openGuis.clear();
|
||||
guiListeners.clear();
|
||||
openGuis = null;
|
||||
listener = null;
|
||||
guiListeners = null;
|
||||
}
|
||||
|
||||
static protected final void registerListener(Class<? extends Listener> listenerClass)
|
||||
{
|
||||
if(guiListeners == null || guiListeners.containsKey(listenerClass))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Constructor<? extends Listener> constructor = listenerClass.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
Listener listener = constructor.newInstance();
|
||||
guiListeners.put(listenerClass, listener);
|
||||
plugin.getServer().getPluginManager().registerEvents(listener, plugin);
|
||||
}
|
||||
catch(Throwable ex)
|
||||
{
|
||||
PluginLogger.error("Could not register listener for GUI", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -283,7 +166,7 @@ abstract public class Gui
|
||||
* @param gui The GUI.
|
||||
* @return The opened GUI.
|
||||
*/
|
||||
static public <T extends Gui> T open(Player owner, T gui)
|
||||
static public final <T extends Gui> T open(Player owner, T gui)
|
||||
{
|
||||
close(owner);
|
||||
((Gui)gui).open(owner);/* JAVA GENERICS Y U NO WORK */
|
||||
@ -295,51 +178,22 @@ abstract public class Gui
|
||||
* Closes any open GUI for a given player.
|
||||
* @param owner The player.
|
||||
*/
|
||||
static public void close(Player owner)
|
||||
static public final void close(Player owner)
|
||||
{
|
||||
Gui openGui = openGuis.get(owner);
|
||||
if(openGui != null) openGui.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements a Bukkit listener for all GUI-related events.
|
||||
*/
|
||||
static private class GuiListener implements Listener
|
||||
|
||||
static public final Gui getOpenGui(HumanEntity entity)
|
||||
{
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event)
|
||||
{
|
||||
if(!(event.getWhoClicked() instanceof Player)) return;
|
||||
Player owner = (Player) event.getWhoClicked();
|
||||
Gui openGui = openGuis.get(owner);
|
||||
if(openGui == null) return;
|
||||
|
||||
openGui.onDrag(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
if(!(event.getWhoClicked() instanceof Player)) return;
|
||||
Player owner = (Player) event.getWhoClicked();
|
||||
Gui openGui = openGuis.get(owner);
|
||||
if(openGui == null) return;
|
||||
|
||||
openGui.onClick(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(InventoryCloseEvent event)
|
||||
{
|
||||
if(!(event.getPlayer() instanceof Player)) return;
|
||||
Player owner = (Player) event.getPlayer();
|
||||
Gui openGui = openGuis.get(owner);
|
||||
if(openGui == null) return;
|
||||
if(!openGui.isOpen()) return;
|
||||
|
||||
openGui.onClose();
|
||||
openGuis.remove(owner);
|
||||
}
|
||||
if(!(entity instanceof Player)) return null;
|
||||
return openGuis.get((Player) entity);
|
||||
}
|
||||
|
||||
static public final <T extends Gui> T getOpenGui(HumanEntity entity, Class<T> guiClass)
|
||||
{
|
||||
Gui openGui = getOpenGui(entity);
|
||||
if(!guiClass.isAssignableFrom(openGui.getClass())) return null;
|
||||
return (T) openGui;
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ abstract public class GuiUtils
|
||||
* @param slot The slot where to put the ItemStack
|
||||
* @param item The ItemStack to set
|
||||
*/
|
||||
static public void setItemLater(Gui gui, int slot, ItemStack item)
|
||||
static public void setItemLater(InventoryGui gui, int slot, ItemStack item)
|
||||
{
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(ImageOnMap.getPlugin(),
|
||||
new CreateDisplayItemTask(gui.getInventory(), item, slot));
|
||||
|
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Moribus
|
||||
* Copyright (C) 2015 ProkopyL <prokopylmc@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap.guiproko.core;
|
||||
|
||||
import static fr.moribus.imageonmap.guiproko.core.Gui.getOpenGui;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.*;
|
||||
import org.bukkit.event.inventory.*;
|
||||
import org.bukkit.inventory.*;
|
||||
|
||||
/**
|
||||
* This class provides the basic needs for chest-type GUIs.
|
||||
* It allows you to create custom GUIs by simply providing an inventory
|
||||
* to fill, as well as rerouting basic events to it.
|
||||
*/
|
||||
abstract public class InventoryGui extends Gui
|
||||
{
|
||||
static protected final int INVENTORY_ROW_SIZE = 9;
|
||||
static protected final int MAX_INVENTORY_COLUMN_SIZE = 6;
|
||||
static protected final int MAX_INVENTORY_SIZE = INVENTORY_ROW_SIZE * MAX_INVENTORY_COLUMN_SIZE;
|
||||
|
||||
public InventoryGui()
|
||||
{
|
||||
registerListener(GuiListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the inventory.
|
||||
*/
|
||||
private int size = 0;
|
||||
|
||||
/**
|
||||
* The title of the inventory.
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* The current Bukkit inventory.
|
||||
*/
|
||||
private Inventory inventory;
|
||||
|
||||
/* ===== Public API ===== */
|
||||
|
||||
/**
|
||||
* Asks the GUI to update its data, and refresh its view accordingly.
|
||||
* The inventory may be regenerated when calling this method.
|
||||
*/
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
Player player = getPlayer();
|
||||
|
||||
//If inventory does not need to be regenerated
|
||||
if(inventory != null && inventory.getTitle().equals(title) && inventory.getSize() == size)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
inventory = Bukkit.createInventory(player, size, title);
|
||||
populate(inventory);
|
||||
|
||||
if(isOpen()) // Reopening the inventory
|
||||
{
|
||||
player.closeInventory();
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the GUI to recreate its view.
|
||||
* The inventory is cleared, but never regenerated when calling this method.
|
||||
*/
|
||||
public void refresh()
|
||||
{
|
||||
inventory.clear();
|
||||
populate(inventory);
|
||||
}
|
||||
|
||||
/* ===== Protected API ===== */
|
||||
|
||||
@Override
|
||||
protected void open(Player player)
|
||||
{
|
||||
super.open(player);
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this inventory.
|
||||
*/
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
super.close();
|
||||
getPlayer().closeInventory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the inventory needs to be (re)populated.
|
||||
*
|
||||
* @param inventory The inventory to populate
|
||||
*/
|
||||
abstract protected void populate(Inventory inventory);
|
||||
|
||||
/**
|
||||
* Raised when an action is performed on an item in the inventory.
|
||||
*
|
||||
* @param event The click event data.
|
||||
*/
|
||||
abstract protected void onClick(InventoryClickEvent event);
|
||||
|
||||
|
||||
/**
|
||||
* Raised when an drag is performed on the inventory.
|
||||
* The default behaviour is to cancel any event that affects the GUI.
|
||||
*
|
||||
* @param event The drag event data.
|
||||
*/
|
||||
protected void onDrag(InventoryDragEvent event)
|
||||
{
|
||||
if(affectsGui(event)) event.setCancelled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given event affects the GUI's inventory.
|
||||
*
|
||||
* @param event The event to test
|
||||
* @return {@code true} if the event's slot is in the GUI's inventory,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
static protected boolean affectsGui(InventoryClickEvent event)
|
||||
{
|
||||
return event.getRawSlot() < event.getInventory().getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given event affects the GUI's inventory.
|
||||
*
|
||||
* @param event The event to test
|
||||
* @return true if any of the event's slots is in the GUI's inventory,
|
||||
* false otherwise.
|
||||
*/
|
||||
static protected boolean affectsGui(InventoryDragEvent event)
|
||||
{
|
||||
for(int slot : event.getRawSlots())
|
||||
{
|
||||
if(slot < event.getInventory().getSize())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ===== Getters & Setters ===== */
|
||||
|
||||
/** @return The size of the inventory. */
|
||||
protected int getSize() { return size; }
|
||||
|
||||
/**
|
||||
* Sets the new size of the inventory.
|
||||
* The given value is raised to be a multiple of the size of an inventory's
|
||||
* row, and is capped to the maximal size of an inventory.
|
||||
* It will be applied on the next GUI update.
|
||||
* @param size The new size of the inventory.
|
||||
*/
|
||||
protected void setSize(int size)
|
||||
{
|
||||
this.size = Math.min(((int)(Math.ceil((double) size / INVENTORY_ROW_SIZE))) * INVENTORY_ROW_SIZE, MAX_INVENTORY_SIZE);
|
||||
}
|
||||
|
||||
/** @return The title of the inventory. */
|
||||
protected String getTitle() { return title; }
|
||||
|
||||
/**
|
||||
* Sets the new title of the inventory.
|
||||
* It will be applied on the next GUI update.
|
||||
* @param title The new title of the inventory
|
||||
*/
|
||||
protected void setTitle(String title){this.title = title;}
|
||||
|
||||
/** @return The underlying inventory, or null if the Gui has not been opened yet. */
|
||||
public Inventory getInventory() { return inventory; }
|
||||
|
||||
/**
|
||||
* Implements a Bukkit listener for all GUI-related events.
|
||||
*/
|
||||
static private class GuiListener implements Listener
|
||||
{
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event)
|
||||
{
|
||||
InventoryGui openGui = getOpenGui(event.getWhoClicked(), InventoryGui.class);
|
||||
if(openGui == null) return;
|
||||
|
||||
openGui.onDrag(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
InventoryGui openGui = getOpenGui(event.getWhoClicked(), InventoryGui.class);
|
||||
if(openGui == null) return;
|
||||
|
||||
openGui.onClick(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(InventoryCloseEvent event)
|
||||
{
|
||||
Gui openGui = getOpenGui(event.getPlayer());
|
||||
if(openGui == null) return;
|
||||
|
||||
if(!openGui.isOpen());
|
||||
openGui.setClosed();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user