diff --git a/src/main/java/fr/moribus/imageonmap/guiproko/core/ExplorerGui.java b/src/main/java/fr/moribus/imageonmap/guiproko/core/ExplorerGui.java index e369bca..3857f6f 100644 --- a/src/main/java/fr/moribus/imageonmap/guiproko/core/ExplorerGui.java +++ b/src/main/java/fr/moribus/imageonmap/guiproko/core/ExplorerGui.java @@ -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 extends ActionGui { + static protected enum Mode {READONLY, CREATIVE}; private T[] data; private int viewWidth; @@ -35,6 +38,8 @@ abstract public class ExplorerGui 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 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 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 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;} } diff --git a/src/main/java/fr/moribus/imageonmap/guiproko/core/Gui.java b/src/main/java/fr/moribus/imageonmap/guiproko/core/Gui.java index d5c417c..9c52fa2 100644 --- a/src/main/java/fr/moribus/imageonmap/guiproko/core/Gui.java +++ b/src/main/java/fr/moribus/imageonmap/guiproko/core/Gui.java @@ -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 ===== */ /** diff --git a/src/main/java/fr/moribus/imageonmap/guiproko/core/GuiUtils.java b/src/main/java/fr/moribus/imageonmap/guiproko/core/GuiUtils.java new file mode 100644 index 0000000..1362b58 --- /dev/null +++ b/src/main/java/fr/moribus/imageonmap/guiproko/core/GuiUtils.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 Moribus + * Copyright (C) 2015 ProkopyL + * + * 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 . + */ + +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(); + } + } + + } +}