diff --git a/src/main/java/de/studiocode/invgui/gui/builder/GUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/GUIBuilder.java index 6310197..74a650a 100644 --- a/src/main/java/de/studiocode/invgui/gui/builder/GUIBuilder.java +++ b/src/main/java/de/studiocode/invgui/gui/builder/GUIBuilder.java @@ -2,16 +2,47 @@ package de.studiocode.invgui.gui.builder; import de.studiocode.invgui.gui.GUI; import de.studiocode.invgui.gui.SlotElement; +import de.studiocode.invgui.gui.impl.SimpleGUI; import de.studiocode.invgui.item.Item; import org.bukkit.inventory.ShapedRecipe; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** - * A utility class to easily construct {@link GUI}s.
+ * A builder class to easily construct {@link GUI}s.
* It provides similar functionality to Bukkit's {@link ShapedRecipe}, as it * allows for a structure String which defines the layout of the {@link GUI}. */ -public interface GUIBuilder { +public class GUIBuilder { + + protected final int width; + protected final int height; + private final int size; + + private final Map ingredientMap = new HashMap<>(); + + private String structure; + + public GUIBuilder(int width, int height) { + this.width = width; + this.height = height; + this.size = width * height; + } + + /** + * Builds the {@link GUI}. + * + * @return The built {@link GUI} + */ + public GUI build() { + SimpleGUI gui = new SimpleGUI(width, height); + setSlotElements(gui); + return gui; + } /** * Sets the structure of the {@link GUI}. @@ -20,7 +51,13 @@ public interface GUIBuilder { * * @param structure The structure {@link String} */ - void setStructure(@NotNull String structure); + public GUIBuilder setStructure(@NotNull String structure) { + String cleanedStructure = structure.replace(" ", "").replace("\n", ""); + if (cleanedStructure.length() != size) throw new IllegalArgumentException("Structure length does not match size"); + this.structure = cleanedStructure; + + return this; + } /** * Sets an ingredient for the structure String, which will later be @@ -29,7 +66,10 @@ public interface GUIBuilder { * @param key The ingredient key * @param item The {@link Item} */ - void setIngredient(char key, @NotNull Item item); + public GUIBuilder setIngredient(char key, @NotNull Item item) { + ingredientMap.put(key, new Ingredient(item)); + return this; + } /** * Sets an ingredient for the structure String, which will later be @@ -38,13 +78,88 @@ public interface GUIBuilder { * @param key The ingredient key * @param slotElement The {@link SlotElement} */ - void setIngredient(char key, @NotNull SlotElement slotElement); + public GUIBuilder setIngredient(char key, @NotNull SlotElement slotElement) { + ingredientMap.put(key, new Ingredient(slotElement)); + return this; + } - /** - * Builds the {@link GUI}. - * - * @return The built {@link GUI} - */ - GUI build(); + protected void setIngredient(char key, int special) { + ingredientMap.put(key, new Ingredient(special)); + } + + private Ingredient[] parseStructure() { + if (structure == null) throw new IllegalStateException("Structure has not been set yet."); + + Ingredient[] ingredients = new Ingredient[size]; + int i = 0; + for (char c : structure.toCharArray()) { + if (c != '.') ingredients[i] = this.ingredientMap.get(c); + i++; + } + + return ingredients; + } + + protected void setSlotElements(GUI gui) { + Ingredient[] ingredients = parseStructure(); + for (int i = 0; i < gui.getSize(); i++) { + Ingredient ingredient = ingredients[i]; + if (ingredient != null && ingredient.isSlotElement()) + gui.setSlotElement(i, ingredient.getSlotElement()); + } + } + + protected int[] findIndicesOf(int special) { + List indices = new ArrayList<>(); + + Ingredient[] ingredients = parseStructure(); + for (int i = 0; i < size; i++) { + Ingredient ingredient = ingredients[i]; + if (ingredient != null && ingredient.isSpecial() && ingredient.getSpecial() == special) + indices.add(i); + } + + return indices.stream().mapToInt(Integer::intValue).toArray(); + } + + static class Ingredient { + + private final SlotElement slotElement; + private final int special; + + public Ingredient(Item item) { + this.slotElement = new SlotElement.ItemSlotElement(item); + this.special = -1; + } + + public Ingredient(SlotElement slotElement) { + this.slotElement = slotElement; + this.special = -1; + } + + public Ingredient(int special) { + this.special = special; + this.slotElement = null; + } + + public SlotElement getSlotElement() { + if (isSpecial()) throw new IllegalStateException("Ingredient is special"); + return slotElement; + } + + public int getSpecial() { + if (isSlotElement()) throw new IllegalStateException("Ingredient is item"); + return special; + } + + public boolean isSlotElement() { + return slotElement != null; + } + + public boolean isSpecial() { + return slotElement == null; + } + + } } diff --git a/src/main/java/de/studiocode/invgui/gui/builder/PagedGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/PagedGUIBuilder.java new file mode 100644 index 0000000..2eeb593 --- /dev/null +++ b/src/main/java/de/studiocode/invgui/gui/builder/PagedGUIBuilder.java @@ -0,0 +1,119 @@ +package de.studiocode.invgui.gui.builder; + +import de.studiocode.invgui.gui.GUI; +import de.studiocode.invgui.gui.SlotElement; +import de.studiocode.invgui.gui.impl.PagedGUI; +import de.studiocode.invgui.gui.impl.SimplePagedGUIs; +import de.studiocode.invgui.gui.impl.SimplePagedItemsGUI; +import de.studiocode.invgui.item.Item; +import de.studiocode.invgui.item.itembuilder.ItemBuilder; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.function.Function; + +public class PagedGUIBuilder extends GUIBuilder { + + private final ContentType contentType; + + private Function backFunction; + private Function forwardFunction; + private int[] listSlots; + private List content; + + public PagedGUIBuilder(ContentType contentType, int width, int height) { + super(width, height); + this.contentType = contentType; + } + + @SuppressWarnings("unchecked") + @Override + public PagedGUI build() { + int[] listSlots = this.listSlots != null ? this.listSlots : findIndicesOf(2); + int[] backSlots = findIndicesOf(0); + int[] forwardSlots = findIndicesOf(1); + + if (listSlots.length == 0) throw new IllegalStateException("No list slots have been set."); + if (backSlots.length == 0) throw new IllegalStateException("Not back slot has been set."); + if (forwardSlots.length == 0) throw new IllegalStateException("No forward slot has been set."); + if (content == null) throw new IllegalStateException("Content has not been set."); + if (forwardFunction == null) throw new IllegalStateException("Forward function has not been set."); + if (backFunction == null) throw new IllegalStateException("Back function has not been set"); + + int backSlot = backSlots[0]; + int forwardSlot = forwardSlots[0]; + + PagedGUI gui; + if (contentType == ContentType.GUI) { + gui = new SimplePagedGUIs(width, height, backSlot, backFunction, + forwardSlot, forwardFunction, (List) content, listSlots); + } else { + gui = new SimplePagedItemsGUI(width, height, backSlot, backFunction, + forwardSlot, forwardFunction, (List) content, listSlots); + } + + setSlotElements(gui); + return gui; + } + + public PagedGUIBuilder setGUIs(List guis) { + if (contentType != ContentType.GUI) + throw new IllegalStateException("Can't set guis if ContentType is not GUI"); + content = guis; + + return this; + } + + public PagedGUIBuilder setItems(List items) { + if (contentType != ContentType.SINGLE_ITEMS) + throw new IllegalStateException("Can't set items if ContentType is not SINGLE_ITEMS"); + content = items; + + return this; + } + + public PagedGUIBuilder setListSlots(int[] listSlots) { + this.listSlots = listSlots; + return this; + } + + public PagedGUIBuilder setListSlotIngredient(char key) { + setIngredient(key, 2); + return this; + } + + public PagedGUIBuilder setBackItem(char key, Function backFunction) { + setIngredient(key, 0); + this.backFunction = backFunction; + return this; + } + + public PagedGUIBuilder setForwardItem(char key, Function forwardFunction) { + setIngredient(key, 1); + this.forwardFunction = forwardFunction; + return this; + } + + @Override + public PagedGUIBuilder setStructure(@NotNull String structure) { + return (PagedGUIBuilder) super.setStructure(structure); + } + + @Override + public PagedGUIBuilder setIngredient(char key, @NotNull Item item) { + return (PagedGUIBuilder) super.setIngredient(key, item); + } + + @Override + public PagedGUIBuilder setIngredient(char key, @NotNull SlotElement slotElement) { + return (PagedGUIBuilder) super.setIngredient(key, slotElement); + } + + public enum ContentType { + + SINGLE_ITEMS, + GUI + + } + +} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/TabGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/TabGUIBuilder.java new file mode 100644 index 0000000..87bfab1 --- /dev/null +++ b/src/main/java/de/studiocode/invgui/gui/builder/TabGUIBuilder.java @@ -0,0 +1,79 @@ +package de.studiocode.invgui.gui.builder; + +import de.studiocode.invgui.gui.GUI; +import de.studiocode.invgui.gui.SlotElement; +import de.studiocode.invgui.gui.impl.SimpleTabGUI; +import de.studiocode.invgui.gui.impl.TabGUI; +import de.studiocode.invgui.item.Item; +import de.studiocode.invgui.item.itembuilder.ItemBuilder; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedHashMap; +import java.util.function.Function; + +public class TabGUIBuilder extends GUIBuilder { + + private final LinkedHashMap> tabs = new LinkedHashMap<>(); + + private int[] listSlots; + private int[] tabItemSlots; + + public TabGUIBuilder(int width, int height) { + super(width, height); + } + + @Override + public TabGUI build() { + int[] listSlots = this.listSlots != null ? this.listSlots : findIndicesOf(0); + int[] tabItemSlots = this.tabItemSlots != null ? this.tabItemSlots : findIndicesOf(1); + + if (listSlots.length == 0) throw new IllegalStateException("No list slots have been set."); + if (tabItemSlots.length != tabs.size()) throw new IllegalStateException("TabItemSlots length has to be the same as tabs size"); + + SimpleTabGUI tabGUI = new SimpleTabGUI(width, height, tabs, listSlots, tabItemSlots); + setSlotElements(tabGUI); + + return tabGUI; + } + + public TabGUIBuilder addTab(GUI gui, Function builderFunction) { + tabs.put(gui, builderFunction); + return this; + } + + public TabGUIBuilder setListSlotIngredient(char key) { + setIngredient(key, 0); + return this; + } + + public TabGUIBuilder setTabSlotIngredient(char key) { + setIngredient(key, 1); + return this; + } + + public TabGUIBuilder setListSlots(int[] listSlots) { + this.listSlots = listSlots; + return this; + } + + public TabGUIBuilder setTabItemSlots(int[] tabItemSlots) { + this.tabItemSlots = tabItemSlots; + return this; + } + + @Override + public TabGUIBuilder setStructure(@NotNull String structure) { + return (TabGUIBuilder) super.setStructure(structure); + } + + @Override + public TabGUIBuilder setIngredient(char key, @NotNull Item item) { + return (TabGUIBuilder) super.setIngredient(key, item); + } + + @Override + public TabGUIBuilder setIngredient(char key, @NotNull SlotElement slotElement) { + return (TabGUIBuilder) super.setIngredient(key, slotElement); + } + +} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/impl/BaseGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/impl/BaseGUIBuilder.java deleted file mode 100644 index 99a89ee..0000000 --- a/src/main/java/de/studiocode/invgui/gui/builder/impl/BaseGUIBuilder.java +++ /dev/null @@ -1,136 +0,0 @@ -package de.studiocode.invgui.gui.builder.impl; - -import de.studiocode.invgui.gui.GUI; -import de.studiocode.invgui.gui.SlotElement; -import de.studiocode.invgui.gui.builder.GUIBuilder; -import de.studiocode.invgui.item.Item; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public abstract class BaseGUIBuilder implements GUIBuilder { - - private final int width; - private final int height; - private final int size; - - private final Map ingredientMap = new HashMap<>(); - - private String structure; - - public BaseGUIBuilder(int width, int height) { - this.width = width; - this.height = height; - this.size = width * height; - } - - @Override - public void setStructure(@NotNull String structure) { - structure = structure.replace(" ", ""); - if (structure.length() != size) throw new IllegalArgumentException("Structure length does not match size"); - this.structure = structure; - } - - @Override - public void setIngredient(char key, @NotNull Item item) { - ingredientMap.put(key, new Ingredient(item)); - } - - @Override - public void setIngredient(char key, @NotNull SlotElement slotElement) { - ingredientMap.put(key, new Ingredient(slotElement)); - } - - public void setIngredient(char key, int special) { - ingredientMap.put(key, new Ingredient(special)); - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - private Ingredient[] parseStructure() { - if (structure == null) throw new IllegalStateException("Structure has not been set yet."); - - Ingredient[] ingredients = new Ingredient[size]; - int i = 0; - for (char c : structure.toCharArray()) { - if (c != '.') ingredients[i] = this.ingredientMap.get(c); - i++; - } - - return ingredients; - } - - protected void setSlotElements(GUI gui) { - Ingredient[] ingredients = parseStructure(); - for (int i = 0; i < gui.getSize(); i++) { - Ingredient ingredient = ingredients[i]; - if (ingredient != null && ingredient.isSlotElement()) - gui.setSlotElement(i, ingredient.getSlotElement()); - } - } - - public List findIndicesOf(int special) { - List indices = new ArrayList<>(); - - Ingredient[] ingredients = parseStructure(); - for (int i = 0; i < size; i++) { - Ingredient ingredient = ingredients[i]; - if (ingredient != null && ingredient.isSpecial() && ingredient.getSpecial() == special) - indices.add(i); - } - - return indices; - } - - public abstract GUI build(); - - static class Ingredient { - - private final SlotElement slotElement; - private final int special; - - public Ingredient(Item item) { - this.slotElement = new SlotElement.ItemSlotElement(item); - this.special = -1; - } - - public Ingredient(SlotElement slotElement) { - this.slotElement = slotElement; - this.special = -1; - } - - public Ingredient(int special) { - this.special = special; - this.slotElement = null; - } - - public SlotElement getSlotElement() { - if (isSpecial()) throw new IllegalStateException("Ingredient is special"); - return slotElement; - } - - public int getSpecial() { - if (isSlotElement()) throw new IllegalStateException("Ingredient is item"); - return special; - } - - public boolean isSlotElement() { - return slotElement != null; - } - - public boolean isSpecial() { - return slotElement == null; - } - - } - -} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/impl/PagedGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/impl/PagedGUIBuilder.java deleted file mode 100644 index 2fb6fad..0000000 --- a/src/main/java/de/studiocode/invgui/gui/builder/impl/PagedGUIBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -package de.studiocode.invgui.gui.builder.impl; - -import de.studiocode.invgui.gui.impl.PagedGUI; -import de.studiocode.invgui.item.itembuilder.ItemBuilder; - -import java.util.List; -import java.util.function.Function; - -public abstract class PagedGUIBuilder extends BaseGUIBuilder { - - private Function backFunction; - private Function forwardFunction; - private int[] listSlots; - - public PagedGUIBuilder(int width, int height) { - super(width, height); - } - - protected int getBackItemIndex() { - List indices = findIndicesOf(0); - if (indices.isEmpty()) - throw new IllegalStateException("BackItem index is not set"); - - return indices.get(0); - } - - protected int getForwardItemIndex() { - List indices = findIndicesOf(1); - if (indices.isEmpty()) - throw new IllegalStateException("ForwardItem index is not set"); - - return indices.get(0); - } - - protected int[] getListSlots() { - if (listSlots == null) - return findIndicesOf(2).stream().mapToInt(Integer::intValue).toArray(); - else return listSlots; - } - - public void setListSlots(int[] listSlots) { - this.listSlots = listSlots; - } - - public void setListSlotIngredient(char key) { - setIngredient(key, 2); - } - - public void setBackItem(char key, Function backFunction) { - setIngredient(key, 0); - this.backFunction = backFunction; - } - - protected Function getBackFunction() { - return backFunction; - } - - public void setForwardItem(char key, Function forwardFunction) { - setIngredient(key, 1); - this.forwardFunction = forwardFunction; - } - - protected Function getForwardFunction() { - return forwardFunction; - } - -} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimpleGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/impl/SimpleGUIBuilder.java deleted file mode 100644 index df377f8..0000000 --- a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimpleGUIBuilder.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.studiocode.invgui.gui.builder.impl; - -import de.studiocode.invgui.gui.impl.SimpleGUI; - -public class SimpleGUIBuilder extends BaseGUIBuilder { - - public SimpleGUIBuilder(int width, int height) { - super(width, height); - } - - @Override - public SimpleGUI build() { - SimpleGUI gui = new SimpleGUI(getWidth(), getHeight()); - setSlotElements(gui); - return gui; - } - -} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimplePagedGUIsBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/impl/SimplePagedGUIsBuilder.java deleted file mode 100644 index 0c7fac2..0000000 --- a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimplePagedGUIsBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.studiocode.invgui.gui.builder.impl; - -import de.studiocode.invgui.gui.GUI; -import de.studiocode.invgui.gui.impl.SimplePagedGUIs; - -import java.util.List; - -public class SimplePagedGUIsBuilder extends PagedGUIBuilder { - - private List guis; - - public SimplePagedGUIsBuilder(int width, int height) { - super(width, height); - } - - @Override - public SimplePagedGUIs build() { - if (getBackFunction() == null || getForwardFunction() == null) - throw new IllegalStateException("BackBuilder or ForwardBuilder haven't been set yet"); - if (guis == null) - throw new IllegalStateException("GUIs haven't been set yet"); - - SimplePagedGUIs gui = new SimplePagedGUIs(getWidth(), getHeight(), getBackItemIndex(), getBackFunction(), - getForwardItemIndex(), getForwardFunction(), guis, getListSlots()); - setSlotElements(gui); - - return gui; - } - - public void setGuis(List guis) { - this.guis = guis; - } - -} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimplePagedItemsGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/impl/SimplePagedItemsGUIBuilder.java deleted file mode 100644 index 7ba3e6e..0000000 --- a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimplePagedItemsGUIBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.studiocode.invgui.gui.builder.impl; - -import de.studiocode.invgui.gui.impl.SimplePagedItemsGUI; -import de.studiocode.invgui.item.Item; - -import java.util.List; - -public class SimplePagedItemsGUIBuilder extends PagedGUIBuilder { - - private List items; - - public SimplePagedItemsGUIBuilder(int width, int height) { - super(width, height); - } - - @Override - public SimplePagedItemsGUI build() { - if (getBackFunction() == null || getForwardFunction() == null) - throw new IllegalStateException("BackBuilder or ForwardBuilder haven't been set yet"); - if (items == null) - throw new IllegalStateException("Items haven't been set yet"); - - SimplePagedItemsGUI gui = new SimplePagedItemsGUI(getWidth(), getHeight(), getBackItemIndex(), getBackFunction(), - getForwardItemIndex(), getForwardFunction(), items, getListSlots()); - setSlotElements(gui); - - return gui; - } - - public void setItems(List items) { - this.items = items; - } - -} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimpleTabGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/impl/SimpleTabGUIBuilder.java deleted file mode 100644 index d812316..0000000 --- a/src/main/java/de/studiocode/invgui/gui/builder/impl/SimpleTabGUIBuilder.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.studiocode.invgui.gui.builder.impl; - -import de.studiocode.invgui.gui.GUI; -import de.studiocode.invgui.gui.impl.SimpleTabGUI; - -public class SimpleTabGUIBuilder extends TabGUIBuilder { - - public SimpleTabGUIBuilder(int width, int height) { - super(width, height); - } - - @Override - public GUI build() { - if (getTabItemSlots().length != getTabs().size()) - throw new IllegalStateException("TabItemSlots length has to be the same as tabs size"); - - SimpleTabGUI tabGUI = new SimpleTabGUI(getWidth(), getHeight(), getTabs(), getListSlots(), getTabItemSlots()); - setSlotElements(tabGUI); - - return tabGUI; - } - -} diff --git a/src/main/java/de/studiocode/invgui/gui/builder/impl/TabGUIBuilder.java b/src/main/java/de/studiocode/invgui/gui/builder/impl/TabGUIBuilder.java deleted file mode 100644 index cf23562..0000000 --- a/src/main/java/de/studiocode/invgui/gui/builder/impl/TabGUIBuilder.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.studiocode.invgui.gui.builder.impl; - -import de.studiocode.invgui.gui.GUI; -import de.studiocode.invgui.gui.impl.TabGUI; -import de.studiocode.invgui.item.itembuilder.ItemBuilder; - -import java.util.LinkedHashMap; -import java.util.function.Function; - -public abstract class TabGUIBuilder extends BaseGUIBuilder { - - private final LinkedHashMap> tabs = new LinkedHashMap<>(); - - private int[] listSlots; - private int[] tabItemSlots; - - public TabGUIBuilder(int width, int height) { - super(width, height); - } - - public void addTab(GUI gui, Function builderFunction) { - tabs.put(gui, builderFunction); - } - - public void setListSlotIngredient(char key) { - setIngredient(key, 0); - } - - public void setTabSlotIngredient(char key) { - setIngredient(key, 1); - } - - public void setListSlots(int[] listSlots) { - this.listSlots = listSlots; - } - - public void setTabItemSlots(int[] tabItemSlots) { - this.tabItemSlots = tabItemSlots; - } - - protected int[] getListSlots() { - if (listSlots == null) { - return findIndicesOf(0).stream().mapToInt(Integer::intValue).toArray(); - } else return listSlots; - } - - protected int[] getTabItemSlots() { - if (tabItemSlots == null) { - return findIndicesOf(1).stream().mapToInt(Integer::intValue).toArray(); - } else return tabItemSlots; - } - - protected LinkedHashMap> getTabs() { - return tabs; - } - -}