Reworked GUIBuilder / GUIType

This commit is contained in:
NichtStudioCode 2021-08-22 14:44:19 +02:00
parent 82ba871ae3
commit ca0dff2153
9 changed files with 247 additions and 95 deletions

@ -2,7 +2,7 @@ package de.studiocode.invui.gui.builder;
import de.studiocode.invui.gui.GUI; import de.studiocode.invui.gui.GUI;
import de.studiocode.invui.gui.SlotElement; import de.studiocode.invui.gui.SlotElement;
import de.studiocode.invui.gui.impl.*; import de.studiocode.invui.gui.builder.guitype.GUIType;
import de.studiocode.invui.gui.structure.Marker; import de.studiocode.invui.gui.structure.Marker;
import de.studiocode.invui.gui.structure.Structure; import de.studiocode.invui.gui.structure.Structure;
import de.studiocode.invui.item.Item; import de.studiocode.invui.item.Item;
@ -10,143 +10,96 @@ import de.studiocode.invui.item.ItemProvider;
import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import static de.studiocode.invui.gui.builder.GUIType.*;
/** /**
* A builder class to easily construct {@link GUI}s.<br> * A builder class to easily construct {@link GUI}s.<br>
* It provides similar functionality to Bukkit's {@link ShapedRecipe}, as it * It provides similar functionality to Bukkit's {@link ShapedRecipe}, as it
* allows for a structure String which defines the layout of the {@link GUI}. * allows for a structure String which defines the layout of the {@link GUI}.
*/ */
public class GUIBuilder { public class GUIBuilder<G extends GUI> {
private final GUIType guiType; private final GUIType<G> guiType;
private final int width; private final GUIContext context;
private final int height;
private Structure structure; public GUIBuilder(@NotNull GUIType<G> guiType, int width, int height) {
private List<Item> items = new ArrayList<>();
private List<GUI> guis = new ArrayList<>();
public GUIBuilder(@NotNull GUIType guiType, int width, int height) {
this.guiType = guiType; this.guiType = guiType;
this.width = width; this.context = new GUIContext(width, height);
this.height = height;
} }
public GUIBuilder setStructure(@NotNull String structureData) { public GUIBuilder<G> setStructure(@NotNull String structureData) {
this.structure = new Structure(structureData); context.setStructure(new Structure(structureData));
return this; return this;
} }
public GUIBuilder setStructure(@NotNull Structure structure) { public GUIBuilder<G> setStructure(@NotNull Structure structure) {
this.structure = structure; context.setStructure(structure);
return this; return this;
} }
public GUIBuilder addIngredient(char key, @NotNull ItemProvider itemProvider) { public GUIBuilder<G> addIngredient(char key, @NotNull ItemProvider itemProvider) {
structure.addIngredient(key, itemProvider); context.getStructure().addIngredient(key, itemProvider);
return this; return this;
} }
public GUIBuilder addIngredient(char key, @NotNull Item item) { public GUIBuilder<G> addIngredient(char key, @NotNull Item item) {
structure.addIngredient(key, item); context.getStructure().addIngredient(key, item);
return this; return this;
} }
public GUIBuilder addIngredient(char key, @NotNull SlotElement element) { public GUIBuilder<G> addIngredient(char key, @NotNull SlotElement element) {
structure.addIngredient(key, element); context.getStructure().addIngredient(key, element);
return this; return this;
} }
public GUIBuilder addIngredient(char key, @NotNull Marker marker) { public GUIBuilder<G> addIngredient(char key, @NotNull Marker marker) {
structure.addIngredient(key, marker); context.getStructure().addIngredient(key, marker);
return this; return this;
} }
public GUIBuilder addIngredient(char key, @NotNull Supplier<? extends Item> itemSupplier) { public GUIBuilder<G> addIngredient(char key, @NotNull Supplier<? extends Item> itemSupplier) {
structure.addIngredient(key, itemSupplier); context.getStructure().addIngredient(key, itemSupplier);
return this; return this;
} }
public GUIBuilder addIngredientElementSupplier(char key, @NotNull Supplier<? extends SlotElement> elementSupplier) { public GUIBuilder<G> addIngredientElementSupplier(char key, @NotNull Supplier<? extends SlotElement> elementSupplier) {
structure.addIngredientElementSupplier(key, elementSupplier); context.getStructure().addIngredientElementSupplier(key, elementSupplier);
return this; return this;
} }
public GUIBuilder setItems(@NotNull List<Item> items) { public GUIBuilder<G> setItems(@NotNull List<Item> items) {
if (guiType != PAGED_ITEMS && guiType != SCROLL) if (!guiType.acceptsItems())
throw new UnsupportedOperationException("Items cannot be set in this gui type."); throw new UnsupportedOperationException("Items cannot be set in this gui type.");
this.items = items; context.setItems(items);
return this; return this;
} }
public GUIBuilder addItem(@NotNull Item item) { public GUIBuilder<G> addItem(@NotNull Item item) {
if (guiType != PAGED_ITEMS && guiType != SCROLL) if (!guiType.acceptsItems())
throw new UnsupportedOperationException("Items cannot be set in this gui type."); throw new UnsupportedOperationException("Items cannot be set in this gui type.");
items.add(item); context.getItems().add(item);
return this; return this;
} }
public GUIBuilder setGUIs(@NotNull List<GUI> guis) { public GUIBuilder<G> setGUIs(@NotNull List<GUI> guis) {
if (guiType != PAGED_GUIs && guiType != TAB) if (!guiType.acceptsGUIs())
throw new UnsupportedOperationException("GUIs cannot be set in this gui type."); throw new UnsupportedOperationException("GUIs cannot be set in this gui type.");
this.guis = guis; context.setGuis(guis);
return this; return this;
} }
public GUIBuilder addGUI(@NotNull GUI gui) { public GUIBuilder<G> addGUI(@NotNull GUI gui) {
if (guiType != PAGED_GUIs && guiType != TAB) if (!guiType.acceptsGUIs())
throw new UnsupportedOperationException("GUIs cannot be set in this gui type."); throw new UnsupportedOperationException("GUIs cannot be set in this gui type.");
guis.add(gui); context.getGuis().add(gui);
return this; return this;
} }
public GUI build() { public G build() {
switch (guiType) { if (context.getStructure() == null) throw new IllegalStateException("GUIContext has not been set yet.");
return guiType.createGUI(context);
case NORMAL:
return buildSimpleGUI();
case PAGED_ITEMS:
return buildSimplePagedItemsGUI();
case PAGED_GUIs:
return buildSimplePagedNestedGUI();
case TAB:
return buildSimpleTabGUI();
case SCROLL:
return buildSimpleScrollGUI();
default:
throw new UnsupportedOperationException("Unknown GUI type");
}
}
private SimpleGUI buildSimpleGUI() {
return new SimpleGUI(width, height, structure);
}
private SimplePagedItemsGUI buildSimplePagedItemsGUI() {
return new SimplePagedItemsGUI(width, height, items, structure);
}
private SimplePagedNestedGUI buildSimplePagedNestedGUI() {
return new SimplePagedNestedGUI(width, height, guis, structure);
}
private SimpleTabGUI buildSimpleTabGUI() {
return new SimpleTabGUI(width, height, guis, structure);
}
private SimpleScrollGUI buildSimpleScrollGUI() {
return new SimpleScrollGUI(width, height, items, structure);
} }
} }

@ -0,0 +1,61 @@
package de.studiocode.invui.gui.builder;
import de.studiocode.invui.gui.GUI;
import de.studiocode.invui.gui.builder.guitype.GUIType;
import de.studiocode.invui.gui.structure.Structure;
import de.studiocode.invui.item.Item;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* The {@link GUIContext} contains all information from the {@link GUIBuilder} to be passed to
* an instance of {@link GUIType} to create a new {@link GUI}.
*/
public class GUIContext {
private final int width;
private final int height;
private Structure structure;
private List<GUI> guis = new ArrayList<>();
private List<Item> items = new ArrayList<>();
public GUIContext(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Structure getStructure() {
return structure;
}
public void setStructure(@NotNull Structure structure) {
this.structure = structure;
}
public List<GUI> getGuis() {
return guis;
}
public void setGuis(@NotNull List<GUI> guis) {
this.guis = guis;
}
public List<Item> getItems() {
return items;
}
public void setItems(@NotNull List<Item> items) {
this.items = items;
}
}

@ -1,11 +0,0 @@
package de.studiocode.invui.gui.builder;
public enum GUIType {
NORMAL,
PAGED_ITEMS,
PAGED_GUIs,
TAB,
SCROLL
}

@ -0,0 +1,34 @@
package de.studiocode.invui.gui.builder.guitype;
import de.studiocode.invui.gui.GUI;
import de.studiocode.invui.gui.builder.GUIContext;
import de.studiocode.invui.gui.impl.*;
import de.studiocode.invui.item.Item;
public interface GUIType<G extends GUI> {
GUIType<SimpleGUI> NORMAL = new NormalGUIType();
GUIType<SimplePagedItemsGUI> PAGED_ITEMS = new PagedItemsGUIType();
GUIType<SimplePagedNestedGUI> PAGED_GUIs = new PagedGUIsGUIType();
GUIType<SimpleTabGUI> TAB = new TabGUIType();
GUIType<SimpleScrollGUI> SCROLL = new ScrollGUIType();
/**
* Creates a {@link GUI} of type {@link G} with the given {@link GUIContext}
*
* @param context The {@link GUIContext} to create the {@link G} from.
* @return The created {@link G}
*/
G createGUI(GUIContext context);
/**
* @return If this {@link GUIType} accepts {@link GUI GUIs} from the {@link GUIContext}.
*/
boolean acceptsGUIs();
/**
* @return If this {@link GUIType} accepts {@link Item Items} from the {@link GUIContext}.
*/
boolean acceptsItems();
}

@ -0,0 +1,23 @@
package de.studiocode.invui.gui.builder.guitype;
import de.studiocode.invui.gui.builder.GUIContext;
import de.studiocode.invui.gui.impl.SimpleGUI;
class NormalGUIType implements GUIType<SimpleGUI> {
@Override
public SimpleGUI createGUI(GUIContext context) {
return new SimpleGUI(context.getWidth(), context.getHeight(), context.getStructure());
}
@Override
public boolean acceptsGUIs() {
return false;
}
@Override
public boolean acceptsItems() {
return false;
}
}

@ -0,0 +1,23 @@
package de.studiocode.invui.gui.builder.guitype;
import de.studiocode.invui.gui.builder.GUIContext;
import de.studiocode.invui.gui.impl.SimplePagedNestedGUI;
class PagedGUIsGUIType implements GUIType<SimplePagedNestedGUI> {
@Override
public SimplePagedNestedGUI createGUI(GUIContext context) {
return new SimplePagedNestedGUI(context.getWidth(), context.getHeight(), context.getGuis(), context.getStructure());
}
@Override
public boolean acceptsGUIs() {
return true;
}
@Override
public boolean acceptsItems() {
return false;
}
}

@ -0,0 +1,23 @@
package de.studiocode.invui.gui.builder.guitype;
import de.studiocode.invui.gui.builder.GUIContext;
import de.studiocode.invui.gui.impl.SimplePagedItemsGUI;
class PagedItemsGUIType implements GUIType<SimplePagedItemsGUI> {
@Override
public SimplePagedItemsGUI createGUI(GUIContext context) {
return new SimplePagedItemsGUI(context.getWidth(), context.getHeight(), context.getItems(), context.getStructure());
}
@Override
public boolean acceptsGUIs() {
return false;
}
@Override
public boolean acceptsItems() {
return true;
}
}

@ -0,0 +1,23 @@
package de.studiocode.invui.gui.builder.guitype;
import de.studiocode.invui.gui.builder.GUIContext;
import de.studiocode.invui.gui.impl.SimpleScrollGUI;
class ScrollGUIType implements GUIType<SimpleScrollGUI> {
@Override
public SimpleScrollGUI createGUI(GUIContext context) {
return new SimpleScrollGUI(context.getWidth(), context.getHeight(), context.getItems(), context.getStructure());
}
@Override
public boolean acceptsGUIs() {
return false;
}
@Override
public boolean acceptsItems() {
return true;
}
}

@ -0,0 +1,23 @@
package de.studiocode.invui.gui.builder.guitype;
import de.studiocode.invui.gui.builder.GUIContext;
import de.studiocode.invui.gui.impl.SimpleTabGUI;
class TabGUIType implements GUIType<SimpleTabGUI> {
@Override
public SimpleTabGUI createGUI(GUIContext context) {
return new SimpleTabGUI(context.getWidth(), context.getHeight(), context.getGuis(), context.getStructure());
}
@Override
public boolean acceptsGUIs() {
return true;
}
@Override
public boolean acceptsItems() {
return false;
}
}