├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src └── main └── java └── io └── mazenmc └── menuapi ├── MenuFactory.java ├── items ├── BasicItem.java ├── Item.java └── ItemListener.java └── menu ├── Menu.java ├── MultiMenu.java └── ScrollingMenu.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .gitignore support plugin (hsz.mobi) 2 | ### Java template 3 | *.class 4 | 5 | # Mobile Tools for Java (J2ME) 6 | .mtj.tmp/ 7 | 8 | # IntelliJ files 9 | .idea/ 10 | 11 | # Package Files # 12 | *.jar 13 | *.war 14 | *.ear 15 | 16 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 17 | hs_err_pid* 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MenuAPI 2 | A lightweight and extensive MenuAPI using Java 8 3 | 4 | ### Adding MenuAPI as a Maven Depedency 5 | MenuAPI is on the main maven repository! You just need to add this into your pom.xml: 6 | 7 | ``` xml 8 | 9 | 10 | io.mazenmc 11 | menuapi 12 | compile 13 | 1.0 14 | 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | io.mazenmc 8 | menuapi 9 | 1.0 10 | 11 | MenuAPI 12 | A lightweight and extensive MenuAPI using Java 8 13 | https://github.com/MazenMC/MenuAPI 14 | 15 | 16 | 17 | ossrh 18 | https://oss.sonatype.org/content/repositories/snapshots 19 | 20 | 21 | ossrh 22 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 23 | 24 | 25 | 26 | 27 | scm:git:git@github.com:MazenMC/MenuAPI.git 28 | scm:git:git@github.com:MazenMC/MenuAPI.git 29 | git@github.com:MazenMC/MenuAPI.git 30 | 31 | 32 | 33 | 34 | ISC License 35 | http://choosealicense.com/licenses/isc/ 36 | 37 | 38 | 39 | 40 | 41 | Mazen Kotb 42 | email@mazenmc.io 43 | 44 | 45 | 46 | 47 | 48 | spigot-repo 49 | https://hub.spigotmc.org/nexus/content/groups/public/ 50 | 51 | 52 | 53 | 54 | 55 | org.spigotmc 56 | spigot-api 57 | 1.11-R0.1-SNAPSHOT 58 | provided 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.apache.maven.plugins 67 | maven-compiler-plugin 68 | 3.1 69 | 70 | 1.8 71 | 1.8 72 | 73 | 74 | 75 | 76 | maven-deploy-plugin 77 | 78 | 79 | 80 | maven-gpg-plugin 81 | 1.5 82 | 83 | 84 | sign-artifacts 85 | verify 86 | 87 | sign 88 | 89 | 90 | 91 | 92 | true 93 | 94 | 95 | 96 | 97 | org.apache.maven.plugins 98 | maven-source-plugin 99 | 2.2.1 100 | 101 | 102 | attach-sources 103 | 104 | jar-no-fork 105 | 106 | 107 | 108 | 109 | 110 | org.apache.maven.plugins 111 | maven-javadoc-plugin 112 | 2.9.1 113 | 114 | 115 | attach-javadocs 116 | 117 | jar 118 | 119 | 120 | 121 | 122 | 123 | 124 | org.sonatype.plugins 125 | nexus-staging-maven-plugin 126 | 1.6.3 127 | true 128 | 129 | ossrh 130 | https://oss.sonatype.org/ 131 | true 132 | 133 | 134 | 135 | 136 | org.codehaus.mojo 137 | versions-maven-plugin 138 | 2.1 139 | 140 | false 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /src/main/java/io/mazenmc/menuapi/MenuFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package io.mazenmc.menuapi; 17 | 18 | import io.mazenmc.menuapi.items.BasicItem; 19 | import io.mazenmc.menuapi.items.Item; 20 | import io.mazenmc.menuapi.items.ItemListener; 21 | import io.mazenmc.menuapi.menu.Menu; 22 | import io.mazenmc.menuapi.menu.MultiMenu; 23 | import io.mazenmc.menuapi.menu.ScrollingMenu; 24 | import org.bukkit.ChatColor; 25 | import org.bukkit.Material; 26 | import org.bukkit.entity.Player; 27 | import org.bukkit.event.HandlerList; 28 | import org.bukkit.event.inventory.ClickType; 29 | import org.bukkit.inventory.ItemStack; 30 | import org.bukkit.inventory.meta.ItemMeta; 31 | 32 | import java.util.Arrays; 33 | 34 | public final class MenuFactory { 35 | public static final ItemListener EMPTY_LISTENER = (ItemListener) MenuFactory::doNothing; 36 | 37 | private MenuFactory() {} 38 | 39 | private static void doNothing(Player p, ClickType type) {} 40 | 41 | /** 42 | * Creates a menu with the inputted specifications 43 | * @param name Name of the menu 44 | * @param size Size of the menu 45 | * @return The generated menu 46 | */ 47 | public static Menu createMenu(String name, int size) { 48 | return Menu.createMenu(name, size); 49 | } 50 | 51 | /** 52 | * Creates a menu with the inputted specifications 53 | * @param name Name of the menu 54 | * @param size Size of the menu 55 | * @param parent The parent of this menu, displayed to the user when it exits this one 56 | * @return The generated menu 57 | */ 58 | public static Menu createMenu(String name, int size, Menu parent) { 59 | return createMenu(name, size).setParent(parent); 60 | } 61 | 62 | public static MultiMenu createMultiMenu(String name, int size) { 63 | return MultiMenu.create(name, size); 64 | } 65 | 66 | public static MultiMenu createMultiMenu(String name, int size, Menu parent) { 67 | return (MultiMenu) createMultiMenu(name, size).setParent(parent); 68 | } 69 | 70 | public static MultiMenu createMultiMenu(String name, int size, int pages) { 71 | return MultiMenu.create(name, size, pages); 72 | } 73 | 74 | public static MultiMenu createMultiMenu(String name, int size, int pages, Menu parent) { 75 | return (MultiMenu) createMultiMenu(name, size, pages).setParent(parent); 76 | } 77 | 78 | public static ScrollingMenu createScrollingMenu(String name) { 79 | return ScrollingMenu.create(name); 80 | } 81 | 82 | public static Item createItem(ItemStack stack, ItemListener listener) { 83 | return BasicItem.create(stack, listener); 84 | } 85 | 86 | public static Item createItem(ItemListener listener, Material material, String name, String... lore) { 87 | ItemStack stack = new ItemStack(material); 88 | ItemMeta meta = stack.getItemMeta(); 89 | 90 | meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); 91 | meta.setLore(Arrays.asList(lore)); 92 | 93 | stack.setItemMeta(meta); 94 | return createItem(stack, listener); 95 | } 96 | 97 | /** 98 | * Disposes of the menu, reduces retention on the menu 99 | * @param menu The menu you wish to dispose 100 | */ 101 | public static void dispose(Menu menu) { 102 | HandlerList.unregisterAll(menu); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/io/mazenmc/menuapi/items/BasicItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package io.mazenmc.menuapi.items; 17 | 18 | import org.bukkit.entity.Player; 19 | import org.bukkit.event.inventory.ClickType; 20 | import org.bukkit.inventory.ItemStack; 21 | 22 | import java.util.function.Predicate; 23 | 24 | public class BasicItem implements Item { 25 | private ItemListener listener; 26 | private ItemStack stack; 27 | 28 | private BasicItem(ItemStack stack, ItemListener listener) { 29 | this.stack = stack; 30 | this.listener = listener; 31 | } 32 | 33 | public static BasicItem create(ItemStack stack, ItemListener listener) { 34 | return new BasicItem(stack, listener); 35 | } 36 | 37 | @Override 38 | public ItemStack stack() { 39 | return stack; 40 | } 41 | 42 | @Override 43 | public void act(Player player, ClickType clickType) { 44 | if (listener == null) 45 | return; 46 | 47 | listener.act(player, clickType); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/mazenmc/menuapi/items/Item.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package io.mazenmc.menuapi.items; 17 | 18 | import org.bukkit.entity.Player; 19 | import org.bukkit.event.inventory.ClickType; 20 | import org.bukkit.inventory.ItemStack; 21 | 22 | public interface Item { 23 | 24 | public ItemStack stack(); 25 | 26 | public default void act(Player player, ClickType clickType) {} 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/mazenmc/menuapi/items/ItemListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package io.mazenmc.menuapi.items; 17 | 18 | import org.bukkit.entity.Player; 19 | import org.bukkit.event.inventory.ClickType; 20 | 21 | public interface ItemListener { 22 | public void act(Player player, ClickType type); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/mazenmc/menuapi/menu/Menu.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package io.mazenmc.menuapi.menu; 17 | 18 | import io.mazenmc.menuapi.items.Item; 19 | import org.bukkit.Bukkit; 20 | import org.bukkit.ChatColor; 21 | import org.bukkit.entity.Player; 22 | import org.bukkit.event.EventHandler; 23 | import org.bukkit.event.Listener; 24 | import org.bukkit.event.inventory.InventoryClickEvent; 25 | import org.bukkit.event.inventory.InventoryCloseEvent; 26 | import org.bukkit.event.inventory.InventoryDragEvent; 27 | import org.bukkit.inventory.Inventory; 28 | import org.bukkit.plugin.java.JavaPlugin; 29 | import org.bukkit.scheduler.BukkitRunnable; 30 | 31 | import java.util.HashMap; 32 | import java.util.Map; 33 | 34 | public class Menu implements Listener { 35 | private static final JavaPlugin OWNER = JavaPlugin.getProvidingPlugin(Menu.class); 36 | 37 | private String name; 38 | private int size; 39 | private Inventory inventory; 40 | protected Map items = new HashMap<>(); // map for quick lookup 41 | private Menu parent; 42 | 43 | protected Menu(String name, int size) { // allow for sub classes 44 | this.name = ChatColor.translateAlternateColorCodes('&', name); 45 | this.size = size; 46 | 47 | this.inventory = Bukkit.createInventory(null, size, this.name); 48 | Bukkit.getPluginManager().registerEvents(this, OWNER); 49 | } 50 | 51 | public static Menu createMenu(String name, int size) { 52 | return new Menu(name, size); 53 | } 54 | 55 | /** 56 | * The name of this menu, with translated color codes 57 | * @return The name 58 | */ 59 | public String name() { 60 | return name; 61 | } 62 | 63 | /** 64 | * The size of this menu 65 | * @return The size of this menu 66 | */ 67 | public int size() { 68 | return size; 69 | } 70 | 71 | /** 72 | * The inventory representation of this menu 73 | * @return The inventory representation 74 | */ 75 | public Inventory inventory() { 76 | return inventory; 77 | } 78 | 79 | /** 80 | * Returns the item at specified index 81 | * @param index 82 | * @return Found item 83 | */ 84 | public Item itemAt(int index) { 85 | return items.get(index); 86 | } 87 | 88 | /** 89 | * Returns the item at specified coordinates, where x is on the horizontal axis and z is on the vertical axis. 90 | * @param x The x coordinate 91 | * @param z The z coordinate 92 | * @return Found item 93 | */ 94 | public Item itemAt(int x, int z) { 95 | return items.get(z * 9 + x); 96 | } 97 | 98 | /** 99 | * Sets the item at the specified index 100 | * @param index Index of the item you wish to set 101 | * @param item The item you wish to set the index as 102 | */ 103 | public Menu setItem(int index, Item item) { 104 | if (item == null) { 105 | inventory.setItem(index, null); 106 | } else { 107 | inventory.setItem(index, item.stack()); 108 | } 109 | 110 | items.put(index, item); 111 | return this; 112 | } 113 | 114 | /** 115 | * Sets the item at the specified coordinates, where x is on the horizontal axis and z is on the vertical axis. 116 | * @param x The x coordinate 117 | * @param z The z coordinate 118 | * @param item The item you wish to set the index as 119 | */ 120 | public Menu setItem(int x, int z, Item item) { 121 | return setItem(z * 9 + x, item); 122 | } 123 | 124 | /** 125 | * Sets the parent of the menu, used when the player exits the menu 126 | */ 127 | public Menu setParent(Menu parent) { 128 | this.parent = parent; 129 | return this; 130 | } 131 | 132 | /** 133 | * Show the menu to the inputted players 134 | * @param players The players you wish to show the menu too 135 | */ 136 | public void showTo(Player... players) { 137 | for (Player p : players) { 138 | p.openInventory(inventory); 139 | } 140 | } 141 | 142 | @EventHandler 143 | public void onExit(InventoryCloseEvent event) { 144 | if(!event.getInventory().equals(inventory)) 145 | return; 146 | 147 | if (parent != null) { 148 | new BukkitRunnable() { 149 | @Override 150 | public void run() { 151 | event.getPlayer().openInventory(parent.inventory); 152 | } 153 | }.runTaskLater(OWNER, 2L); 154 | } 155 | } 156 | 157 | @EventHandler 158 | public void onClick(InventoryClickEvent event) { 159 | if(!event.getInventory().equals(inventory)) 160 | return; 161 | 162 | if(event.getRawSlot() >= size && !event.getClick().isShiftClick()) 163 | return; 164 | 165 | event.setCancelled(true); 166 | 167 | if(!items.containsKey(event.getSlot())) { 168 | return; 169 | } 170 | 171 | items.get(event.getSlot()).act((Player) event.getWhoClicked(), event.getClick()); 172 | } 173 | 174 | @EventHandler 175 | public void onDrag(InventoryDragEvent event) { 176 | if(!event.getInventory().equals(inventory)) 177 | return; 178 | 179 | event.setCancelled(true); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/main/java/io/mazenmc/menuapi/menu/MultiMenu.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package io.mazenmc.menuapi.menu; 17 | 18 | import io.mazenmc.menuapi.MenuFactory; 19 | import org.bukkit.ChatColor; 20 | import org.bukkit.Material; 21 | import org.bukkit.inventory.ItemStack; 22 | import org.bukkit.inventory.meta.ItemMeta; 23 | 24 | /** 25 | * Menu with multiple sub menus, or "pages", 26 | * 27 | * This class extends Menu, moreover this instance is the main page or menu. 28 | * You can use the setMenu at index 0 to override this. 29 | */ 30 | public final class MultiMenu extends Menu { 31 | private static final Menu EMPTY_MENU = MenuFactory.createMenu("Empty Menu", 18); 32 | 33 | 34 | private ItemStack next = new ItemStack(Material.ARROW); 35 | private ItemStack back = new ItemStack(Material.BED); 36 | 37 | protected Menu[] menus; 38 | 39 | protected MultiMenu(String name, int size) { 40 | this(name, size, 5); 41 | } 42 | 43 | protected MultiMenu(String name, int size, int pages) { 44 | super(name, size); 45 | 46 | menus = new Menu[pages]; 47 | 48 | menus[0] = this; // this menu is the front page 49 | setName(next, "&3Next"); 50 | setName(back, "&3Back"); 51 | 52 | for (int i = 1; i < pages; i++) { 53 | menus[i] = EMPTY_MENU; 54 | } 55 | 56 | updateMenus(); 57 | } 58 | 59 | /** 60 | * Creates a MultiMenu with 5 empty menus/pages 61 | * @param name Name of the main menu 62 | * @param size Size of the main menu 63 | * @return Created menu 64 | */ 65 | public static MultiMenu create(String name, int size) { 66 | return new MultiMenu(name, size); 67 | } 68 | 69 | /** 70 | * Create a MultiMenu with the following specifications 71 | * @param name Name of the main menu 72 | * @param size Size of the main menu 73 | * @param pages Amount of pages or menus in this MultiMenu, not graved in stone 74 | */ 75 | public static MultiMenu create(String name, int size, int pages) { 76 | return new MultiMenu(name, size, pages); 77 | } 78 | 79 | static void setName(ItemStack stack, String name) { 80 | ItemMeta meta = stack.getItemMeta(); 81 | 82 | meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); 83 | stack.setItemMeta(meta); 84 | } 85 | 86 | /** 87 | * Set menu at the specified index, can be over the size. 88 | * If the index is over the menu size, it will resize the menus array. 89 | * 90 | * @param index Index you wish to set the menu at 91 | * @param menu Menu you wish to set 92 | */ 93 | public void setMenu(int index, Menu menu) { 94 | if (menus.length <= index && menus.length != (index - 1)) { 95 | resizeMenus(index - (menus.length - 1)); 96 | } 97 | 98 | menus[index] = menu; 99 | updateMenus(); 100 | 101 | if (menu != this) { // compare references 102 | menu.setParent(this); 103 | } 104 | } 105 | 106 | private void updateMenus() { 107 | for (int index = 0; index< menus.length; ++index) { 108 | Menu menu = menuAt(index); 109 | int indexSize = menu.size() - 1; 110 | 111 | Menu next = (menus.length == (index + 1)) ? menu : menus[index + 1]; 112 | Menu back = (index == 0) ? menu : menus[index - 1]; 113 | 114 | menu.setItem(indexSize, MenuFactory.createItem(this.next, 115 | (p, c) -> next.showTo(p))); 116 | menu.setItem(indexSize - 8, MenuFactory.createItem(this.back, 117 | (p, c) -> back.showTo(p))); 118 | } 119 | } 120 | 121 | public Menu menuAt(int index) { 122 | return menus[index]; 123 | } 124 | 125 | public ItemStack nextItem() { 126 | return next; 127 | } 128 | 129 | public ItemStack backItem() { 130 | return back; 131 | } 132 | 133 | public void setNext(ItemStack next) { 134 | this.next = next; 135 | } 136 | 137 | public void setBack(ItemStack back) { 138 | this.back = back; 139 | } 140 | 141 | private void resizeMenus(int amount) { 142 | Menu[] menus = new Menu[(this.menus.length + amount)]; 143 | 144 | System.arraycopy(this.menus, 0, menus, 0, this.menus.length); 145 | 146 | for (int i = this.menus.length; i < menus.length; i++) { 147 | menus[i] = EMPTY_MENU; 148 | } 149 | 150 | this.menus = menus; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/io/mazenmc/menuapi/menu/ScrollingMenu.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Mazen Kotb, email@mazenmc.io 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package io.mazenmc.menuapi.menu; 17 | 18 | import io.mazenmc.menuapi.MenuFactory; 19 | import io.mazenmc.menuapi.items.Item; 20 | import org.bukkit.Material; 21 | import org.bukkit.Sound; 22 | import org.bukkit.entity.Player; 23 | import org.bukkit.inventory.ItemStack; 24 | 25 | import java.util.HashMap; 26 | import java.util.Map; 27 | 28 | /** 29 | * A menu that allows for scrolling. 30 | * 31 | * This class is designed to be put for a one viewers perspective, 32 | * meaning if there are multiple viewers one scroll will take place on all screens. 33 | * 34 | * Unlike other implementations, effects made to ScrollingMenu do not take place unless the flush method is called. 35 | * 36 | * When slots are set, your indexes are added by 10. Moreover, slot at (0,0) are at position (1,0) for the inventory or 37 | * slot at the index 0 are at the position 9. 38 | * 39 | * @see io.mazenmc.menuapi.menu.ScrollingMenu#flush() 40 | */ 41 | public class ScrollingMenu extends Menu { 42 | private static final ItemStack SCROLL = new ItemStack(Material.LADDER); 43 | 44 | private Map extendedMenu = new HashMap<>(); 45 | private ItemStack panel = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 0, (byte) 7); 46 | private int index = 0; 47 | 48 | protected ScrollingMenu(String name) { 49 | super(name, 54); 50 | flush(); 51 | } 52 | 53 | public static ScrollingMenu create(String name) { 54 | return new ScrollingMenu(name); 55 | } 56 | 57 | private void updateButtons() { 58 | ItemStack scrollDown = SCROLL; 59 | boolean canScrollDown = canScroll(ScrollDirection.DOWN); 60 | 61 | MultiMenu.setName(scrollDown, canScrollDown ? "&6Scroll down" : "&8Cannot scroll down!"); 62 | pushItem(0, 5, MenuFactory.createItem(scrollDown, (player, type) -> scrollDown(player))); 63 | 64 | ItemStack scrollUp = SCROLL; 65 | boolean canScrollUp = canScroll(ScrollDirection.UP); 66 | 67 | MultiMenu.setName(scrollUp, canScrollUp ? "&6Scroll up" : "&8Cannot scroll up!"); 68 | pushItem(0, 0, MenuFactory.createItem(scrollUp, (player, type) -> scrollUp(player))); 69 | } 70 | 71 | private int highestIndex() { 72 | int highestIndex = 0; 73 | 74 | for (Map.Entry entry : extendedMenu.entrySet()) { 75 | int ind = entry.getKey(); 76 | 77 | if (ind > highestIndex) { 78 | highestIndex = ind; 79 | } 80 | } 81 | 82 | return (int) Math.floor(highestIndex / 9); 83 | } 84 | 85 | public void setPanel(ItemStack panel) { 86 | this.panel = panel; 87 | } 88 | 89 | public void scrollDown(Player player) { 90 | if (!canScroll(ScrollDirection.DOWN)) { 91 | if (player != null) { 92 | player.playSound(player.getLocation(), Sound.ENTITY_CREEPER_HURT, 25, 50); 93 | } 94 | 95 | return; 96 | } 97 | 98 | ++index; 99 | flush(); 100 | 101 | if (player != null) { 102 | player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 50, 50); 103 | } 104 | } 105 | 106 | public void scrollDown() { //0c866fb1 107 | scrollDown(null); 108 | } 109 | 110 | public void scrollUp(Player player) { 111 | if (index == 0) { 112 | if (player != null) { 113 | player.playSound(player.getLocation(), Sound.ENTITY_CREEPER_HURT, 25, 50); 114 | } 115 | 116 | return; 117 | } 118 | 119 | --index; 120 | flush(); 121 | 122 | if (player != null) { 123 | player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 50, 50); 124 | } 125 | } 126 | 127 | public void scrollUp() { 128 | scrollUp(null); 129 | } 130 | 131 | public boolean canScroll(ScrollDirection direction) { 132 | switch (direction) { 133 | case UP: 134 | return index != 0; 135 | 136 | case DOWN: 137 | return highestIndex() != index; 138 | 139 | default: 140 | return false; 141 | } 142 | } 143 | 144 | public void flush() { 145 | for (int x = 0; x < 9; x++) { 146 | pushItem(x, 0, MenuFactory.createItem(panel, MenuFactory.EMPTY_LISTENER)); 147 | pushItem(x, 5, MenuFactory.createItem(panel, MenuFactory.EMPTY_LISTENER)); 148 | } 149 | 150 | for (int z = 1; z < 5; z++) { 151 | for (int x = 0; x < 9; x++) { 152 | pushItem(x, z, extendedMenu.get(((z - 1) * 9 + x) + index * 9)); 153 | } 154 | } 155 | 156 | updateButtons(); 157 | } 158 | 159 | @Override 160 | public Menu setItem(int index, Item item) { 161 | extendedMenu.put(index, item); 162 | return this; 163 | } 164 | 165 | private void pushItem(int index, Item item) { 166 | if (item == null) { 167 | inventory().setItem(index, null); 168 | } else { 169 | inventory().setItem(index, item.stack()); 170 | items.put(index, item); 171 | } 172 | } 173 | 174 | private void pushItem(int x, int z, Item item) { 175 | pushItem(z * 9 + x, item); 176 | } 177 | 178 | public enum ScrollDirection { 179 | UP, 180 | DOWN 181 | } 182 | } 183 | --------------------------------------------------------------------------------