Implemented user interaction to ExplorerGui.

* NEW: ExplorerGui: Added interaction modes.
* NEW: ExplorerGui: Implemented user interaction.
* NEW: ExplorerGui: Added getPickedUpItem and onPutItem events.
* NEW: Gui: Added getInventory() getter.
* NEW: Added the GuiUtils module, which provides various utility methods.
This commit is contained in:
Adrien Prokopowicz 2015-07-24 18:18:46 +02:00
parent 6ecfc1a561
commit 90968c6009
3 changed files with 168 additions and 2 deletions

View File

@ -19,12 +19,15 @@
package fr.moribus.imageonmap.guiproko.core;
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;
abstract public class ExplorerGui<T> extends ActionGui
{
static protected enum Mode {READONLY, CREATIVE};
private T[] data;
private int viewWidth;
@ -35,6 +38,8 @@ abstract public class ExplorerGui<T> extends ActionGui
private int pageCountY = 0;
private int inventoryViewSize;
private Mode mode = Mode.CREATIVE;
protected void setData(T[] data, int viewWidth)
{
this.data = data;
@ -85,6 +90,83 @@ abstract public class ExplorerGui<T> extends ActionGui
super.update();
}
@Override
protected void onClick(InventoryClickEvent event)
{
int slot = event.getRawSlot();
//Clicked in the action bar
if(slot > MAX_INVENTORY_SIZE - INVENTORY_ROW_SIZE
&& slot < MAX_INVENTORY_SIZE)
{
super.onClick(event);
return;
}
if(slot < event.getInventory().getSize())//The user clicked in its own inventory
{
switch(event.getAction())
{
case PICKUP_ALL: case PICKUP_HALF: case PICKUP_ONE: case PICKUP_SOME:
case HOTBAR_MOVE_AND_READD: case HOTBAR_SWAP:
case MOVE_TO_OTHER_INVENTORY:
onActionPickup(event); break;
case PLACE_ALL: case PLACE_ONE: case PLACE_SOME:
case SWAP_WITH_CURSOR:
onActionPut(event); break;
case DROP_ALL_CURSOR: case DROP_ONE_CURSOR:
break;
default:
event.setCancelled(true);
}
}
else
{
if(event.getAction().equals(InventoryAction.MOVE_TO_OTHER_INVENTORY))
onActionMove(event);
}
}
private int getDataIndex(int slot)
{
int inventorySize = MAX_INVENTORY_SIZE;
if(getPageCount() > 1) inventorySize -= INVENTORY_ROW_SIZE;
return currentPageX * inventorySize + slot;
}
private void onActionPickup(InventoryClickEvent event)
{
if(mode.equals(Mode.READONLY))
{
event.setCancelled(true);
return;
}
int dataIndex = getDataIndex(event.getSlot());
if(dataIndex < 0 || dataIndex >= data.length)
{
event.setCancelled(true);
return;
}
event.setCurrentItem(getPickedUpItem(data[dataIndex]));
GuiUtils.setItemLater(this, event.getSlot(), getViewItem(data[dataIndex]));
}
private void onActionPut(InventoryClickEvent event)
{
event.setCancelled(true);
if(mode.equals(Mode.READONLY)) return;
if(!onPutItem(event.getCursor())) return;
event.setCursor(new ItemStack(Material.AIR));
}
private void onActionMove(InventoryClickEvent event)
{
event.setCancelled(true);
if(mode.equals(Mode.READONLY)) return;
if(!onPutItem(event.getCurrentItem())) return;
event.setCurrentItem(new ItemStack(Material.AIR));
}
@Override
protected void onAfterUpdate()
{
@ -95,18 +177,21 @@ abstract public class ExplorerGui<T> extends ActionGui
}
}
protected void action_next()
private void action_next()
{
next();
}
protected void action_previous()
private void action_previous()
{
previous();
}
abstract protected ItemStack getViewItem(T data);
protected ItemStack getPickedUpItem(T data){return getViewItem(data);}
protected boolean onPutItem(ItemStack item){return true;}
public void next()
{
if(!canGoNext()) return;
@ -150,4 +235,7 @@ abstract public class ExplorerGui<T> extends ActionGui
return (int)Math.ceil(data.length / (MAX_INVENTORY_COLUMN_SIZE - (hasActions() ? 0 : 1)));
}
protected Mode getMode() {return mode;}
protected void setMode(Mode mode) {this.mode = mode;}
}

View File

@ -185,6 +185,9 @@ abstract public class Gui
*/
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 ===== */
/**

View File

@ -0,0 +1,75 @@
/*
* 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.ImageOnMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
/**
* Various utility methods for GUIs.
*/
abstract public class GuiUtils
{
/**
* Stores the ItemStack at the given index of a GUI's inventory.
* The inventory is only updated the next time the Bukkit Scheduler runs (i.e. next server tick).
*
* @param gui The GUI to update
* @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)
{
Bukkit.getScheduler().scheduleSyncDelayedTask(ImageOnMap.getPlugin(),
new CreateDisplayItemTask(gui.getInventory(), item, slot));
}
/**
* Implements a bukkit runnable that updates an inventory slot later.
*/
static private class CreateDisplayItemTask implements Runnable
{
private final Inventory inventory;
private final ItemStack item;
private final int slot;
public CreateDisplayItemTask(Inventory inventory, ItemStack item, int slot)
{
this.inventory = inventory;
this.item = item;
this.slot = slot;
}
@Override
public void run()
{
inventory.setItem(slot, item);
for(HumanEntity player : inventory.getViewers())
{
((Player)player).updateInventory();
}
}
}
}