mirror of
https://github.com/zDevelopers/ImageOnMap.git
synced 2024-11-14 14:15:11 +01:00
Added new Explorer GUI class (and tests).
* NEW: Added new Explorer GUI type (not yet complete). * NEW: Added testing implementation of MaterialGui. * NEW: Added testing implementation of MapListGui (not functional). * NEW: Gui: Added the MAX_INVENTORY_COLUMN_SIZE constant. * NEW: ActionGui: Added the onAction_unknown event. * NEW: ActionGui: Added the updateAction methods. * BUG: ActionGui can now find action handlers in subclasses. * BUG: ActionGui: Actions in the player's inventory are not cancelled anymore.
This commit is contained in:
parent
59f099a116
commit
6ecfc1a561
@ -22,6 +22,8 @@ package fr.moribus.imageonmap.commands.maptool;
|
||||
import fr.moribus.imageonmap.commands.*;
|
||||
import fr.moribus.imageonmap.gui.core.*;
|
||||
import fr.moribus.imageonmap.gui.list.*;
|
||||
import fr.moribus.imageonmap.guiproko.core.Gui;
|
||||
import fr.moribus.imageonmap.guiproko.list.MaterialGui;
|
||||
|
||||
|
||||
@CommandInfo(name = "manage")
|
||||
@ -35,6 +37,7 @@ public class ManageCommand extends Command
|
||||
@Override
|
||||
protected void run() throws CommandException
|
||||
{
|
||||
GuiManager.openGui(playerSender(), new MapListGui());
|
||||
//GuiManager.openGui(playerSender(), new MapListGui());
|
||||
Gui.open(playerSender(), new MaterialGui());
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -35,7 +36,6 @@ 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 ===== */
|
||||
|
||||
@ -56,32 +56,61 @@ abstract public class ActionGui extends Gui
|
||||
meta.setLore(loreLines);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
Method callback;
|
||||
try
|
||||
{
|
||||
callback = guiClass.getDeclaredMethod(ACTION_HANDLER_NAME + name);
|
||||
callback.setAccessible(true);
|
||||
}
|
||||
catch (Throwable ex)
|
||||
{
|
||||
callback = null;
|
||||
action(name, slot, item);
|
||||
}
|
||||
|
||||
protected void action(String name, int slot, Material material)
|
||||
{
|
||||
action(name, slot, new ItemStack(material));
|
||||
}
|
||||
|
||||
protected void action(String name, int slot)
|
||||
{
|
||||
action(name, slot, (ItemStack)null);
|
||||
}
|
||||
|
||||
protected void action(String name, int slot, ItemStack item)
|
||||
{
|
||||
if(slot > getSize() || slot < 0)
|
||||
throw new IllegalArgumentException("Illegal slot ID");
|
||||
|
||||
action(new Action(name, slot, item, callback));
|
||||
action(new Action(name, slot, item, getActionHandler(guiClass, name)));
|
||||
}
|
||||
|
||||
|
||||
private void action(Action action)
|
||||
{
|
||||
actions.put(action.slot, action);
|
||||
if(maxSlot < action.slot) maxSlot = action.slot;
|
||||
}
|
||||
|
||||
protected void updateAction(String name, Material item, String title)
|
||||
{
|
||||
updateAction(name, new ItemStack(item), title);
|
||||
}
|
||||
|
||||
protected void updateAction(String name, ItemStack item, String title)
|
||||
{
|
||||
Action action = getAction(name);
|
||||
action.item = item;
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName(title);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
private Action getAction(String name)
|
||||
{
|
||||
for(Action action : actions.values())
|
||||
{
|
||||
if(action.name.equals(name)) return action;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown action name : " + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected abstract void onUpdate();
|
||||
|
||||
protected void onAction_unknown(String name, int slot, ItemStack item){}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
@ -101,10 +130,25 @@ abstract public class ActionGui extends Gui
|
||||
@Override
|
||||
protected void onClick(InventoryClickEvent event)
|
||||
{
|
||||
if(event.getRawSlot() >= event.getInventory().getSize())//The user clicked in its own inventory
|
||||
{
|
||||
if(!event.getAction().equals(InventoryAction.MOVE_TO_OTHER_INVENTORY))
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
|
||||
Action action = actions.get(event.getRawSlot());
|
||||
if(action == null || action.callback == null) return;
|
||||
callAction(actions.get(event.getRawSlot()));
|
||||
}
|
||||
|
||||
private void callAction(Action action)
|
||||
{
|
||||
if(action == null) return;
|
||||
if(action.callback == null)
|
||||
{
|
||||
onAction_unknown(action.name, action.slot, action.item);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
action.callback.invoke(this);
|
||||
@ -115,10 +159,38 @@ abstract public class ActionGui extends Gui
|
||||
}
|
||||
catch (InvocationTargetException ex)
|
||||
{
|
||||
PluginLogger.error("Error while invoking action handler {0} of GUI {1}", ex, action.name, guiClass.getName());
|
||||
PluginLogger.error("Error while invoking action handler {0} of GUI {1}",
|
||||
ex.getCause(), action.name, guiClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private Method getActionHandler(Class klass, String name)
|
||||
{
|
||||
Method callback = null;
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
callback = klass.getDeclaredMethod(ACTION_HANDLER_NAME + name);
|
||||
callback.setAccessible(true);
|
||||
break;
|
||||
}
|
||||
catch (Throwable ex)
|
||||
{
|
||||
callback = null;
|
||||
klass = klass.getSuperclass();
|
||||
}
|
||||
|
||||
}while(klass != null);
|
||||
|
||||
return callback;
|
||||
}
|
||||
|
||||
protected boolean hasActions()
|
||||
{
|
||||
return !actions.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
static private class Action
|
||||
{
|
||||
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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 org.bukkit.Material;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
|
||||
abstract public class ExplorerGui<T> extends ActionGui
|
||||
{
|
||||
|
||||
private T[] data;
|
||||
private int viewWidth;
|
||||
|
||||
private int currentPageX = 0;
|
||||
|
||||
private int pageCountX = 0;
|
||||
private int pageCountY = 0;
|
||||
private int inventoryViewSize;
|
||||
|
||||
protected void setData(T[] data, int viewWidth)
|
||||
{
|
||||
this.data = data;
|
||||
this.viewWidth = viewWidth;
|
||||
}
|
||||
|
||||
protected void setData(T[] data)
|
||||
{
|
||||
setData(data, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void populate(Inventory inventory)
|
||||
{
|
||||
int inventorySize = MAX_INVENTORY_SIZE;
|
||||
if(getPageCount() > 1)
|
||||
{
|
||||
inventorySize -= INVENTORY_ROW_SIZE;
|
||||
if(canGoNext())
|
||||
updateAction("next", Material.ARROW, "Next page");
|
||||
else
|
||||
updateAction("next", Material.STICK, "No next page");
|
||||
|
||||
if(canGoPrevious())
|
||||
updateAction("previous", Material.ARROW, "Previous page");
|
||||
else
|
||||
updateAction("previous", Material.STICK, "No previous page");
|
||||
}
|
||||
|
||||
if(viewWidth <= 0)
|
||||
{
|
||||
int start = currentPageX * inventorySize;
|
||||
int max = Math.min(inventorySize, data.length - start);
|
||||
for(int i = 0; i < max; i++)
|
||||
{
|
||||
inventory.setItem(i, getViewItem(data[i + start]));
|
||||
}
|
||||
}
|
||||
if(hasActions()) super.populate(inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
//TODO: Make inventory fit to content
|
||||
setSize(MAX_INVENTORY_SIZE);
|
||||
|
||||
super.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAfterUpdate()
|
||||
{
|
||||
if(getPageCount() > 1)
|
||||
{
|
||||
action("previous", MAX_INVENTORY_SIZE - INVENTORY_ROW_SIZE);
|
||||
action("next", MAX_INVENTORY_SIZE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
protected void action_next()
|
||||
{
|
||||
next();
|
||||
}
|
||||
|
||||
protected void action_previous()
|
||||
{
|
||||
previous();
|
||||
}
|
||||
|
||||
abstract protected ItemStack getViewItem(T data);
|
||||
|
||||
public void next()
|
||||
{
|
||||
if(!canGoNext()) return;
|
||||
currentPageX++;
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void previous()
|
||||
{
|
||||
if(!canGoPrevious()) return;
|
||||
currentPageX--;
|
||||
refresh();
|
||||
}
|
||||
|
||||
public boolean canGoNext()
|
||||
{
|
||||
return currentPageX < getPageCount();
|
||||
}
|
||||
|
||||
public boolean canGoPrevious()
|
||||
{
|
||||
return currentPageX > 0;
|
||||
}
|
||||
|
||||
public int getPageCount()
|
||||
{
|
||||
if(data.length == 0) return 0;
|
||||
|
||||
if(viewWidth > 0)
|
||||
{
|
||||
if(viewWidth > INVENTORY_ROW_SIZE) return 1;
|
||||
return (int)Math.ceil(viewWidth / (INVENTORY_ROW_SIZE - 1));
|
||||
}
|
||||
|
||||
return (int)Math.ceil(data.length / (MAX_INVENTORY_SIZE - (hasActions() ? INVENTORY_ROW_SIZE : 0)));
|
||||
}
|
||||
|
||||
public int getVerticalPageCount()
|
||||
{
|
||||
if(viewWidth <= 0) return 0;
|
||||
|
||||
return (int)Math.ceil(data.length / (MAX_INVENTORY_COLUMN_SIZE - (hasActions() ? 0 : 1)));
|
||||
}
|
||||
}
|
@ -36,7 +36,8 @@ import org.bukkit.plugin.Plugin;
|
||||
abstract public class Gui
|
||||
{
|
||||
static protected final int INVENTORY_ROW_SIZE = 9;
|
||||
static protected final int MAX_INVENTORY_SIZE = INVENTORY_ROW_SIZE * 6;
|
||||
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.
|
||||
@ -67,7 +68,7 @@ abstract public class Gui
|
||||
{
|
||||
this.player = player;
|
||||
openGuis.put(player, this);
|
||||
update();
|
||||
this.update();
|
||||
player.openInventory(inventory);
|
||||
this.open = true;
|
||||
}
|
||||
@ -75,18 +76,18 @@ abstract public class Gui
|
||||
/* ===== Public API ===== */
|
||||
|
||||
/**
|
||||
* Asks the GUI to update its data, and recreate its view accordingly.
|
||||
* The inventory is regenerated when calling this method.
|
||||
* 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)
|
||||
{
|
||||
inventory.clear();
|
||||
populate(inventory);
|
||||
refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -100,6 +101,16 @@ abstract public class Gui
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@ -116,7 +127,13 @@ abstract public class Gui
|
||||
* Raised when the {@link Gui#update() } method is called.
|
||||
* Use this method to update your internal data.
|
||||
*/
|
||||
protected void onUpdate(){};
|
||||
protected void onUpdate(){}
|
||||
|
||||
/**
|
||||
* Raised when the {@link Gui#update() } method is called, but before the inventory is populated.
|
||||
* Use this method in a Gui subclass to analyze given data and set other parameters accordingly.
|
||||
*/
|
||||
protected void onAfterUpdate(){}
|
||||
|
||||
/**
|
||||
* Called when the inventory needs to be (re)populated.
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.ExplorerGui;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import java.util.List;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class MapListGui extends ExplorerGui<ImageMap>
|
||||
{
|
||||
private ImageMap[] maps;
|
||||
|
||||
@Override
|
||||
protected ItemStack getViewItem(ImageMap data)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdate()
|
||||
{
|
||||
List<ImageMap> listMaps = MapManager.getMapList(getPlayer().getUniqueId());
|
||||
maps = new ImageMap[listMaps.size()];
|
||||
|
||||
for(int i = listMaps.size(); i --> 0;)
|
||||
{
|
||||
maps[i] = listMaps.get(i);
|
||||
}
|
||||
|
||||
setData(maps);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.ExplorerGui;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class MaterialGui extends ExplorerGui<Material>
|
||||
{
|
||||
|
||||
@Override
|
||||
protected ItemStack getViewItem(Material data)
|
||||
{
|
||||
return new ItemStack(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdate()
|
||||
{
|
||||
setTitle("All da materials");
|
||||
setData(Material.values());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user