package me.desht.scrollingmenusign.views;
import me.desht.dhutils.ConfigurationManager;
import me.desht.scrollingmenusign.*;
import me.desht.scrollingmenusign.views.action.ViewUpdateAction;
import me.desht.scrollingmenusign.views.icon.IconMenu;
import me.desht.scrollingmenusign.views.icon.IconMenu.OptionClickEvent;
import me.desht.scrollingmenusign.views.icon.IconMenu.OptionClickEventHandler;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.util.UUID;
/**
* This view uses Minecraft inventories and icons to draw menus.
* With thanks to Nisovin: http://forums.bukkit.org/threads/icon-menu.108342/
*/
public class SMSInventoryView extends SMSView implements PoppableView, OptionClickEventHandler {
public static final String WIDTH = "width";
public static final String AUTOPOPDOWN = "autopopdown";
public static final String SPACING = "spacing";
public static final String NO_ESCAPE = "noescape";
private final Map<UUID, IconMenu> popups = new HashMap<UUID, IconMenu>();
public SMSInventoryView(String name, SMSMenu menu) {
super(name, menu);
registerAttribute(WIDTH, 9, "Number of icons per inventory row");
registerAttribute(AUTOPOPDOWN, true, "Auto-popdown after item click?");
registerAttribute(SPACING, 1, "Distance (in slots) between each icon");
registerAttribute(NO_ESCAPE, false, "Prevent menu being closed with Escape");
}
@Override
public void update(Observable obj, Object arg1) {
super.update (obj, arg1);
ViewUpdateAction vu = ViewUpdateAction.getAction(arg1);
if (vu.getSender() instanceof Player) {
IconMenu iconMenu = popups.get(((Player) vu.getSender()).getUniqueId());
if (iconMenu != null) {
iconMenu.repaint();
}
} else {
for (IconMenu iconMenu : popups.values()) {
iconMenu.repaint();
}
}
}
@Override
public void onDeleted(boolean temporary) {
for (IconMenu iconMenu : popups.values()) {
iconMenu.destroy();
}
popups.clear();
}
@Override
public String getType() {
return "inventory";
}
@Override
public void showGUI(Player player) {
IconMenu im = popups.get(player.getUniqueId());
if (im == null) {
im = new IconMenu(this, player);
popups.put(player.getUniqueId(), im);
}
im.popup();
}
@Override
public void hideGUI(Player player) {
IconMenu im = popups.get(player.getUniqueId());
if (im != null) {
im.popdown();
}
}
@Override
public void toggleGUI(Player player) {
if (hasActiveGUI(player)) {
hideGUI(player);
} else {
showGUI(player);
}
}
@Override
public boolean hasActiveGUI(Player player) {
SMSPopup popup = getActiveGUI(player);
return popup != null && popup.isPoppedUp();
}
@Override
public SMSPopup getActiveGUI(Player player) {
SMSPopup popup = popups.get(player.getUniqueId());
if (popup != null && popup.isPoppedUp()) {
return popup;
} else {
return null;
}
}
@Override
public void onOptionClick(final OptionClickEvent event) {
final Player player = event.getPlayer();
SMSMenu menu = getActiveMenu(player);
SMSMenuItem item = getActiveMenuItemByLabel(player, event.getLabel());
if (item == null) {
throw new SMSException("icon menu: item [" + event.getLabel() + "] unknown for menu: " + menu.getName());
}
event.setWillClose((Boolean) getAttribute(AUTOPOPDOWN));
item.executeCommand(player, this, event.getClickType().isRightClick() || event.getClickType().isShiftClick());
item.feedbackMessage(player);
onExecuted(player);
if (item.getCommand().isEmpty() && item.getMessage().isEmpty()) {
// An item with no command or feedback in an inventory view is basically
// a label and won't cause the view to close if clicked
event.setWillClose(false);
return;
}
if (menu != getActiveMenu(player)) {
// We just pushed or popped a submenu, so we need to pop this
// inventory down and pop up a new one with the right title
event.setWillClose(true);
Bukkit.getScheduler().runTaskLater(ScrollingMenuSign.getInstance(), new Runnable() {
@Override
public void run() {
showGUI(player);
}
}, 2L);
}
}
@Override
public Object onConfigurationValidate(ConfigurationManager configurationManager, String key, Object oldVal, Object newVal) {
super.onConfigurationValidate(configurationManager, key, oldVal, newVal);
if (key.equals(SPACING)) {
SMSValidate.isTrue((Integer) newVal >= 1 && (Integer) newVal <= 7, "Spacing must be in the range 1 .. 7");
} else if (key.equals(WIDTH)) {
SMSValidate.isTrue((Integer) newVal >= 1 && (Integer) newVal <= 9, "Width must be in the range 1 .. 9");
} else if (key.equals(AUTOPOPDOWN) && !((Boolean) newVal)) {
SMSValidate.isFalse((Boolean) getAttribute(NO_ESCAPE), "Cannot set 'autopopdown' to false if 'noescape' is true");
} else if (key.equals(NO_ESCAPE) && ((Boolean) newVal)) {
SMSValidate.isTrue((Boolean) getAttribute(AUTOPOPDOWN), "Cannot set 'noescape' to true if 'autopopdown' is false");
}
return newVal;
}
@Override
public String toString() {
return "inventory: " + popups.size() + " icon menus created";
}
}