Added new Action GUI class (and tests).

* NEW: Added new Action GUI type.
* NEW: Added testing implementation of ConfirmDeleteMapGui.
* BUG: Newly opened GUIs are now correctly registered.
* BUG: GUI: Fixed NPE when first generating the inventory.
* BUG: GUIs opened from another GUI do not interfere anymore when
  the parent GUI is closed.
This commit is contained in:
Adrien Prokopowicz 2015-07-15 02:24:27 +02:00
parent 1ffc64e580
commit 59f099a116
4 changed files with 194 additions and 7 deletions

View File

@ -20,6 +20,7 @@ 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;
@ -266,6 +267,7 @@ public class MapDetailGui extends AbstractGui
case "delete":
GuiManager.openGui(player, new ConfirmDeleteMapGui(map, currentPage));
//Gui.open(player, new fr.moribus.imageonmap.guiproko.list.ConfirmDeleteMapGui());
return;
default:

View File

@ -0,0 +1,138 @@
/*
* 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 fr.moribus.imageonmap.PluginLogger;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
abstract public class ActionGui extends Gui
{
static private final String ACTION_HANDLER_NAME = "action_";
private final Class<? extends ActionGui> guiClass = this.getClass();
private final HashMap<Integer, Action> actions = new HashMap<>();
private int maxSlot;
/* ===== Protected API ===== */
protected void action(String name, int slot, Material material, String title, String ... loreLines)
{
action(name, slot, new ItemStack(material), title, Arrays.asList(loreLines));
}
protected void action(String name, int slot, ItemStack item, String title, String ... loreLines)
{
action(name, slot, item, title, Arrays.asList(loreLines));
}
protected void action(String name, int slot, ItemStack item, String title, List<String> loreLines)
{
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(title);
meta.setLore(loreLines);
item.setItemMeta(meta);
Method callback;
try
{
callback = guiClass.getDeclaredMethod(ACTION_HANDLER_NAME + name);
callback.setAccessible(true);
}
catch (Throwable ex)
{
callback = null;
}
if(slot > getSize() || slot < 0)
throw new IllegalArgumentException("Illegal slot ID");
action(new Action(name, slot, item, callback));
}
private void action(Action action)
{
actions.put(action.slot, action);
if(maxSlot < action.slot) maxSlot = action.slot;
}
@Override
protected abstract void onUpdate();
@Override
public void update()
{
actions.clear();
super.update();
}
@Override
protected void populate(Inventory inventory)
{
for(Action action : actions.values())
{
inventory.setItem(action.slot, action.item);
}
}
@Override
protected void onClick(InventoryClickEvent event)
{
event.setCancelled(true);
Action action = actions.get(event.getRawSlot());
if(action == null || action.callback == null) return;
try
{
action.callback.invoke(this);
}
catch (IllegalAccessException | IllegalArgumentException ex)
{
PluginLogger.error("Could not invoke GUI action handler", ex);
}
catch (InvocationTargetException ex)
{
PluginLogger.error("Error while invoking action handler {0} of GUI {1}", ex, action.name, guiClass.getName());
}
}
static private class Action
{
public String name;
public int slot;
public ItemStack item;
public Method callback;
public Action(String name, int slot, ItemStack item, Method callback)
{
this.name = name;
this.slot = slot;
this.item = item;
this.callback = callback;
}
}
}

View File

@ -66,9 +66,10 @@ abstract public class Gui
private void open(HumanEntity player)
{
this.player = player;
openGuis.put(player, this);
update();
this.open = true;
player.openInventory(inventory);
this.open = true;
}
/* ===== Public API ===== */
@ -81,8 +82,13 @@ abstract public class Gui
{
onUpdate();
//If inventory needs to be regenerated
//If inventory does not need to be regenerated
if(inventory != null && inventory.getTitle().equals(title) && inventory.getSize() == size)
{
inventory.clear();
populate(inventory);
}
else
{
inventory = Bukkit.createInventory(player, size, title);
populate(inventory);
@ -92,11 +98,6 @@ abstract public class Gui
player.openInventory(inventory);
}
}
else
{
inventory.clear();
populate(inventory);
}
}
/**
@ -250,6 +251,7 @@ abstract public class Gui
HumanEntity owner = event.getPlayer();
Gui openGui = openGuis.get(owner);
if(openGui == null) return;
if(!openGui.isOpen()) return;
openGui.onClose();
openGuis.remove(owner);

View File

@ -0,0 +1,45 @@
/*
* 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.list;
import fr.moribus.imageonmap.guiproko.core.ActionGui;
import org.bukkit.Material;
public class ConfirmDeleteMapGui extends ActionGui
{
@Override
protected void onUpdate()
{
setTitle("Are you sure ?");
setSize(2);
action("toto", 1, Material.DIAMOND, "Toto");
action("tata", 2, Material.EMERALD, "Tata");
}
protected void action_toto()
{
getPlayer().sendMessage("toto");
}
protected void action_tata()
{
getPlayer().sendMessage("tata");
}
}