From 4f6dee68619d0ddefa776d05e5b077295221693f Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Sun, 26 Feb 2023 15:29:57 +0100 Subject: [PATCH] Improved Gui- and Window builders --- .../kotlin/xyz/xenondevs/invui/GuiBuilders.kt | 11 - .../xyz/xenondevs/invui/ItemBuilders.kt | 2 +- .../xyz/xenondevs/invui/WindowBuilders.kt | 11 - .../invui/adventure/AdventureItemBuilders.kt | 6 +- .../adventure/AdventureWindowContexts.kt | 9 +- .../xyz/xenondevs/invui/gui/AbstractGui.java | 135 +++++++ .../xenondevs/invui/gui/AbstractPagedGui.java | 58 ++- .../invui/gui/AbstractScrollGui.java | 56 ++- .../xenondevs/invui/gui/AbstractTabGui.java | 53 +++ .../java/xyz/xenondevs/invui/gui/Gui.java | 228 ++++++++++- .../invui/gui/{impl => }/NormalGuiImpl.java | 25 +- .../xyz/xenondevs/invui/gui/PagedGui.java | 105 ++++- .../gui/{impl => }/PagedItemsGuiImpl.java | 28 +- .../gui/{impl => }/PagedNestedGuiImpl.java | 29 +- .../xyz/xenondevs/invui/gui/ScrollGui.java | 129 +++++- .../{impl => }/ScrollInventoryGuiImpl.java | 28 +- .../gui/{impl => }/ScrollItemsGuiImpl.java | 28 +- .../gui/{impl => }/ScrollNestedGuiImpl.java | 30 +- .../java/xyz/xenondevs/invui/gui/TabGui.java | 70 +++- .../invui/gui/{impl => }/TabGuiImpl.java | 31 +- .../invui/gui/builder/AbstractGuiBuilder.java | 159 -------- .../gui/builder/AbstractPagedGuiBuilder.java | 60 --- .../gui/builder/AbstractScrollGuiBuilder.java | 60 --- .../invui/gui/builder/GuiBuilder.java | 15 - .../xenondevs/invui/gui/builder/GuiType.java | 42 -- .../invui/gui/builder/NormalGuiBuilder.java | 33 -- .../gui/builder/PagedItemsGuiBuilder.java | 34 -- .../gui/builder/PagedNestedGuiBuilder.java | 34 -- .../builder/ScrollInventoryGuiBuilder.java | 34 -- .../gui/builder/ScrollItemsGuiBuilder.java | 34 -- .../gui/builder/ScrollNestedGuiBuilder.java | 34 -- .../invui/gui/builder/TabGuiBuilder.java | 83 ---- .../invui/window/AbstractSingleWindow.java | 30 ++ .../invui/window/AbstractSplitWindow.java | 50 +++ .../invui/window/AbstractWindow.java | 105 +++++ .../{impl => }/AnvilSingleWindowImpl.java | 52 ++- .../invui/window/AnvilSplitWindowImpl.java | 105 +++++ .../xenondevs/invui/window/AnvilWindow.java | 44 ++- .../CartographySingleWindowImpl.java | 33 +- .../CartographySplitWindowImpl.java | 41 +- .../invui/window/CartographyWindow.java | 30 ++ .../{impl => }/NormalMergedWindowImpl.java | 31 +- .../invui/window/NormalSingleWindowImpl.java | 59 +++ .../invui/window/NormalSplitWindowImpl.java | 54 +++ .../xyz/xenondevs/invui/window/Window.java | 368 +++++++++++++++++- .../builder/AbstractSingleWindowBuilder.java | 33 -- .../builder/AbstractSplitWindowBuilder.java | 52 --- .../window/builder/AbstractWindowBuilder.java | 118 ------ .../builder/AnvilSingleWindowBuilder.java | 67 ---- .../builder/AnvilSplitWindowBuilder.java | 70 ---- .../CartographySingleWindowBuilder.java | 44 --- .../CartographySplitWindowBuilder.java | 45 --- .../builder/NormalMergedWindowBuilder.java | 44 --- .../builder/NormalSingleWindowBuilder.java | 53 --- .../builder/NormalSplitWindowBuilder.java | 47 --- .../invui/window/builder/WindowBuilder.java | 15 - .../invui/window/builder/WindowType.java | 39 -- .../window/impl/AnvilSplitWindowImpl.java | 58 --- .../window/impl/NormalSingleWindowImpl.java | 25 -- .../window/impl/NormalSplitWindowImpl.java | 25 -- 60 files changed, 1899 insertions(+), 1532 deletions(-) delete mode 100644 invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/GuiBuilders.kt delete mode 100644 invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/WindowBuilders.kt rename invui/src/main/java/xyz/xenondevs/invui/gui/{impl => }/NormalGuiImpl.java (57%) rename invui/src/main/java/xyz/xenondevs/invui/gui/{impl => }/PagedItemsGuiImpl.java (80%) rename invui/src/main/java/xyz/xenondevs/invui/gui/{impl => }/PagedNestedGuiImpl.java (77%) rename invui/src/main/java/xyz/xenondevs/invui/gui/{impl => }/ScrollInventoryGuiImpl.java (81%) rename invui/src/main/java/xyz/xenondevs/invui/gui/{impl => }/ScrollItemsGuiImpl.java (78%) rename invui/src/main/java/xyz/xenondevs/invui/gui/{impl => }/ScrollNestedGuiImpl.java (79%) rename invui/src/main/java/xyz/xenondevs/invui/gui/{impl => }/TabGuiImpl.java (79%) delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractPagedGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractScrollGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiType.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/NormalGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedItemsGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedNestedGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollInventoryGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollItemsGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollNestedGuiBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/gui/builder/TabGuiBuilder.java rename invui/src/main/java/xyz/xenondevs/invui/window/{impl => }/AnvilSingleWindowImpl.java (50%) create mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/AnvilSplitWindowImpl.java rename invui/src/main/java/xyz/xenondevs/invui/window/{impl => }/CartographySingleWindowImpl.java (74%) rename invui/src/main/java/xyz/xenondevs/invui/window/{impl => }/CartographySplitWindowImpl.java (69%) rename invui/src/main/java/xyz/xenondevs/invui/window/{impl => }/NormalMergedWindowImpl.java (52%) create mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/NormalSingleWindowImpl.java create mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/NormalSplitWindowImpl.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSingleWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSplitWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSingleWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSplitWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySingleWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySplitWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalMergedWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSingleWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSplitWindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowBuilder.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowType.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/impl/AnvilSplitWindowImpl.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSingleWindowImpl.java delete mode 100644 invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSplitWindowImpl.java diff --git a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/GuiBuilders.kt b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/GuiBuilders.kt deleted file mode 100644 index 53b9197..0000000 --- a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/GuiBuilders.kt +++ /dev/null @@ -1,11 +0,0 @@ -@file:Suppress("PackageDirectoryMismatch") - -package xyz.xenondevs.invui.gui.builder - -import xyz.xenondevs.invui.gui.Gui - -fun > GuiType.create(builderConsumer: B.() -> Unit): G { - val builder = builder() - builder.builderConsumer() - return builder.build() -} \ No newline at end of file diff --git a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/ItemBuilders.kt b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/ItemBuilders.kt index 515a422..06ec743 100644 --- a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/ItemBuilders.kt +++ b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/ItemBuilders.kt @@ -9,4 +9,4 @@ import xyz.xenondevs.invui.util.ComponentUtils /** * Sets the lore of the item stack. */ -fun AbstractItemBuilder.setLore(lore: List>): T = setLore(lore.map { BaseComponentWrapper(ComponentUtils.withoutPreFormatting(*it)) }) \ No newline at end of file +fun > T.setLore(lore: List>): T = setLore(lore.map { BaseComponentWrapper(ComponentUtils.withoutPreFormatting(*it)) }) \ No newline at end of file diff --git a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/WindowBuilders.kt b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/WindowBuilders.kt deleted file mode 100644 index 1e5c040..0000000 --- a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/WindowBuilders.kt +++ /dev/null @@ -1,11 +0,0 @@ -@file:Suppress("PackageDirectoryMismatch") - -package xyz.xenondevs.invui.window.builder - -import xyz.xenondevs.invui.window.Window - -fun > WindowType.create(builderConsumer: B.() -> Unit): W { - val builder = builder() - builder.builderConsumer() - return builder.build() -} \ No newline at end of file diff --git a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureItemBuilders.kt b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureItemBuilders.kt index 17e0f13..8a7d57f 100644 --- a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureItemBuilders.kt +++ b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureItemBuilders.kt @@ -8,14 +8,14 @@ import xyz.xenondevs.inventoryaccess.component.AdventureComponentWrapper /** * Sets the display name of the item stack. */ -fun AbstractItemBuilder.setDisplayName(displayName: Component): T = setDisplayName(AdventureComponentWrapper(displayName)) +fun > T.setDisplayName(displayName: Component): T = setDisplayName(AdventureComponentWrapper(displayName)) /** * Sets the lore the item stack. */ -fun AbstractItemBuilder.setLore(lore: List): T = setLore(lore.map { AdventureComponentWrapper(it) }) +fun > T.setLore(lore: List): T = setLore(lore.map { AdventureComponentWrapper(it) }) /** * Adds lore lines to the item stack. */ -fun AbstractItemBuilder.addLoreLines(vararg components: Component): T = addLoreLines(*components.map { AdventureComponentWrapper(it) }.toTypedArray()) \ No newline at end of file +fun > T.addLoreLines(vararg components: Component): T = addLoreLines(*components.map { AdventureComponentWrapper(it) }.toTypedArray()) \ No newline at end of file diff --git a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureWindowContexts.kt b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureWindowContexts.kt index 175baed..81859db 100644 --- a/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureWindowContexts.kt +++ b/invui-kotlin/src/main/kotlin/xyz/xenondevs/invui/adventure/AdventureWindowContexts.kt @@ -3,10 +3,15 @@ package xyz.xenondevs.invui.window.type.context import net.kyori.adventure.text.Component +import org.jetbrains.annotations.Contract import xyz.xenondevs.inventoryaccess.component.AdventureComponentWrapper -import xyz.xenondevs.invui.window.builder.AbstractWindowBuilder +import xyz.xenondevs.invui.window.Window /** * Sets the title of the window. + * + * @param title the new title + * @return This Window Builder */ -fun AbstractWindowBuilder<*, *, *>.setTitle(title: Component) = setTitle(AdventureComponentWrapper(title)) \ No newline at end of file +@Contract("_ -> this") +fun > B.setTitle(title: Component): B = setTitle(AdventureComponentWrapper(title)) \ No newline at end of file diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractGui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractGui.java index 4710525..0316828 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractGui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractGui.java @@ -10,9 +10,11 @@ import org.bukkit.inventory.PlayerInventory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.xenondevs.invui.animation.Animation; +import xyz.xenondevs.invui.gui.structure.Marker; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.ItemWrapper; import xyz.xenondevs.invui.item.impl.controlitem.ControlItem; import xyz.xenondevs.invui.util.ArrayUtils; import xyz.xenondevs.invui.util.InventoryUtils; @@ -24,7 +26,9 @@ import xyz.xenondevs.invui.virtualinventory.event.UpdateReason; import xyz.xenondevs.invui.window.*; import java.util.*; +import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; public abstract class AbstractGui implements Gui, GuiParent { @@ -682,4 +686,135 @@ public abstract class AbstractGui implements Gui, GuiParent { } // endregion + @SuppressWarnings("unchecked") + public static abstract class AbstractBuilder> implements Gui.Builder { + + protected Structure structure; + protected ItemProvider background; + protected List> modifiers; + + @Override + public S setStructure(int width, int height, @NotNull String structureData) { + structure = new Structure(width, height, structureData); + return (S) this; + } + + @Override + public S setStructure(@NotNull String... structureData) { + structure = new Structure(structureData); + return (S) this; + } + + @Override + public S setStructure(@NotNull Structure structure) { + this.structure = structure; + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull ItemStack itemStack) { + structure.addIngredient(key, itemStack); + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull ItemProvider itemProvider) { + structure.addIngredient(key, itemProvider); + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull Item item) { + structure.addIngredient(key, item); + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull VirtualInventory inventory) { + structure.addIngredient(key, inventory); + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull VirtualInventory inventory, @Nullable ItemProvider background) { + structure.addIngredient(key, inventory, background); + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull SlotElement element) { + structure.addIngredient(key, element); + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull Marker marker) { + structure.addIngredient(key, marker); + return (S) this; + } + + @Override + public S addIngredient(char key, @NotNull Supplier itemSupplier) { + structure.addIngredient(key, itemSupplier); + return (S) this; + } + + @Override + public S addIngredientElementSupplier(char key, @NotNull Supplier elementSupplier) { + structure.addIngredientElementSupplier(key, elementSupplier); + return (S) this; + } + + @Override + public S setBackground(@NotNull ItemProvider itemProvider) { + background = itemProvider; + return (S) this; + } + + @Override + public S setBackground(@NotNull ItemStack itemStack) { + background = new ItemWrapper(itemStack); + return (S) this; + } + + @Override + public S addModifier(@NotNull Consumer<@NotNull Gui> modifier) { + if (modifiers == null) + modifiers = new ArrayList<>(); + + modifiers.add(modifier); + return (S) this; + } + + @Override + public S setModifiers(@NotNull List<@NotNull Consumer<@NotNull Gui>> modifiers) { + this.modifiers = modifiers; + return (S) this; + } + + protected void applyModifiers(@NotNull G gui) { + if (background != null) { + gui.setBackground(background); + } + if (modifiers != null) { + modifiers.forEach(modifier -> modifier.accept(gui)); + } + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull S clone() { + try { + var clone = (AbstractBuilder) super.clone(); + clone.structure = structure.clone(); + if (modifiers != null) + clone.modifiers = new ArrayList<>(modifiers); + return (S) clone; + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java index 77bb435..3619c76 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java @@ -2,9 +2,6 @@ package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.builder.GuiType; -import xyz.xenondevs.invui.gui.impl.PagedItemsGuiImpl; -import xyz.xenondevs.invui.gui.impl.PagedNestedGuiImpl; import xyz.xenondevs.invui.gui.structure.Structure; import java.util.ArrayList; @@ -14,7 +11,6 @@ import java.util.function.BiConsumer; /** * A {@link Gui} with pages. * - * @see GuiType * @see PagedItemsGuiImpl * @see PagedNestedGuiImpl */ @@ -135,4 +131,58 @@ public abstract class AbstractPagedGui extends AbstractGui implements PagedGu protected abstract List getPageElements(int page); + public static abstract class AbstractBuilder + extends AbstractGui.AbstractBuilder, PagedGui.Builder> + implements PagedGui.Builder + { + + protected List content; + protected List> pageChangeHandlers; + + @Override + public PagedGui.Builder setContent(@NotNull List<@NotNull C> content) { + this.content = content; + return this; + } + + @Override + public PagedGui.Builder addContent(@NotNull C content) { + if (this.content == null) + this.content = new ArrayList<>(); + + this.content.add(content); + return this; + } + + @Override + public PagedGui.Builder setPageChangeHandlers(@NotNull List<@NotNull BiConsumer> handlers) { + pageChangeHandlers = handlers; + return this; + } + + @Override + public PagedGui.Builder addPageChangeHandler(@NotNull BiConsumer handler) { + if (pageChangeHandlers == null) + pageChangeHandlers = new ArrayList<>(1); + + pageChangeHandlers.add(handler); + return this; + } + + @Override + protected void applyModifiers(@NotNull PagedGui gui) { + super.applyModifiers(gui); + gui.setPageChangeHandlers(pageChangeHandlers); + } + + @Override + public @NotNull PagedGui.Builder clone() { + var clone = (AbstractBuilder) super.clone(); + clone.content = new ArrayList<>(content); + clone.pageChangeHandlers = new ArrayList<>(pageChangeHandlers); + return clone; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java index 1cd6734..4f3373e 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java @@ -1,8 +1,6 @@ package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl; -import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.util.SlotUtils; @@ -134,4 +132,58 @@ public abstract class AbstractScrollGui extends AbstractGui implements Scroll protected abstract List getElements(int from, int to); + public abstract static class AbstractBuilder + extends AbstractGui.AbstractBuilder, ScrollGui.Builder> + implements ScrollGui.Builder + { + + protected List content; + protected List> scrollHandlers; + + @Override + public ScrollGui.Builder setContent(@NotNull List<@NotNull C> content) { + this.content = content; + return this; + } + + @Override + public ScrollGui.Builder addContent(@NotNull C content) { + if (this.content == null) + this.content = new ArrayList<>(); + + this.content.add(content); + return this; + } + + @Override + public ScrollGui.Builder setScrollHandlers(@NotNull List<@NotNull BiConsumer> handlers) { + scrollHandlers = handlers; + return this; + } + + @Override + public ScrollGui.Builder addScrollHandler(@NotNull BiConsumer handler) { + if (scrollHandlers == null) + scrollHandlers = new ArrayList<>(1); + + scrollHandlers.add(handler); + return this; + } + + @Override + protected void applyModifiers(@NotNull ScrollGui gui) { + super.applyModifiers(gui); + gui.setScrollHandlers(scrollHandlers); + } + + @Override + public @NotNull ScrollGui.Builder clone() { + var clone = (AbstractBuilder) super.clone(); + clone.content = new ArrayList<>(content); + clone.scrollHandlers = new ArrayList<>(scrollHandlers); + return clone; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractTabGui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractTabGui.java index 1a75e29..b762b4a 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractTabGui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/AbstractTabGui.java @@ -96,5 +96,58 @@ public abstract class AbstractTabGui extends AbstractGui implements TabGui { protected abstract List getSlotElements(int tab); + public static abstract class AbstractBuilder + extends AbstractGui.AbstractBuilder + implements TabGui.Builder + { + + protected List tabs; + protected List> tabChangeHandlers; + + @Override + public TabGui.Builder setTabs(@NotNull List<@Nullable Gui> tabs) { + this.tabs = tabs; + return this; + } + + @Override + public TabGui.Builder addTab(@Nullable Gui tab) { + if (this.tabs == null) + this.tabs = new ArrayList<>(); + + this.tabs.add(tab); + return this; + } + + @Override + public TabGui.Builder addTabChangeHandler(@NotNull BiConsumer handler) { + if (tabChangeHandlers == null) + tabChangeHandlers = new ArrayList<>(1); + + tabChangeHandlers.add(handler); + return this; + } + + @Override + public TabGui.Builder setTabChangeHandlers(@NotNull List<@NotNull BiConsumer> handlers) { + tabChangeHandlers = handlers; + return this; + } + + @Override + protected void applyModifiers(@NotNull TabGui gui) { + super.applyModifiers(gui); + gui.setTabChangeHandlers(tabChangeHandlers); + } + + @Override + public @NotNull TabGui.Builder clone() { + var clone = (AbstractBuilder) super.clone(); + clone.tabs = new ArrayList<>(tabs); + clone.tabChangeHandlers = new ArrayList<>(tabChangeHandlers); + return clone; + } + + } } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/Gui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/Gui.java index 03f04f0..b4a51da 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/Gui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/Gui.java @@ -2,11 +2,12 @@ package xyz.xenondevs.invui.gui; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.xenondevs.invui.animation.Animation; -import xyz.xenondevs.invui.gui.builder.GuiType; -import xyz.xenondevs.invui.gui.impl.NormalGuiImpl; +import xyz.xenondevs.invui.gui.structure.Marker; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemProvider; @@ -16,7 +17,9 @@ import xyz.xenondevs.invui.window.WindowManager; import java.util.List; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.function.Supplier; /** * A Gui is a container for width * height {@link SlotElement SlotElements}.
@@ -28,15 +31,33 @@ import java.util.function.Predicate; * In order to create an {@link Inventory} which is visible * to players, you will need to use a {@link Window}. * - * @see GuiType - * @see AbstractGui - * @see AbstractPagedGui - * @see AbstractScrollGui - * @see AbstractTabGui + * @see PagedGui + * @see ScrollGui + * @see TabGui */ -@SuppressWarnings("deprecation") public interface Gui { + /** + * Creates a new {@link Builder.Normal Gui Builder} for a normal {@link Gui}. + * + * @return The new {@link Builder.Normal Gui Builder}. + */ + static @NotNull Builder.Normal normal() { + return new NormalGuiImpl.Builder(); + } + + /** + * Creates a new normal {@link Gui} after configuring a {@link Builder.Normal Gui Builder} with the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder.Normal Gui Builder}. + * @return The created {@link Gui}. + */ + static @NotNull Gui normal(@NotNull Consumer consumer) { + Builder.Normal builder = normal(); + consumer.accept(builder); + return builder.build(); + } + /** * Creates a new empty {@link Gui}. * @@ -356,4 +377,195 @@ public interface Gui { // + /** + * A {@link Gui} builder. + * + * @param The type of the {@link Gui} + * @param The type of the builder + */ + interface Builder> extends Cloneable { + + /** + * Sets the {@link Structure} of the {@link Gui}. + * + * @param structure The {@link Structure} of the {@link Gui} + * @return This {@link Builder} + */ + @Contract("_ -> this") + S setStructure(@NotNull Structure structure); + + /** + * Sets the {@link Structure} of the {@link Gui} using the given structure data Strings. + * Each String is interpreted as a row of the {@link Gui}. All Strings must have the same length. + * + * @param structureData The structure data + * @return This {@link Builder Gui Builder} + */ + @Contract("_ -> this") + S setStructure(@NotNull String... structureData); + + /** + * Sets the {@link Structure} of the {@link Gui} using the given structure data, width and height. + * + * @param width The width of the {@link Gui} + * @param height The height of the {@link Gui} + * @param structureData The structure data + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _, _, -> this") + S setStructure(int width, int height, @NotNull String structureData); + + /** + * Adds an {@link ItemStack} ingredient under the given key. + * + * @param key The key + * @param itemStack The {@link ItemStack} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredient(char key, @NotNull ItemStack itemStack); + + /** + * Adds an {@link ItemProvider} ingredient under the given key. + * + * @param key The key + * @param itemProvider The {@link ItemProvider} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredient(char key, @NotNull ItemProvider itemProvider); + + /** + * Adds an {@link Item} ingredient under the given key. + * + * @param key The key + * @param item The {@link Item} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredient(char key, @NotNull Item item); + + /** + * Adds an {@link VirtualInventory} ingredient under the given key. + * + * @param key The key + * @param inventory The {@link VirtualInventory} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredient(char key, @NotNull VirtualInventory inventory); + + /** + * Adds an {@link VirtualInventory} ingredient under the given key. + * + * @param key The key + * @param inventory The {@link VirtualInventory} + * @param background The {@link ItemProvider} for empty slots of the {@link VirtualInventory} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _, _ -> this") + S addIngredient(char key, @NotNull VirtualInventory inventory, @Nullable ItemProvider background); + + /** + * Adds a {@link SlotElement} ingredient under the given key. + * + * @param key The key + * @param element The {@link SlotElement} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredient(char key, @NotNull SlotElement element); + + /** + * Adds a {@link Marker} ingredient under the given key. + * + * @param key The key + * @param marker The {@link Marker} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredient(char key, @NotNull Marker marker); + + /** + * Adds a {@link Supplier} of {@link Item Items} ingredient under the given key. + * + * @param key The key + * @param itemSupplier The {@link Supplier} of {@link Item Items} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredient(char key, @NotNull Supplier itemSupplier); + + /** + * Adds a {@link Supplier} of {@link SlotElement SlotElements} ingredient under the given key. + * + * @param key The key + * @param elementSupplier The {@link Supplier} of {@link SlotElement SlotElements} + * @return This {@link Builder Gui Builder} + */ + @Contract("_, _ -> this") + S addIngredientElementSupplier(char key, @NotNull Supplier elementSupplier); + + /** + * Sets the background of the {@link Gui}. + * + * @param itemProvider The {@link ItemProvider} for the background + * @return This {@link Builder Gui Builder} + */ + @Contract("_ -> this") + S setBackground(@NotNull ItemProvider itemProvider); + + /** + * Sets the background of the {@link Gui}. + * + * @param itemStack The {@link ItemStack} for the background + * @return This {@link Builder Gui Builder} + */ + @Contract("_ -> this") + S setBackground(@NotNull ItemStack itemStack); + + /** + * Sets the background of the {@link Gui}. + * + * @param modifier The {@link Consumer} for the background + * @return This {@link Builder Gui Builder} + */ + @Contract("_ -> this") + S addModifier(@NotNull Consumer<@NotNull Gui> modifier); + + /** + * Sets the background of the {@link Gui}. + * + * @param modifiers The {@link Consumer Consumers} for the background + * @return This {@link Builder Gui Builder} + */ + @Contract("_ -> this") + S setModifiers(@NotNull List<@NotNull Consumer<@NotNull Gui>> modifiers); + + /** + * Builds the {@link Gui}. + * + * @return The {@link Gui} + */ + @Contract("-> new") + @NotNull G build(); + + /** + * Clones the Gui Builder. + * + * @return The cloned Gui Builder + */ + @Contract("-> new") + @NotNull S clone(); + + /** + * A normal {@link Gui} builder. + * + * @see PagedGui.Builder + * @see ScrollGui.Builder + * @see TabGui.Builder + */ + interface Normal extends Builder {} + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/NormalGuiImpl.java b/invui/src/main/java/xyz/xenondevs/invui/gui/NormalGuiImpl.java similarity index 57% rename from invui/src/main/java/xyz/xenondevs/invui/gui/impl/NormalGuiImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/gui/NormalGuiImpl.java index 16784e9..6d27173 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/NormalGuiImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/NormalGuiImpl.java @@ -1,24 +1,19 @@ -package xyz.xenondevs.invui.gui.impl; +package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.structure.Structure; /** * A normal {@link Gui} without any special features. */ -@SuppressWarnings("DeprecatedIsStillUsed") -public final class NormalGuiImpl extends AbstractGui { +final class NormalGuiImpl extends AbstractGui { /** * Creates a new {@link NormalGuiImpl}. * * @param width The width of this Gui. * @param height The height of this Gui. - * @deprecated Use {@link Gui#empty(int, int)} instead. */ - @Deprecated public NormalGuiImpl(int width, int height) { super(width, height); } @@ -27,12 +22,24 @@ public final class NormalGuiImpl extends AbstractGui { * Creates a new {@link NormalGuiImpl}. * * @param structure The {@link Structure} to use. - * @deprecated Use {@link Gui#of(Structure)} instead. */ - @Deprecated public NormalGuiImpl(@NotNull Structure structure) { super(structure.getWidth(), structure.getHeight()); applyStructure(structure); } + public static class Builder extends AbstractBuilder implements Gui.Builder.Normal { + + @Override + public @NotNull Gui build() { + if (structure == null) + throw new IllegalStateException("Structure is not defined."); + + var gui = new NormalGuiImpl(structure); + applyModifiers(gui); + return gui; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java index cc0d15c..bc39496 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java @@ -1,18 +1,43 @@ package xyz.xenondevs.invui.gui; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.impl.PagedItemsGuiImpl; -import xyz.xenondevs.invui.gui.impl.PagedNestedGuiImpl; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.Item; import java.util.List; import java.util.function.BiConsumer; +import java.util.function.Consumer; -@SuppressWarnings("deprecation") +/** + * A {@link Gui} that can display multiple pages of content. + * + * @param The content type + */ public interface PagedGui extends Gui { + /** + * Creates a new {@link Builder Gui Builder} for a {@link PagedGui} that uses {@link Item Items} as content. + * + * @return The new {@link Builder Gui Builder}. + */ + static @NotNull Builder<@NotNull Item> items() { + return new PagedItemsGuiImpl.Builder(); + } + + /** + * Creates a new {@link PagedGui} after configuring a {@link Builder Gui Builder} using the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder Gui Builder}. + * @return The created {@link PagedGui}. + */ + static @NotNull PagedGui<@NotNull Item> items(@NotNull Consumer<@NotNull Builder<@NotNull Item>> consumer) { + Builder<@NotNull Item> builder = items(); + consumer.accept(builder); + return builder.build(); + } + /** * Creates a new {@link PagedGui}. * @@ -22,7 +47,7 @@ public interface PagedGui extends Gui { * @param contentListSlots The slots where content should be displayed. * @return The created {@link PagedGui}. */ - static @NotNull PagedGui ofItems(int width, int height, @NotNull List<@NotNull Item> items, int... contentListSlots) { + static @NotNull PagedGui<@NotNull Item> ofItems(int width, int height, @NotNull List<@NotNull Item> items, int... contentListSlots) { return new PagedItemsGuiImpl(width, height, items, contentListSlots); } @@ -33,10 +58,31 @@ public interface PagedGui extends Gui { * @param items The {@link Item Items} to use as in pages. * @return The created {@link PagedGui}. */ - static @NotNull PagedGui ofItems(Structure structure, @NotNull List<@NotNull Item> items) { + static @NotNull PagedGui<@NotNull Item> ofItems(@NotNull Structure structure, @NotNull List<@NotNull Item> items) { return new PagedItemsGuiImpl(items, structure); } + /** + * Creates a new {@link Builder Gui Builder} for a {@link PagedGui} that uses {@link Gui Guis} as content. + * + * @return The new {@link Builder Gui Builder}. + */ + static @NotNull Builder<@NotNull Gui> guis() { + return new PagedNestedGuiImpl.Builder(); + } + + /** + * Creates a new {@link PagedGui} after configuring a {@link Builder Gui Builder} using the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder Gui Builder}. + * @return The created {@link PagedGui}. + */ + static @NotNull PagedGui<@NotNull Gui> guis(@NotNull Consumer<@NotNull Builder<@NotNull Gui>> consumer) { + Builder<@NotNull Gui> builder = guis(); + consumer.accept(builder); + return builder.build(); + } + /** * Creates a new {@link PagedGui}. * @@ -46,7 +92,7 @@ public interface PagedGui extends Gui { * @param contentListSlots The slots where content should be displayed. * @return The created {@link PagedGui}. */ - static @NotNull PagedGui ofGuis(int width, int height, @NotNull List<@NotNull Gui> guis, int... contentListSlots) { + static @NotNull PagedGui<@NotNull Gui> ofGuis(int width, int height, @NotNull List<@NotNull Gui> guis, int... contentListSlots) { return new PagedNestedGuiImpl(width, height, guis, contentListSlots); } @@ -57,7 +103,7 @@ public interface PagedGui extends Gui { * @param guis The {@link Gui Guis} to use as pages. * @return The created {@link PagedGui}. */ - static @NotNull PagedGui ofGuis(Structure structure, @NotNull List<@NotNull Gui> guis) { + static @NotNull PagedGui<@NotNull Gui> ofGuis(@NotNull Structure structure, @NotNull List<@NotNull Gui> guis) { return new PagedNestedGuiImpl(guis, structure); } @@ -155,4 +201,49 @@ public interface PagedGui extends Gui { */ void removePageChangeHandler(@NotNull BiConsumer handler); + /** + * A {@link PagedGui} builder. + * + * @param The content type. + */ + interface Builder extends Gui.Builder, Builder> { + + /** + * Sets the content of the {@link PagedGui} for all pages. + * + * @param content The content to set. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder setContent(@NotNull List<@NotNull C> content); + + /** + * Adds content to the {@link PagedGui}. + * + * @param content The content to add. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder addContent(@NotNull C content); + + /** + * Sets the page change handlers of the {@link PagedGui}. + * + * @param handlers The page change handlers to set. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder setPageChangeHandlers(@NotNull List<@NotNull BiConsumer> handlers); + + /** + * Adds a page change handler to the {@link PagedGui}. + * + * @param handler The page change handler to add. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder addPageChangeHandler(@NotNull BiConsumer handler); + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/PagedItemsGuiImpl.java b/invui/src/main/java/xyz/xenondevs/invui/gui/PagedItemsGuiImpl.java similarity index 80% rename from invui/src/main/java/xyz/xenondevs/invui/gui/impl/PagedItemsGuiImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/gui/PagedItemsGuiImpl.java index 98ee35a..5d5a252 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/PagedItemsGuiImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/PagedItemsGuiImpl.java @@ -1,11 +1,7 @@ -package xyz.xenondevs.invui.gui.impl; +package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.AbstractPagedGui; -import xyz.xenondevs.invui.gui.PagedGui; -import xyz.xenondevs.invui.gui.SlotElement; -import xyz.xenondevs.invui.gui.builder.GuiType; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.Item; @@ -17,11 +13,9 @@ import java.util.stream.Collectors; /** * A {@link AbstractPagedGui} that is filled with {@link Item Items}. * - * @see GuiType * @see PagedNestedGuiImpl */ -@SuppressWarnings("DeprecatedIsStillUsed") -public final class PagedItemsGuiImpl extends AbstractPagedGui { +final class PagedItemsGuiImpl extends AbstractPagedGui { private List items; private List> pageChangeHandlers; @@ -33,9 +27,7 @@ public final class PagedItemsGuiImpl extends AbstractPagedGui { * @param height The height of this Gui. * @param items The {@link Item Items} to use as pages. * @param contentListSlots The slots where content should be displayed. - * @deprecated Use {@link PagedGui#ofItems(int, int, List, int...)} instead. */ - @Deprecated public PagedItemsGuiImpl(int width, int height, @Nullable List<@NotNull Item> items, int... contentListSlots) { super(width, height, false, contentListSlots); setContent(items); @@ -46,9 +38,7 @@ public final class PagedItemsGuiImpl extends AbstractPagedGui { * * @param items The {@link Item Items} to use as pages. * @param structure The {@link Structure} to use. - * @deprecated Use {@link PagedGui#ofItems(Structure, List)} instead. */ - @Deprecated public PagedItemsGuiImpl(@Nullable List<@NotNull Item> items, @NotNull Structure structure) { super(structure.getWidth(), structure.getHeight(), false, structure); setContent(items); @@ -74,4 +64,18 @@ public final class PagedItemsGuiImpl extends AbstractPagedGui { return items.subList(from, to).stream().map(SlotElement.ItemSlotElement::new).collect(Collectors.toList()); } + public static final class Builder extends AbstractBuilder { + + @Override + public @NotNull PagedGui build() { + if (structure == null) + throw new IllegalStateException("Structure is not defined."); + + var gui = new PagedItemsGuiImpl(content, structure); + applyModifiers(gui); + return gui; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/PagedNestedGuiImpl.java b/invui/src/main/java/xyz/xenondevs/invui/gui/PagedNestedGuiImpl.java similarity index 77% rename from invui/src/main/java/xyz/xenondevs/invui/gui/impl/PagedNestedGuiImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/gui/PagedNestedGuiImpl.java index 71fbfba..368a7ab 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/PagedNestedGuiImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/PagedNestedGuiImpl.java @@ -1,12 +1,7 @@ -package xyz.xenondevs.invui.gui.impl; +package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.AbstractPagedGui; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.PagedGui; -import xyz.xenondevs.invui.gui.SlotElement; -import xyz.xenondevs.invui.gui.builder.GuiType; import xyz.xenondevs.invui.gui.structure.Structure; import java.util.ArrayList; @@ -17,11 +12,9 @@ import java.util.stream.IntStream; /** * A {@link AbstractPagedGui} where every page is its own {@link Gui}. * - * @see GuiType * @see PagedItemsGuiImpl */ -@SuppressWarnings("DeprecatedIsStillUsed") -public final class PagedNestedGuiImpl extends AbstractPagedGui { +final class PagedNestedGuiImpl extends AbstractPagedGui { private List guis; @@ -32,9 +25,7 @@ public final class PagedNestedGuiImpl extends AbstractPagedGui { * @param height The height of this Gui. * @param guis The {@link Gui Guis} to use as pages. * @param contentListSlots The slots where content should be displayed. - * @deprecated Use {@link PagedGui#ofGuis(int, int, List, int...)} instead. */ - @Deprecated public PagedNestedGuiImpl(int width, int height, @Nullable List<@NotNull Gui> guis, int... contentListSlots) { super(width, height, false, contentListSlots); setContent(guis); @@ -45,9 +36,7 @@ public final class PagedNestedGuiImpl extends AbstractPagedGui { * * @param guis The {@link Gui Guis} to use as pages. * @param structure The {@link Structure} to use. - * @deprecated Use {@link PagedGui#ofGuis(Structure, List)} instead. */ - @Deprecated public PagedNestedGuiImpl(@Nullable List<@NotNull Gui> guis, @NotNull Structure structure) { super(structure.getWidth(), structure.getHeight(), false, structure); setContent(guis); @@ -76,4 +65,18 @@ public final class PagedNestedGuiImpl extends AbstractPagedGui { .collect(Collectors.toList()); } + public static final class Builder extends AbstractBuilder { + + @Override + public @NotNull PagedGui build() { + if (structure == null) + throw new IllegalStateException("Structure is not defined."); + + var gui = new PagedNestedGuiImpl(content, structure); + applyModifiers(gui); + return gui; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java index 094ae86..1a192d9 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java @@ -1,20 +1,40 @@ package xyz.xenondevs.invui.gui; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl; -import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl; -import xyz.xenondevs.invui.gui.impl.ScrollInventoryGuiImpl; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.virtualinventory.VirtualInventory; import java.util.List; import java.util.function.BiConsumer; +import java.util.function.Consumer; -@SuppressWarnings("deprecation") public interface ScrollGui extends Gui { + /** + * Creates a new {@link Builder Gui Builder} for a {@link ScrollGui} that uses {@link Item Items} as content. + * + * @return The new {@link Builder Gui Builder}. + */ + static @NotNull Builder<@NotNull Item> items() { + return new ScrollItemsGuiImpl.Builder(); + } + + /** + * Creates a new {@link ScrollGui} that uses {@link Item Items} as content after configuring a + * {@link Builder Gui Builder} using the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder Gui Builder}. + * @return The created {@link ScrollGui}. + */ + static @NotNull ScrollGui<@NotNull Item> items(@NotNull Consumer<@NotNull Builder<@NotNull Item>> consumer) { + Builder<@NotNull Item> builder = items(); + consumer.accept(builder); + return builder.build(); + } + /** * Creates a new {@link ScrollGui}. * @@ -24,7 +44,7 @@ public interface ScrollGui extends Gui { * @param contentListSlots The slots where content should be displayed. * @return The created {@link ScrollGui}. */ - static @NotNull ScrollGui ofItems(int width, int height, @NotNull List<@NotNull Item> items, int... contentListSlots) { + static @NotNull ScrollGui<@NotNull Item> ofItems(int width, int height, @NotNull List<@NotNull Item> items, int... contentListSlots) { return new ScrollItemsGuiImpl(width, height, items, contentListSlots); } @@ -35,10 +55,32 @@ public interface ScrollGui extends Gui { * @param items The {@link Item Items} to use. * @return The created {@link ScrollGui}. */ - static @NotNull ScrollGui ofItems(@NotNull Structure structure, @NotNull List<@NotNull Item> items) { + static @NotNull ScrollGui<@NotNull Item> ofItems(@NotNull Structure structure, @NotNull List<@NotNull Item> items) { return new ScrollItemsGuiImpl(items, structure); } + /** + * Creates a new {@link Builder Gui Builder} for a {@link ScrollGui} that uses {@link Gui Guis} as content. + * + * @return The new {@link Builder Gui Builder}. + */ + static @NotNull Builder<@NotNull Gui> guis() { + return new ScrollNestedGuiImpl.Builder(); + } + + /** + * Creates a new {@link ScrollGui} that uses {@link Gui Guis} as content after configuring a + * {@link Builder Gui Builder} using the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder Gui Builder}. + * @return The created {@link ScrollGui}. + */ + static @NotNull ScrollGui<@NotNull Gui> guis(@NotNull Consumer<@NotNull Builder<@NotNull Gui>> consumer) { + Builder<@NotNull Gui> builder = guis(); + consumer.accept(builder); + return builder.build(); + } + /** * Creates a new {@link ScrollGui}. * @@ -48,7 +90,7 @@ public interface ScrollGui extends Gui { * @param contentListSlots The slots where content should be displayed. * @return The created {@link ScrollGui}. */ - static @NotNull ScrollGui ofGuis(int width, int height, @NotNull List<@NotNull Gui> guis, int... contentListSlots) { + static @NotNull ScrollGui<@NotNull Gui> ofGuis(int width, int height, @NotNull List<@NotNull Gui> guis, int... contentListSlots) { return new ScrollNestedGuiImpl(width, height, guis, contentListSlots); } @@ -59,10 +101,32 @@ public interface ScrollGui extends Gui { * @param guis The {@link Gui Guis} to use. * @return The created {@link ScrollGui}. */ - static @NotNull ScrollGui ofGuis(Structure structure, @NotNull List<@NotNull Gui> guis) { + static @NotNull ScrollGui<@NotNull Gui> ofGuis(Structure structure, @NotNull List<@NotNull Gui> guis) { return new ScrollNestedGuiImpl(guis, structure); } + /** + * Creates a new {@link Builder Gui Builder} for a {@link ScrollGui} that uses {@link VirtualInventory VirtualInventories} as content. + * + * @return The new {@link Builder Gui Builder}. + */ + static @NotNull Builder<@NotNull VirtualInventory> inventories() { + return new ScrollInventoryGuiImpl.Builder(); + } + + /** + * Creates a new {@link ScrollGui} that uses {@link VirtualInventory VirtualInventories} as content after configuring a + * {@link Builder Gui Builder} using the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder Gui Builder}. + * @return The created {@link ScrollGui}. + */ + static @NotNull ScrollGui<@NotNull VirtualInventory> inventories(@NotNull Consumer<@NotNull Builder<@NotNull VirtualInventory>> consumer) { + Builder<@NotNull VirtualInventory> builder = inventories(); + consumer.accept(builder); + return builder.build(); + } + /** * Creates a new {@link ScrollGui}. * @@ -72,7 +136,7 @@ public interface ScrollGui extends Gui { * @param contentListSlots The slots where content should be displayed. * @return The created {@link ScrollGui}. */ - static @NotNull ScrollGui ofInventories(int width, int height, @NotNull List<@NotNull VirtualInventory> inventories, int... contentListSlots) { + static @NotNull ScrollGui<@NotNull VirtualInventory> ofInventories(int width, int height, @NotNull List<@NotNull VirtualInventory> inventories, int... contentListSlots) { return new ScrollInventoryGuiImpl(width, height, inventories, contentListSlots); } @@ -83,7 +147,7 @@ public interface ScrollGui extends Gui { * @param inventories The {@link VirtualInventory VirtualInventories} to use. * @return The created {@link ScrollGui}. */ - static @NotNull ScrollGui ofInventories(@NotNull Structure structure, @NotNull List<@NotNull VirtualInventory> inventories) { + static @NotNull ScrollGui<@NotNull VirtualInventory> ofInventories(@NotNull Structure structure, @NotNull List<@NotNull VirtualInventory> inventories) { return new ScrollInventoryGuiImpl(inventories, structure); } @@ -150,4 +214,49 @@ public interface ScrollGui extends Gui { */ void removeScrollHandler(@NotNull BiConsumer scrollHandler); + /** + * A {@link ScrollGui} builder. + * + * @param The content type. + */ + interface Builder extends Gui.Builder, Builder> { + + /** + * Sets the content of the {@link ScrollGui} for all lines. + * + * @param content The content to set. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder setContent(@NotNull List<@NotNull C> content); + + /** + * Adds content to the {@link ScrollGui}. + * + * @param content The content to add. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder addContent(@NotNull C content); + + /** + * Adds content to the {@link ScrollGui}. + * + * @param handlers The content to add. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder setScrollHandlers(@NotNull List<@NotNull BiConsumer> handlers); + + /** + * Adds a scroll handler to the {@link ScrollGui}. + * + * @param handler The scroll handler to add. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder addScrollHandler(@NotNull BiConsumer handler); + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollInventoryGuiImpl.java b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollInventoryGuiImpl.java similarity index 81% rename from invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollInventoryGuiImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/gui/ScrollInventoryGuiImpl.java index fe4ebe5..32b9ea2 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollInventoryGuiImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollInventoryGuiImpl.java @@ -1,11 +1,7 @@ -package xyz.xenondevs.invui.gui.impl; +package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.AbstractScrollGui; -import xyz.xenondevs.invui.gui.ScrollGui; -import xyz.xenondevs.invui.gui.SlotElement; -import xyz.xenondevs.invui.gui.builder.GuiType; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.virtualinventory.VirtualInventory; @@ -15,12 +11,10 @@ import java.util.List; /** * A {@link AbstractScrollGui} that uses {@link VirtualInventory VirtualInventories} as content. * - * @see GuiType * @see ScrollItemsGuiImpl * @see ScrollNestedGuiImpl */ -@SuppressWarnings("DeprecatedIsStillUsed") -public final class ScrollInventoryGuiImpl extends AbstractScrollGui { +final class ScrollInventoryGuiImpl extends AbstractScrollGui { private List inventories; private List elements; @@ -32,9 +26,7 @@ public final class ScrollInventoryGuiImpl extends AbstractScrollGui inventories, int... contentListSlots) { super(width, height, false, contentListSlots); setContent(inventories); @@ -45,9 +37,7 @@ public final class ScrollInventoryGuiImpl extends AbstractScrollGui inventories, @NotNull Structure structure) { super(structure.getWidth(), structure.getHeight(), false, structure); setContent(inventories); @@ -80,4 +70,18 @@ public final class ScrollInventoryGuiImpl extends AbstractScrollGui { + + @Override + public @NotNull ScrollGui build() { + if (structure == null) + throw new IllegalStateException("Structure is not defined."); + + var gui = new ScrollInventoryGuiImpl(content, structure); + applyModifiers(gui); + return gui; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollItemsGuiImpl.java b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollItemsGuiImpl.java similarity index 78% rename from invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollItemsGuiImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/gui/ScrollItemsGuiImpl.java index d2441dc..9dfd757 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollItemsGuiImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollItemsGuiImpl.java @@ -1,11 +1,7 @@ -package xyz.xenondevs.invui.gui.impl; +package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.AbstractScrollGui; -import xyz.xenondevs.invui.gui.ScrollGui; -import xyz.xenondevs.invui.gui.SlotElement; -import xyz.xenondevs.invui.gui.builder.GuiType; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.Item; @@ -16,12 +12,10 @@ import java.util.stream.Collectors; /** * A {@link AbstractScrollGui} that uses {@link Item Items} as content. * - * @see GuiType * @see ScrollInventoryGuiImpl * @see ScrollNestedGuiImpl */ -@SuppressWarnings("DeprecatedIsStillUsed") -public final class ScrollItemsGuiImpl extends AbstractScrollGui { +final class ScrollItemsGuiImpl extends AbstractScrollGui { private List items; @@ -32,9 +26,7 @@ public final class ScrollItemsGuiImpl extends AbstractScrollGui { * @param height The height of this Gui. * @param items The {@link Item Items} to use. * @param contentListSlots The slots where content should be displayed. - * @deprecated Use {@link ScrollGui#ofItems(int, int, List, int...)} instead. */ - @Deprecated public ScrollItemsGuiImpl(int width, int height, @Nullable List<@NotNull Item> items, int... contentListSlots) { super(width, height, false, contentListSlots); setContent(items); @@ -45,9 +37,7 @@ public final class ScrollItemsGuiImpl extends AbstractScrollGui { * * @param items The {@link Item Items} to use. * @param structure The {@link Structure} to use. - * @deprecated Use {@link ScrollGui#ofItems(Structure, List)} instead. */ - @Deprecated public ScrollItemsGuiImpl(@Nullable List<@NotNull Item> items, @NotNull Structure structure) { super(structure.getWidth(), structure.getHeight(), false, structure); setContent(items); @@ -71,4 +61,18 @@ public final class ScrollItemsGuiImpl extends AbstractScrollGui { return (int) Math.ceil((double) items.size() / (double) getLineLength()) - 1; } + public static final class Builder extends AbstractBuilder { + + @Override + public @NotNull ScrollGui build() { + if (structure == null) + throw new IllegalStateException("Structure is not defined."); + + var gui = new ScrollItemsGuiImpl(content, structure); + applyModifiers(gui); + return gui; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollNestedGuiImpl.java b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollNestedGuiImpl.java similarity index 79% rename from invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollNestedGuiImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/gui/ScrollNestedGuiImpl.java index 7e023a6..5ed2bb1 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/ScrollNestedGuiImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/ScrollNestedGuiImpl.java @@ -1,12 +1,7 @@ -package xyz.xenondevs.invui.gui.impl; +package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.AbstractScrollGui; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.ScrollGui; -import xyz.xenondevs.invui.gui.SlotElement; -import xyz.xenondevs.invui.gui.builder.GuiType; import xyz.xenondevs.invui.gui.structure.Structure; import java.util.ArrayList; @@ -15,12 +10,10 @@ import java.util.List; /** * A {@link AbstractScrollGui} that uses {@link Gui Guis} as content. * - * @see GuiType * @see ScrollItemsGuiImpl * @see ScrollInventoryGuiImpl */ -@SuppressWarnings("DeprecatedIsStillUsed") -public final class ScrollNestedGuiImpl extends AbstractScrollGui { +final class ScrollNestedGuiImpl extends AbstractScrollGui { private List guis; private List elements; @@ -32,9 +25,7 @@ public final class ScrollNestedGuiImpl extends AbstractScrollGui { * @param height The height of this Gui. * @param guis The {@link Gui Guis} to use. * @param contentListSlots The slots where content should be displayed. - * @deprecated Use {@link ScrollGui#ofGuis(int, int, List, int...)} instead. */ - @Deprecated public ScrollNestedGuiImpl(int width, int height, @Nullable List<@NotNull Gui> guis, int... contentListSlots) { super(width, height, false, contentListSlots); setContent(guis); @@ -45,9 +36,7 @@ public final class ScrollNestedGuiImpl extends AbstractScrollGui { * * @param guis The {@link Gui Guis} to use. * @param structure The {@link Structure} to use. - * @deprecated Use {@link ScrollGui#ofGuis(Structure, List)} instead. */ - @Deprecated public ScrollNestedGuiImpl(@Nullable List<@NotNull Gui> guis, @NotNull Structure structure) { super(structure.getWidth(), structure.getHeight(), false, structure); setContent(guis); @@ -80,4 +69,19 @@ public final class ScrollNestedGuiImpl extends AbstractScrollGui { return (int) Math.ceil((double) elements.size() / (double) getLineLength()) - 1; } + public static final class Builder extends AbstractBuilder { + + @Override + public @NotNull ScrollGui build() { + if (structure == null) + throw new IllegalStateException("Structure is not defined."); + + var gui = new ScrollNestedGuiImpl(content, structure); + applyModifiers(gui); + return gui; + } + + } + + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/TabGui.java b/invui/src/main/java/xyz/xenondevs/invui/gui/TabGui.java index 116e9dc..f2720d2 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/TabGui.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/TabGui.java @@ -1,16 +1,37 @@ package xyz.xenondevs.invui.gui; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.impl.TabGuiImpl; import xyz.xenondevs.invui.gui.structure.Structure; import java.util.List; import java.util.function.BiConsumer; +import java.util.function.Consumer; -@SuppressWarnings("deprecation") public interface TabGui extends Gui { + /** + * Creates a new {@link Builder Gui Builder} for a {@link TabGui}. + * + * @return The new {@link Builder Gui Builder}. + */ + static @NotNull Builder normal() { + return new TabGuiImpl.BuilderImpl(); + } + + /** + * Creates a new {@link TabGui} after configuring a {@link Builder Gui Builder} using the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder Gui Builder}. + * @return The created {@link TabGui}. + */ + static @NotNull TabGui normal(@NotNull Consumer<@NotNull Builder> consumer) { + Builder builder = normal(); + consumer.accept(builder); + return builder.build(); + } + /** * Creates a new {@link TabGui}. * @@ -92,4 +113,49 @@ public interface TabGui extends Gui { */ void removeTabChangeHandler(@NotNull BiConsumer handler); + /** + * A {@link TabGui} builder. + */ + interface Builder extends Gui.Builder { + + /** + * Sets the tabs of the {@link TabGui}. + * Individual tabs can be null to disable them, but there must at least one tab. + * + * @param tabs The tabs of the {@link TabGui}. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder setTabs(@NotNull List<@Nullable Gui> tabs); + + /** + * Adds a tab to the {@link TabGui}. + * Individual tabs can be null to disable them, but there must at least one tab. + * + * @param tab The tab to add. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder addTab(@Nullable Gui tab); + + /** + * Sets the tab change handlers of the {@link TabGui}. + * + * @param handlers The tab change handlers of the {@link TabGui}. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder setTabChangeHandlers(@NotNull List<@NotNull BiConsumer> handlers); + + /** + * Adds a tab change handler to the {@link TabGui}. + * + * @param handler The tab change handler to add. + * @return This {@link Builder Gui Builder}. + */ + @Contract("_ -> this") + Builder addTabChangeHandler(@NotNull BiConsumer handler); + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/TabGuiImpl.java b/invui/src/main/java/xyz/xenondevs/invui/gui/TabGuiImpl.java similarity index 79% rename from invui/src/main/java/xyz/xenondevs/invui/gui/impl/TabGuiImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/gui/TabGuiImpl.java index 271df2d..d33a6c3 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/impl/TabGuiImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/gui/TabGuiImpl.java @@ -1,12 +1,7 @@ -package xyz.xenondevs.invui.gui.impl; +package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.AbstractTabGui; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.SlotElement; -import xyz.xenondevs.invui.gui.TabGui; -import xyz.xenondevs.invui.gui.builder.GuiType; import xyz.xenondevs.invui.gui.structure.Structure; import java.util.ArrayList; @@ -16,11 +11,8 @@ import java.util.stream.Collectors; /** * A {@link Gui} that has multiple tabs with which users can switch between {@link Gui}s. - * - * @see GuiType */ -@SuppressWarnings("DeprecatedIsStillUsed") -public final class TabGuiImpl extends AbstractTabGui { +final class TabGuiImpl extends AbstractTabGui { private final List tabs; private final List> linkingElements; @@ -32,9 +24,7 @@ public final class TabGuiImpl extends AbstractTabGui { * @param height The height of this Gui. * @param tabs The {@link Gui Guis} to use as tabs. * @param contentListSlots The slots where content should be displayed. - * @deprecated Use {@link TabGui#of(int, int, List, int...)} instead. */ - @Deprecated public TabGuiImpl(int width, int height, @NotNull List<@Nullable Gui> tabs, int[] contentListSlots) { super(width, height, tabs.size(), contentListSlots); this.linkingElements = tabs.stream().map(this::getLinkingElements).collect(Collectors.toList()); @@ -48,9 +38,7 @@ public final class TabGuiImpl extends AbstractTabGui { * * @param tabs The {@link Gui Guis} to use as tabs. * @param structure The {@link Structure} to use. - * @deprecated Use {@link TabGui#of(Structure, List)} instead. */ - @Deprecated public TabGuiImpl(@NotNull List<@Nullable Gui> tabs, @NotNull Structure structure) { super(structure.getWidth(), structure.getHeight(), tabs.size(), structure); this.linkingElements = tabs.stream().map(this::getLinkingElements).collect(Collectors.toList()); @@ -85,4 +73,19 @@ public final class TabGuiImpl extends AbstractTabGui { return linkingElements.get(tab); } + public static final class BuilderImpl extends AbstractBuilder implements TabGui.Builder { + + @Override + public @NotNull TabGui build() { + if (structure == null) + throw new IllegalStateException("Structure is not defined."); + if (tabs == null) + throw new IllegalStateException("Tabs are not defined."); + var gui = new TabGuiImpl(tabs, structure); + applyModifiers(gui); + return gui; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractGuiBuilder.java deleted file mode 100644 index 314e018..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractGuiBuilder.java +++ /dev/null @@ -1,159 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.ShapedRecipe; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.SlotElement; -import xyz.xenondevs.invui.gui.structure.Marker; -import xyz.xenondevs.invui.gui.structure.Structure; -import xyz.xenondevs.invui.item.Item; -import xyz.xenondevs.invui.item.ItemProvider; -import xyz.xenondevs.invui.item.ItemWrapper; -import xyz.xenondevs.invui.virtualinventory.VirtualInventory; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; - - -/** - * A builder class to easily construct {@link Gui Guis}.
- * 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 abstract class AbstractGuiBuilder> implements GuiBuilder { - - protected Structure structure; - protected ItemProvider background; - protected List> modifiers; - - @Contract("_, _, _, -> this") - public S setStructure(int width, int height, @NotNull String structureData) { - structure = new Structure(width, height, structureData); - return getThis(); - } - - @Contract("_ -> this") - public S setStructure(@NotNull String... structureData) { - structure = new Structure(structureData); - return getThis(); - } - - @Contract("_ -> this") - public S setStructure(@NotNull Structure structure) { - this.structure = structure; - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredient(char key, @NotNull ItemStack itemStack) { - structure.addIngredient(key, itemStack); - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredient(char key, @NotNull ItemProvider itemProvider) { - structure.addIngredient(key, itemProvider); - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredient(char key, @NotNull Item item) { - structure.addIngredient(key, item); - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredient(char key, @NotNull VirtualInventory inventory) { - structure.addIngredient(key, inventory); - return getThis(); - } - - @Contract("_, _, _ -> this") - public S addIngredient(char key, @NotNull VirtualInventory inventory, @Nullable ItemProvider background) { - structure.addIngredient(key, inventory, background); - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredient(char key, @NotNull SlotElement element) { - structure.addIngredient(key, element); - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredient(char key, @NotNull Marker marker) { - structure.addIngredient(key, marker); - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredient(char key, @NotNull Supplier itemSupplier) { - structure.addIngredient(key, itemSupplier); - return getThis(); - } - - @Contract("_, _ -> this") - public S addIngredientElementSupplier(char key, @NotNull Supplier elementSupplier) { - structure.addIngredientElementSupplier(key, elementSupplier); - return getThis(); - } - - @Contract("_ -> this") - public S setBackground(@NotNull ItemProvider itemProvider) { - background = itemProvider; - return getThis(); - } - - @Contract("_ -> this") - public S setBackground(@NotNull ItemStack itemStack) { - background = new ItemWrapper(itemStack); - return getThis(); - } - - @Contract("_ -> this") - public S addModifier(@NotNull Consumer<@NotNull Gui> modifier) { - if (modifiers == null) - modifiers = new ArrayList<>(); - - modifiers.add(modifier); - return getThis(); - } - - @Contract("_ -> this") - public S setModifiers(@NotNull List<@NotNull Consumer<@NotNull Gui>> modifiers) { - this.modifiers = modifiers; - return getThis(); - } - - protected void applyModifiers(@NotNull G gui) { - if (background != null) { - gui.setBackground(background); - } - if (modifiers != null) { - modifiers.forEach(modifier -> modifier.accept(gui)); - } - } - - @SuppressWarnings("unchecked") - @Override - public @NotNull AbstractGuiBuilder clone() { - try { - var clone = (AbstractGuiBuilder) super.clone(); - clone.structure = structure.clone(); - if (modifiers != null) - clone.modifiers = new ArrayList<>(modifiers); - return clone; - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } - - @Contract(value = "-> this", pure = true) - protected abstract S getThis(); - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractPagedGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractPagedGuiBuilder.java deleted file mode 100644 index 6d4e995..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractPagedGuiBuilder.java +++ /dev/null @@ -1,60 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.PagedGui; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiConsumer; - -public abstract class AbstractPagedGuiBuilder> extends AbstractGuiBuilder, S> { - - protected List content; - protected List> pageChangeHandlers; - - @Contract("_ -> this") - public S setContent(@NotNull List<@NotNull C> content) { - this.content = content; - return getThis(); - } - - @Contract("_ -> this") - public S addContent(@NotNull C content) { - if (this.content == null) - this.content = new ArrayList<>(); - - this.content.add(content); - return getThis(); - } - - @Contract("_ -> this") - public S setPageChangeHandlers(@NotNull List<@NotNull BiConsumer> handlers) { - pageChangeHandlers = handlers; - return getThis(); - } - - @Contract("_ -> this") - public S addPageChangeHandler(@NotNull BiConsumer handler) { - if (pageChangeHandlers == null) - pageChangeHandlers = new ArrayList<>(1); - - pageChangeHandlers.add(handler); - return getThis(); - } - - @Override - protected void applyModifiers(@NotNull PagedGui gui) { - super.applyModifiers(gui); - gui.setPageChangeHandlers(pageChangeHandlers); - } - - @Override - public @NotNull AbstractPagedGuiBuilder clone() { - var clone = (AbstractPagedGuiBuilder) super.clone(); - clone.content = new ArrayList<>(content); - clone.pageChangeHandlers = new ArrayList<>(pageChangeHandlers); - return clone; - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractScrollGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractScrollGuiBuilder.java deleted file mode 100644 index bc7edc1..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/AbstractScrollGuiBuilder.java +++ /dev/null @@ -1,60 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.ScrollGui; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiConsumer; - -public abstract class AbstractScrollGuiBuilder> extends AbstractGuiBuilder, S>{ - - protected List content; - protected List> scrollHandlers; - - @Contract("_ -> this") - public S setContent(@NotNull List<@NotNull C> content) { - this.content = content; - return getThis(); - } - - @Contract("_ -> this") - public S addContent(@NotNull C content) { - if (this.content == null) - this.content = new ArrayList<>(); - - this.content.add(content); - return getThis(); - } - - @Contract("_ -> this") - public S setScrollHandlers(@NotNull List<@NotNull BiConsumer> handlers) { - scrollHandlers = handlers; - return getThis(); - } - - @Contract("_ -> this") - public S addScrollHandler(@NotNull BiConsumer handler) { - if (scrollHandlers == null) - scrollHandlers = new ArrayList<>(1); - - scrollHandlers.add(handler); - return getThis(); - } - - @Override - protected void applyModifiers(@NotNull ScrollGui gui) { - super.applyModifiers(gui); - gui.setScrollHandlers(scrollHandlers); - } - - @Override - public @NotNull AbstractScrollGuiBuilder clone() { - var clone = (AbstractScrollGuiBuilder) super.clone(); - clone.content = new ArrayList<>(content); - clone.scrollHandlers = new ArrayList<>(scrollHandlers); - return clone; - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiBuilder.java deleted file mode 100644 index ae08b63..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiBuilder.java +++ /dev/null @@ -1,15 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.Gui; - -public interface GuiBuilder extends Cloneable { - - @Contract("-> new") - @NotNull G build(); - - @Contract("-> new") - @NotNull GuiBuilder clone(); - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiType.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiType.java deleted file mode 100644 index dab85a9..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/GuiType.java +++ /dev/null @@ -1,42 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.PagedGui; -import xyz.xenondevs.invui.gui.ScrollGui; -import xyz.xenondevs.invui.gui.TabGui; -import xyz.xenondevs.invui.item.Item; -import xyz.xenondevs.invui.virtualinventory.VirtualInventory; - -import java.util.function.Consumer; - -public interface GuiType> { - - GuiType NORMAL = NormalGuiBuilder::new; - GuiType, PagedItemsGuiBuilder> PAGED_ITEMS = PagedItemsGuiBuilder::new; - GuiType, PagedNestedGuiBuilder> PAGED_GUIS = PagedNestedGuiBuilder::new; - GuiType TAB = TabGuiBuilder::new; - GuiType, ScrollItemsGuiBuilder> SCROLL_ITEMS = ScrollItemsGuiBuilder::new; - GuiType, ScrollNestedGuiBuilder> SCROLL_GUIS = ScrollNestedGuiBuilder::new; - GuiType, ScrollInventoryGuiBuilder> SCROLL_INVENTORY = ScrollInventoryGuiBuilder::new; - - /** - * Creates a new {@link GuiBuilder} for this {@link GuiType}. - * - * @return The created {@link GuiBuilder}. - */ - @NotNull B builder(); - - /** - * Creates a new {@link Gui} after modifying the {@link GuiBuilder} with the given {@link Consumer}. - * - * @param builderConsumer The {@link Consumer} which modifies the {@link GuiBuilder}. - * @return The new {@link Gui}. - */ - default @NotNull G createGui(@NotNull Consumer builderConsumer) { - var builder = builder(); - builderConsumer.accept(builder); - return builder.build(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/NormalGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/NormalGuiBuilder.java deleted file mode 100644 index c1ca5d3..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/NormalGuiBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.impl.NormalGuiImpl; - -public final class NormalGuiBuilder extends AbstractGuiBuilder { - - NormalGuiBuilder() { - } - - @SuppressWarnings("deprecation") - @Override - public @NotNull Gui build() { - if (structure == null) - throw new IllegalStateException("Structure is not defined."); - - var gui = new NormalGuiImpl(structure); - applyModifiers(gui); - return gui; - } - - @Override - protected NormalGuiBuilder getThis() { - return this; - } - - @Override - public @NotNull NormalGuiBuilder clone() { - return (NormalGuiBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedItemsGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedItemsGuiBuilder.java deleted file mode 100644 index bc980f7..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedItemsGuiBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.PagedGui; -import xyz.xenondevs.invui.gui.impl.PagedItemsGuiImpl; -import xyz.xenondevs.invui.item.Item; - -public final class PagedItemsGuiBuilder extends AbstractPagedGuiBuilder { - - PagedItemsGuiBuilder() { - } - - @SuppressWarnings("deprecation") - @Override - public @NotNull PagedGui build() { - if (structure == null) - throw new IllegalStateException("Structure is not defined."); - - var gui = new PagedItemsGuiImpl(content, structure); - applyModifiers(gui); - return gui; - } - - @Override - protected PagedItemsGuiBuilder getThis() { - return this; - } - - @Override - public @NotNull PagedItemsGuiBuilder clone() { - return (PagedItemsGuiBuilder) super.clone(); - } - -} \ No newline at end of file diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedNestedGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedNestedGuiBuilder.java deleted file mode 100644 index 3723abb..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/PagedNestedGuiBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.PagedGui; -import xyz.xenondevs.invui.gui.impl.PagedNestedGuiImpl; - -public final class PagedNestedGuiBuilder extends AbstractPagedGuiBuilder { - - PagedNestedGuiBuilder() { - } - - @SuppressWarnings("deprecation") - @Override - public @NotNull PagedGui build() { - if (structure == null) - throw new IllegalStateException("Structure is not defined."); - - var gui = new PagedNestedGuiImpl(content, structure); - applyModifiers(gui); - return gui; - } - - @Override - protected PagedNestedGuiBuilder getThis() { - return this; - } - - @Override - public @NotNull PagedNestedGuiBuilder clone() { - return (PagedNestedGuiBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollInventoryGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollInventoryGuiBuilder.java deleted file mode 100644 index 3af0739..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollInventoryGuiBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.ScrollGui; -import xyz.xenondevs.invui.gui.impl.ScrollInventoryGuiImpl; -import xyz.xenondevs.invui.virtualinventory.VirtualInventory; - -public final class ScrollInventoryGuiBuilder extends AbstractScrollGuiBuilder { - - ScrollInventoryGuiBuilder() { - } - - @SuppressWarnings("deprecation") - @Override - public @NotNull ScrollGui build() { - if (structure == null) - throw new IllegalStateException("Structure is not defined."); - - var gui = new ScrollInventoryGuiImpl(content, structure); - applyModifiers(gui); - return gui; - } - - @Override - protected ScrollInventoryGuiBuilder getThis() { - return this; - } - - @Override - public @NotNull ScrollInventoryGuiBuilder clone() { - return (ScrollInventoryGuiBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollItemsGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollItemsGuiBuilder.java deleted file mode 100644 index 9144873..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollItemsGuiBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.ScrollGui; -import xyz.xenondevs.invui.gui.impl.ScrollItemsGuiImpl; -import xyz.xenondevs.invui.item.Item; - -public final class ScrollItemsGuiBuilder extends AbstractScrollGuiBuilder { - - ScrollItemsGuiBuilder() { - } - - @SuppressWarnings("deprecation") - @Override - public @NotNull ScrollGui build() { - if (structure == null) - throw new IllegalStateException("Structure is not defined."); - - var gui = new ScrollItemsGuiImpl(content, structure); - applyModifiers(gui); - return gui; - } - - @Override - protected ScrollItemsGuiBuilder getThis() { - return this; - } - - @Override - public @NotNull ScrollItemsGuiBuilder clone() { - return (ScrollItemsGuiBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollNestedGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollNestedGuiBuilder.java deleted file mode 100644 index 109d47c..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/ScrollNestedGuiBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.ScrollGui; -import xyz.xenondevs.invui.gui.impl.ScrollNestedGuiImpl; - -public final class ScrollNestedGuiBuilder extends AbstractScrollGuiBuilder{ - - ScrollNestedGuiBuilder() { - } - - @SuppressWarnings("deprecation") - @Override - public @NotNull ScrollGui build() { - if (structure == null) - throw new IllegalStateException("Structure is not defined."); - - var gui = new ScrollNestedGuiImpl(content, structure); - applyModifiers(gui); - return gui; - } - - @Override - protected ScrollNestedGuiBuilder getThis() { - return this; - } - - @Override - public @NotNull ScrollNestedGuiBuilder clone() { - return (ScrollNestedGuiBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/TabGuiBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/gui/builder/TabGuiBuilder.java deleted file mode 100644 index b9f3d72..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/gui/builder/TabGuiBuilder.java +++ /dev/null @@ -1,83 +0,0 @@ -package xyz.xenondevs.invui.gui.builder; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.TabGui; -import xyz.xenondevs.invui.gui.impl.TabGuiImpl; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiConsumer; - -public final class TabGuiBuilder extends AbstractGuiBuilder { - - private List tabs; - private List> tabChangeHandlers; - - TabGuiBuilder() { - } - - @Contract("_ -> this") - public TabGuiBuilder setTabs(@NotNull List<@Nullable Gui> tabs) { - this.tabs = tabs; - return this; - } - - @Contract("_ -> this") - public TabGuiBuilder addTab(@Nullable Gui tab) { - if (this.tabs == null) - this.tabs = new ArrayList<>(); - - this.tabs.add(tab); - return this; - } - - @Contract("_ -> this") - public TabGuiBuilder addTabChangeHandler(@NotNull BiConsumer handler) { - if (tabChangeHandlers == null) - tabChangeHandlers = new ArrayList<>(1); - - tabChangeHandlers.add(handler); - return this; - } - - @Contract("_ -> this") - public TabGuiBuilder setTabChangeHandlers(@NotNull List<@NotNull BiConsumer> handlers) { - tabChangeHandlers = handlers; - return this; - } - - @Override - protected void applyModifiers(@NotNull TabGui gui) { - super.applyModifiers(gui); - gui.setTabChangeHandlers(tabChangeHandlers); - } - - @SuppressWarnings("deprecation") - @Override - public @NotNull TabGui build() { - if (structure == null) - throw new IllegalStateException("Structure is not defined."); - if (tabs == null) - throw new IllegalStateException("Tabs are not defined."); - var gui = new TabGuiImpl(tabs, structure); - applyModifiers(gui); - return gui; - } - - @Override - protected TabGuiBuilder getThis() { - return this; - } - - @Override - public @NotNull TabGuiBuilder clone() { - var clone = (TabGuiBuilder) super.clone(); - clone.tabs = new ArrayList<>(tabs); - clone.tabChangeHandlers = new ArrayList<>(tabChangeHandlers); - return clone; - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSingleWindow.java b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSingleWindow.java index e2ef67e..c549119 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSingleWindow.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSingleWindow.java @@ -5,6 +5,7 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.Gui; @@ -13,6 +14,7 @@ import xyz.xenondevs.invui.util.InventoryUtils; import xyz.xenondevs.invui.util.Pair; import java.util.UUID; +import java.util.function.Supplier; /** * A {@link Window} that just uses the top {@link Inventory}. @@ -106,4 +108,32 @@ public abstract class AbstractSingleWindow extends AbstractWindow { return gui; } + @SuppressWarnings("unchecked") + public abstract static class AbstractBuilder> + extends AbstractWindow.AbstractBuilder + implements Builder.Single + { + + protected Supplier guiSupplier; + + @Override + public S setGui(@NotNull Supplier guiSupplier) { + this.guiSupplier = guiSupplier; + return (S) this; + } + + @Override + public S setGui(@NotNull Gui gui) { + this.guiSupplier = () -> gui; + return (S) this; + } + + @Override + public S setGui(@NotNull Gui.Builder builder) { + this.guiSupplier = builder::build; + return (S) this; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSplitWindow.java b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSplitWindow.java index 4cc4a73..1994406 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSplitWindow.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractSplitWindow.java @@ -3,6 +3,7 @@ package xyz.xenondevs.invui.window; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.Gui; @@ -10,6 +11,8 @@ import xyz.xenondevs.invui.gui.SlotElement; import xyz.xenondevs.invui.util.Pair; import xyz.xenondevs.invui.util.SlotUtils; +import java.util.function.Supplier; + /** * A {@link Window} where top and player {@link Inventory} are affected by different {@link Gui}s. */ @@ -64,4 +67,51 @@ public abstract class AbstractSplitWindow extends AbstractDoubleWindow { return new AbstractGui[] {upperGui, lowerGui}; } + @SuppressWarnings("unchecked") + public static abstract class AbstractBuilder> + extends AbstractWindow.AbstractBuilder + implements Window.Builder.Double + { + + protected Supplier upperGuiSupplier; + protected Supplier lowerGuiSupplier; + + @Override + public S setUpperGui(@NotNull Supplier guiSupplier) { + this.upperGuiSupplier = guiSupplier; + return (S) this; + } + + @Override + public S setUpperGui(@NotNull Gui gui) { + this.upperGuiSupplier = () -> gui; + return (S) this; + } + + @Override + public S setUpperGui(@NotNull Gui.Builder builder) { + this.upperGuiSupplier = builder::build; + return (S) this; + } + + @Override + public S setLowerGui(@NotNull Supplier guiSupplier) { + this.lowerGuiSupplier = guiSupplier; + return (S) this; + } + + @Override + public S setLowerGui(@NotNull Gui gui) { + this.lowerGuiSupplier = () -> gui; + return (S) this; + } + + @Override + public S setLowerGui(@NotNull Gui.Builder builder) { + this.lowerGuiSupplier = builder::build; + return (S) this; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java index 105b463..a069c7b 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java @@ -34,6 +34,7 @@ import xyz.xenondevs.invui.virtualinventory.event.PlayerUpdateReason; import xyz.xenondevs.invui.virtualinventory.event.UpdateReason; import java.util.*; +import java.util.function.Consumer; public abstract class AbstractWindow implements Window, GuiParent { @@ -365,4 +366,108 @@ public abstract class AbstractWindow implements Window, GuiParent { public abstract void handleViewerDeath(PlayerDeathEvent event); + @SuppressWarnings("unchecked") + public static abstract class AbstractBuilder> implements Window.Builder { + + protected V viewer; + protected ComponentWrapper title; + protected boolean closeable = true; + protected boolean retain = false; + protected List closeHandlers; + protected List> modifiers; + + @Override + public S setViewer(@NotNull V viewer) { + this.viewer = viewer; + return (S) this; + } + + @Override + public S setTitle(@NotNull ComponentWrapper title) { + this.title = title; + return (S) this; + } + + @Override + public S setTitle(@NotNull BaseComponent @NotNull [] title) { + this.title = new BaseComponentWrapper(title); + return (S) this; + } + + @Override + public S setTitle(@NotNull String title) { + this.title = new BaseComponentWrapper(TextComponent.fromLegacyText(title)); + return (S) this; + } + + @Override + public S setCloseable(boolean closeable) { + this.closeable = closeable; + return (S) this; + } + + @Override + public S setRetain(boolean retain) { + this.retain = retain; + return (S) this; + } + + @Override + public S setCloseHandlers(List closeHandlers) { + this.closeHandlers = closeHandlers; + return (S) this; + } + + @Override + public S addCloseHandler(Runnable closeHandler) { + if (closeHandlers == null) + closeHandlers = new ArrayList<>(); + + closeHandlers.add(closeHandler); + return (S) this; + } + + @Override + public S setModifiers(List> modifiers) { + this.modifiers = modifiers; + return (S) this; + } + + @Override + public S addModifier(Consumer modifier) { + if (modifiers == null) + modifiers = new ArrayList<>(); + + modifiers.add(modifier); + return (S) this; + } + + protected void applyModifiers(W window) { + if (closeHandlers != null) + window.setCloseHandlers(closeHandlers); + + if (modifiers != null) + modifiers.forEach(modifier -> modifier.accept(window)); + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull S clone() { + try { + var clone = (AbstractBuilder) super.clone(); + if (title != null) + clone.title = title.clone(); + if (closeHandlers != null) + clone.closeHandlers = new ArrayList<>(closeHandlers); + if (modifiers != null) + clone.modifiers = new ArrayList<>(modifiers); + return (S) clone; + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + + } + + } \ No newline at end of file diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/impl/AnvilSingleWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/AnvilSingleWindowImpl.java similarity index 50% rename from invui/src/main/java/xyz/xenondevs/invui/window/impl/AnvilSingleWindowImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/window/AnvilSingleWindowImpl.java index 7b3ee3a..4cbe4c5 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/impl/AnvilSingleWindowImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/AnvilSingleWindowImpl.java @@ -1,4 +1,4 @@ -package xyz.xenondevs.invui.window.impl; +package xyz.xenondevs.invui.window; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -8,13 +8,12 @@ import xyz.xenondevs.inventoryaccess.InventoryAccess; import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.AbstractSingleWindow; -import xyz.xenondevs.invui.window.AnvilWindow; +import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -public final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilWindow { +final class AnvilSingleWindowImpl extends AbstractSingleWindow implements AnvilWindow { private final AnvilInventory anvilInventory; @@ -53,4 +52,49 @@ public final class AnvilSingleWindowImpl extends AbstractSingleWindow implements return anvilInventory.getRenameText(); } + public static final class BuilderImpl + extends AbstractSingleWindow.AbstractBuilder + implements AnvilWindow.Builder.Single + { + + private List> renameHandlers; + + @Override + public BuilderImpl setRenameHandlers(@NotNull List<@NotNull Consumer> renameHandlers) { + this.renameHandlers = renameHandlers; + return this; + } + + @Override + public BuilderImpl addRenameHandler(@NotNull Consumer renameHandler) { + if (renameHandlers == null) + renameHandlers = new ArrayList<>(); + + renameHandlers.add(renameHandler); + return this; + } + + @Override + public @NotNull AnvilWindow build() { + if (viewer == null) + throw new IllegalStateException("Viewer is not defined."); + if (guiSupplier == null) + throw new IllegalStateException("Gui is not defined."); + + var window = new AnvilSingleWindowImpl( + viewer, + title, + (AbstractGui) guiSupplier.get(), + renameHandlers, + closeable, + retain + ); + + applyModifiers(window); + + return window; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/AnvilSplitWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/AnvilSplitWindowImpl.java new file mode 100644 index 0000000..181d423 --- /dev/null +++ b/invui/src/main/java/xyz/xenondevs/invui/window/AnvilSplitWindowImpl.java @@ -0,0 +1,105 @@ +package xyz.xenondevs.invui.window; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.xenondevs.inventoryaccess.InventoryAccess; +import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; +import xyz.xenondevs.invui.gui.AbstractGui; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWindow { + + private final AnvilInventory anvilInventory; + + public AnvilSplitWindowImpl( + @NotNull Player player, + @Nullable ComponentWrapper title, + @NotNull AbstractGui upperGui, + @NotNull AbstractGui lowerGui, + @Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers, + boolean closeable, + boolean retain + ) { + super(player, title, upperGui, lowerGui, null, false, closeable, retain); + + anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandlers); + upperInventory = anvilInventory.getBukkitInventory(); + + initUpperItems(); + register(); + } + + @Override + protected void setUpperInvItem(int slot, ItemStack itemStack) { + anvilInventory.setItem(slot, itemStack); + } + + @Override + public void show() { + if (isRemoved()) throw new IllegalStateException("The Window has already been closed."); + + Player viewer = getViewer(); + if (viewer == null) throw new IllegalStateException("The player is not online."); + anvilInventory.open(); + } + + @Override + public String getRenameText() { + return anvilInventory.getRenameText(); + } + + public static final class BuilderImpl + extends AbstractSplitWindow.AbstractBuilder + implements AnvilWindow.Builder.Split + { + + private List> renameHandlers; + + @Override + public BuilderImpl setRenameHandlers(@NotNull List<@NotNull Consumer> renameHandlers) { + this.renameHandlers = renameHandlers; + return this; + } + + @Override + public BuilderImpl addRenameHandler(@NotNull Consumer renameHandler) { + if (renameHandlers == null) + renameHandlers = new ArrayList<>(); + + renameHandlers.add(renameHandler); + return this; + } + + @Override + public @NotNull AnvilWindow build() { + if (viewer == null) + throw new IllegalStateException("Viewer is not defined."); + if (upperGuiSupplier == null) + throw new IllegalStateException("Upper Gui is not defined."); + if (lowerGuiSupplier == null) + throw new IllegalStateException("Lower Gui is not defined."); + + var window = new AnvilSplitWindowImpl( + viewer, + title, + (AbstractGui) upperGuiSupplier.get(), + (AbstractGui) lowerGuiSupplier.get(), + renameHandlers, + closeable, + retain + ); + + applyModifiers(window); + + return window; + } + + } + +} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/AnvilWindow.java b/invui/src/main/java/xyz/xenondevs/invui/window/AnvilWindow.java index 2273a4d..a8b2e24 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/AnvilWindow.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/AnvilWindow.java @@ -1,7 +1,49 @@ package xyz.xenondevs.invui.window; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Consumer; + public interface AnvilWindow extends Window { - String getRenameText(); + static @NotNull Builder.Single single() { + return new AnvilSingleWindowImpl.BuilderImpl(); + } + + static @NotNull AnvilWindow single(@NotNull Consumer consumer) { + Builder.Single builder = single(); + consumer.accept(builder); + return builder.build(); + } + + static @NotNull Builder.Split split() { + return new AnvilSplitWindowImpl.BuilderImpl(); + } + + static @NotNull AnvilWindow split(Consumer consumer) { + Builder.Split builder = split(); + consumer.accept(builder); + return builder.build(); + } + + @Nullable String getRenameText(); + + interface Builder> extends Window.Builder { + + @Contract("_ -> this") + S setRenameHandlers(@NotNull List<@NotNull Consumer> renameHandlers); + + @Contract("_ -> this") + S addRenameHandler(@NotNull Consumer renameHandler); + + interface Single extends Builder, Window.Builder.Single {} + + interface Split extends Builder, Window.Builder.Double {} + + } } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/impl/CartographySingleWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/CartographySingleWindowImpl.java similarity index 74% rename from invui/src/main/java/xyz/xenondevs/invui/window/impl/CartographySingleWindowImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/window/CartographySingleWindowImpl.java index 5608093..d333461 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/impl/CartographySingleWindowImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/CartographySingleWindowImpl.java @@ -1,4 +1,4 @@ -package xyz.xenondevs.invui.window.impl; +package xyz.xenondevs.invui.window; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -14,12 +14,10 @@ import xyz.xenondevs.inventoryaccess.map.MapIcon; import xyz.xenondevs.inventoryaccess.map.MapPatch; import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.util.MathUtils; -import xyz.xenondevs.invui.window.AbstractSingleWindow; -import xyz.xenondevs.invui.window.CartographyWindow; import java.util.List; -public final class CartographySingleWindowImpl extends AbstractSingleWindow implements CartographyWindow { +final class CartographySingleWindowImpl extends AbstractSingleWindow implements CartographyWindow { private final CartographyInventory cartographyInventory; private int mapId; @@ -83,4 +81,31 @@ public final class CartographySingleWindowImpl extends AbstractSingleWindow impl cartographyInventory.open(); } + public static final class BuilderImpl + extends AbstractSingleWindow.AbstractBuilder + implements CartographyWindow.Builder.Single + { + + @Override + public @NotNull CartographyWindow build() { + if (viewer == null) + throw new IllegalStateException("Viewer is not defined."); + if (guiSupplier == null) + throw new IllegalStateException("Gui is not defined."); + + var window = new CartographySingleWindowImpl( + viewer, + title, + (AbstractGui) guiSupplier.get(), + closeable, + retain + ); + + applyModifiers(window); + + return window; + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/impl/CartographySplitWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/CartographySplitWindowImpl.java similarity index 69% rename from invui/src/main/java/xyz/xenondevs/invui/window/impl/CartographySplitWindowImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/window/CartographySplitWindowImpl.java index 45ce4b9..4964fe8 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/impl/CartographySplitWindowImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/CartographySplitWindowImpl.java @@ -1,4 +1,4 @@ -package xyz.xenondevs.invui.window.impl; +package xyz.xenondevs.invui.window; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -13,14 +13,11 @@ import xyz.xenondevs.inventoryaccess.map.MapIcon; import xyz.xenondevs.inventoryaccess.map.MapPatch; import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.impl.NormalGuiImpl; import xyz.xenondevs.invui.util.MathUtils; -import xyz.xenondevs.invui.window.AbstractSplitWindow; -import xyz.xenondevs.invui.window.CartographyWindow; import java.util.List; -public final class CartographySplitWindowImpl extends AbstractSplitWindow implements CartographyWindow { +final class CartographySplitWindowImpl extends AbstractSplitWindow implements CartographyWindow { private final CartographyInventory cartographyInventory; private int mapId; @@ -43,14 +40,13 @@ public final class CartographySplitWindowImpl extends AbstractSplitWindow implem register(); } - @SuppressWarnings("deprecation") private static AbstractGui createWrappingGui(Gui upperGui) { if (upperGui.getWidth() != 2 || upperGui.getHeight() != 1) throw new IllegalArgumentException("Gui has to be 2x1"); - NormalGuiImpl wrapperGui = new NormalGuiImpl(3, 1); + Gui wrapperGui = Gui.empty(3, 1); wrapperGui.fillRectangle(1, 0, upperGui, true); - return wrapperGui; + return (AbstractGui) wrapperGui; } @Override @@ -80,4 +76,33 @@ public final class CartographySplitWindowImpl extends AbstractSplitWindow implem cartographyInventory.open(); } + public static final class BuilderImpl + extends AbstractSplitWindow.AbstractBuilder + implements CartographyWindow.Builder.Split + { + + @Override + public @NotNull CartographyWindow build() { + if (viewer == null) + throw new IllegalStateException("Viewer is not defined."); + if (upperGuiSupplier == null) + throw new IllegalStateException("Upper Gui is not defined."); + + var window = new CartographySplitWindowImpl( + viewer, + title, + (AbstractGui) upperGuiSupplier.get(), + (AbstractGui) lowerGuiSupplier.get(), + closeable, + retain + ); + + applyModifiers(window); + + return window; + } + + } + + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/CartographyWindow.java b/invui/src/main/java/xyz/xenondevs/invui/window/CartographyWindow.java index 377108d..54c0a62 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/CartographyWindow.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/CartographyWindow.java @@ -1,13 +1,36 @@ package xyz.xenondevs.invui.window; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.xenondevs.inventoryaccess.map.MapIcon; import xyz.xenondevs.inventoryaccess.map.MapPatch; import java.util.List; +import java.util.function.Consumer; public interface CartographyWindow extends Window { + static @NotNull Builder.Single single() { + return new CartographySingleWindowImpl.BuilderImpl(); + } + + static @NotNull CartographyWindow single(@NotNull Consumer consumer) { + Builder.Single builder = single(); + consumer.accept(builder); + return builder.build(); + } + + static @NotNull Builder.Split split() { + return new CartographySplitWindowImpl.BuilderImpl(); + } + + static @NotNull CartographyWindow split(@NotNull Consumer consumer) { + Builder.Split builder = split(); + consumer.accept(builder); + return builder.build(); + } + void updateMap(@Nullable MapPatch patch, @Nullable List icons); default void updateMap(@Nullable MapPatch patch) { @@ -20,4 +43,11 @@ public interface CartographyWindow extends Window { void resetMap(); + interface Builder> extends Window.Builder { + + interface Single extends Builder, Window.Builder.Single {} + interface Split extends Builder, Window.Builder.Double {} + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalMergedWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/NormalMergedWindowImpl.java similarity index 52% rename from invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalMergedWindowImpl.java rename to invui/src/main/java/xyz/xenondevs/invui/window/NormalMergedWindowImpl.java index 373f05f..34ec049 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalMergedWindowImpl.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/NormalMergedWindowImpl.java @@ -1,4 +1,4 @@ -package xyz.xenondevs.invui.window.impl; +package xyz.xenondevs.invui.window; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -8,9 +8,8 @@ import org.jetbrains.annotations.Nullable; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; import xyz.xenondevs.invui.gui.AbstractGui; import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.window.AbstractMergedWindow; -public final class NormalMergedWindowImpl extends AbstractMergedWindow { +final class NormalMergedWindowImpl extends AbstractMergedWindow { public NormalMergedWindowImpl( @NotNull Player player, @@ -32,4 +31,30 @@ public final class NormalMergedWindowImpl extends AbstractMergedWindow { return Bukkit.createInventory(null, gui.getSize() - 36); } + public static final class BuilderImpl + extends AbstractSingleWindow.AbstractBuilder + implements Window.Builder.Normal.Merged + { + + @Override + public @NotNull Window build() { + if (viewer == null) + throw new IllegalStateException("Viewer is not defined."); + if (guiSupplier == null) + throw new IllegalStateException("Gui is not defined."); + + var window = new NormalMergedWindowImpl( + viewer, + title, + (AbstractGui) guiSupplier.get(), + closeable, + retain + ); + + applyModifiers(window); + + return window; + } + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/NormalSingleWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/NormalSingleWindowImpl.java new file mode 100644 index 0000000..0cd1ee0 --- /dev/null +++ b/invui/src/main/java/xyz/xenondevs/invui/window/NormalSingleWindowImpl.java @@ -0,0 +1,59 @@ +package xyz.xenondevs.invui.window; + +import org.bukkit.OfflinePlayer; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; +import xyz.xenondevs.invui.gui.AbstractGui; +import xyz.xenondevs.invui.util.InventoryUtils; + +import java.util.UUID; + +final class NormalSingleWindowImpl extends AbstractSingleWindow { + + public NormalSingleWindowImpl( + @NotNull UUID viewerUUID, + @Nullable ComponentWrapper title, + @NotNull AbstractGui gui, + boolean closeable, + boolean retain + ) { + super(viewerUUID, title, gui, InventoryUtils.createMatchingInventory(gui, ""), true, closeable, retain); + register(); + } + + public static final class BuilderImpl + extends AbstractSingleWindow.AbstractBuilder + implements Window.Builder.Normal.Single + { + + @Contract("_ -> this") + public BuilderImpl setViewer(@NotNull OfflinePlayer player) { + setViewer(player.getUniqueId()); + return this; + } + + @Override + public @NotNull Window build() { + if (viewer == null) + throw new IllegalStateException("Viewer is not defined."); + if (guiSupplier == null) + throw new IllegalStateException("Gui is not defined."); + + var window = new NormalSingleWindowImpl( + viewer, + title, + (AbstractGui) guiSupplier.get(), + closeable, + retain + ); + + applyModifiers(window); + + return window; + } + + } + +} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/NormalSplitWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/NormalSplitWindowImpl.java new file mode 100644 index 0000000..488902f --- /dev/null +++ b/invui/src/main/java/xyz/xenondevs/invui/window/NormalSplitWindowImpl.java @@ -0,0 +1,54 @@ +package xyz.xenondevs.invui.window; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; +import xyz.xenondevs.invui.gui.AbstractGui; +import xyz.xenondevs.invui.util.InventoryUtils; + +final class NormalSplitWindowImpl extends AbstractSplitWindow { + + public NormalSplitWindowImpl( + @NotNull Player player, + @Nullable ComponentWrapper title, + @NotNull AbstractGui upperGui, + @NotNull AbstractGui lowerGui, + boolean closeable, + boolean retain + ) { + super(player, title, upperGui, lowerGui, InventoryUtils.createMatchingInventory(upperGui, ""), true, closeable, retain); + register(); + } + + public static final class BuilderImpl + extends AbstractSplitWindow.AbstractBuilder + implements Window.Builder.Normal.Split + { + + @Override + public @NotNull Window build() { + if (viewer == null) + throw new IllegalStateException("Viewer is not defined."); + if (upperGuiSupplier == null) + throw new IllegalStateException("Upper Gui is not defined."); + if (lowerGuiSupplier == null) + throw new IllegalStateException("Lower Gui is not defined."); + + var window = new NormalSplitWindowImpl( + viewer, + title, + (AbstractGui) upperGuiSupplier.get(), + (AbstractGui) lowerGuiSupplier.get(), + closeable, + retain + ); + + applyModifiers(window); + + return window; + } + + } + +} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/Window.java b/invui/src/main/java/xyz/xenondevs/invui/window/Window.java index bb856fa..ef9df28 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/Window.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/Window.java @@ -1,29 +1,93 @@ package xyz.xenondevs.invui.window; import net.md_5.bungee.api.chat.BaseComponent; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; -import xyz.xenondevs.invui.window.builder.WindowType; +import xyz.xenondevs.invui.gui.Gui; import java.util.List; import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.Supplier; /** - * A Window is the way to show a player a Gui. Windows can only have one viewer. - * The default Window implementations can be instantiated using {@link WindowType}. + * A Window is the way to show a player a {@link Gui}. Windows can only have one viewer. + * To create a new {@link Window}, use the builder factory methods {@link Window#single}, + * {@link Window#split} and {@link Window#merged}. * - * @see WindowType - * @see AbstractWindow - * @see AbstractSingleWindow - * @see AbstractDoubleWindow - * @see AbstractSplitWindow - * @see AbstractMergedWindow + * @see AnvilWindow + * @see CartographyWindow */ public interface Window { + /** + * Creates a new {@link Builder.Normal.Single Window Builder} for a normal single window. + * + * @return The new {@link Builder.Normal.Single Window Builder}. + */ + static @NotNull Builder.Normal.Single single() { + return new NormalSingleWindowImpl.BuilderImpl(); + } + + /** + * Creates a new normal single {@link Window} after configuring a {@link Builder.Normal.Split Window Builder} with the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder.Normal.Split Window Builder}. + * @return The new {@link Window}. + */ + static @NotNull Window single(@NotNull Consumer consumer) { + Builder.Normal.Single builder = single(); + consumer.accept(builder); + return builder.build(); + } + + /** + * Creates a new {@link Builder.Normal.Split Window Builder} for a normal split window. + * + * @return The new {@link Builder.Normal.Split Window Builder}. + */ + static @NotNull Builder.Normal.Split split() { + return new NormalSplitWindowImpl.BuilderImpl(); + } + + /** + * Creates a new normal split {@link Window} after configuring a {@link Builder.Normal.Split Window Builder} with the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder.Normal.Split Window Builder}. + * @return The new {@link Window}. + */ + static @NotNull Window split(@NotNull Consumer consumer) { + Builder.Normal.Split builder = split(); + consumer.accept(builder); + return builder.build(); + } + + /** + * Creates a new {@link Builder.Normal.Merged Window Builder} for a normal merged window. + * + * @return The new {@link Builder.Normal.Merged Window Builder}. + */ + static @NotNull Builder.Normal.Merged merged() { + return new NormalMergedWindowImpl.BuilderImpl(); + } + + /** + * Creates a new normal merged {@link Window} after configuring a {@link Builder.Normal.Merged Window Builder} with the given {@link Consumer}. + * + * @param consumer The {@link Consumer} to configure the {@link Builder.Normal.Merged Window Builder}. + * @return The new {@link Window}. + */ + static @NotNull Window merged(@NotNull Consumer consumer) { + Builder.Normal.Merged builder = merged(); + consumer.accept(builder); + return builder.build(); + } + /** * Shows the window to the player. */ @@ -125,4 +189,290 @@ public interface Window { */ void removeCloseHandler(@NotNull Runnable closeHandler); + /** + * A {@link Window} builder. + * + * @param The window type + * @param The viewer type + * @param The builder type + */ + interface Builder> extends Cloneable { + + /** + * Sets the viewer of the {@link Window}. + * + * @param viewer The viewer of the {@link Window} + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setViewer(@NotNull V viewer); + + /** + * Sets the title of the {@link Window}. + * + * @param title The title of the {@link Window} + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setTitle(@NotNull ComponentWrapper title); + + /** + * Sets the title of the {@link Window}. + * + * @param title The title of the {@link Window} + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setTitle(@NotNull BaseComponent @NotNull [] title); + + /** + * Sets the title of the {@link Window}. + * + * @param title The title of the {@link Window} + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setTitle(@NotNull String title); + + /** + * Configures if the {@link Window} is closeable. + * + * @param closeable If the {@link Window} is closeable + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setCloseable(boolean closeable); + + /** + * Configures if the {@link Window} should be retained after it has been closed. + * + * @param retain If the {@link Window} should be retained + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setRetain(boolean retain); + + /** + * Sets the close handlers of the {@link Window}. + * + * @param closeHandlers The close handlers of the {@link Window} + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setCloseHandlers(List closeHandlers); + + /** + * Adds a close handler to the {@link Window}. + * + * @param closeHandler The close handler to add + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S addCloseHandler(Runnable closeHandler); + + /** + * Sets the modifiers of the {@link Window}. + * + * @param modifiers The modifiers of the {@link Window} + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S setModifiers(List> modifiers); + + /** + * Adds a modifier to the {@link Window}. + * + * @param modifier The modifier to add + * @return This {@link Builder Window Builder} + */ + @Contract("_ -> this") + S addModifier(Consumer modifier); + + /** + * Builds the {@link Window}. + * + * @return The built {@link Window} + */ + @Contract("-> new") + @NotNull W build(); + + /** + * Clones the {@link Builder Window Builder}. + * + * @return The cloned {@link Builder Window Builder} + */ + @Contract("-> new") + @NotNull S clone(); + + /** + * A single {@link Window} builder. Single Windows only have on {@link Gui}. + * + * @param The window type + * @param The viewer type + * @param The builder type + * + * @see Window.Builder.Normal.Single + * @see Window.Builder.Normal.Merged + * @see AnvilWindow.Builder.Single + * @see CartographyWindow.Builder.Single + */ + interface Single> extends Builder { + + /** + * Sets the {@link Gui} of the {@link Window}. + * + * @param gui The {@link Gui} of the {@link Window} + * @return This {@link Single Window Builder} + */ + @Contract("_ -> this") + S setGui(@NotNull Gui gui); + + /** + * Sets the {@link Gui.Builder} for this {@link Single Window Builder}. + * The {@link Gui.Builder} will be called every time a new {@link Window} is created using this builder. + * + * @param builder The {@link Gui.Builder} for this {@link Single Window Builder} + * @return This {@link Single Window Builder} + */ + @Contract("_ -> this") + S setGui(@NotNull Gui.Builder builder); + + /** + * Sets the {@link Gui} {@link Supplier} for this {@link Single Window Builder}. + * The {@link Supplier} will be called every time a new {@link Window} is created using this builder. + * + * @param guiSupplier The {@link Gui} {@link Supplier} + * @return This {@link Single Window Builder} + */ + @Contract("_ -> this") + S setGui(@NotNull Supplier guiSupplier); + + } + + /** + * A double {@link Window} builder. Double Windows have two {@link Gui Guis}. + * + * @param The window type + * @param The viewer type + * @param The builder type + * + * @see Window.Builder.Normal.Split + * @see AnvilWindow.Builder.Split + * @see CartographyWindow.Builder.Split + */ + interface Double> extends Builder { + + /** + * Sets the upper {@link Gui} of the {@link Window}. + * + * @param gui The upper {@link Gui} of the {@link Window} + * @return This {@link Double Window Builder} + */ + @Contract("_ -> this") + S setUpperGui(@NotNull Gui gui); + + /** + * Sets the {@link Gui.Builder} for the upper {@link Gui} of this {@link Double Window Builder}. + * The {@link Gui.Builder} will be called every time a new {@link Window} is created using this builder. + * + * @param builder The {@link Gui.Builder} for the upper {@link Gui} of this {@link Double Window Builder} + * @return This {@link Double Window Builder} + */ + @Contract("_ -> this") + S setUpperGui(@NotNull Gui.Builder builder); + + /** + * Sets the {@link Gui} {@link Supplier} for the upper {@link Gui} of this {@link Double Window Builder}. + * The {@link Supplier} will be called every time a new {@link Window} is created using this builder. + * + * @param guiSupplier The {@link Gui} {@link Supplier} for the upper {@link Gui} of this {@link Double Window Builder} + * @return This {@link Double Window Builder} + */ + @Contract("_ -> this") + S setUpperGui(@NotNull Supplier guiSupplier); + + /** + * Sets the lower {@link Gui} of the {@link Window}. + * + * @param gui The lower {@link Gui} of the {@link Window} + * @return This {@link Double Window Builder} + */ + @Contract("_ -> this") + S setLowerGui(@NotNull Gui gui); + + /** + * Sets the {@link Gui.Builder} for the lower {@link Gui} of this {@link Double Window Builder}. + * The {@link Gui.Builder} will be called every time a new {@link Window} is created using this builder. + * + * @param builder The {@link Gui.Builder} for the lower {@link Gui} of this {@link Double Window Builder} + * @return This {@link Double Window Builder} + */ + @Contract("_ -> this") + S setLowerGui(@NotNull Gui.Builder builder); + + /** + * Sets the {@link Gui} {@link Supplier} for the lower {@link Gui} of this {@link Double Window Builder}. + * The {@link Supplier} will be called every time a new {@link Window} is created using this builder. + * + * @param guiSupplier The {@link Gui} {@link Supplier} for the lower {@link Gui} of this {@link Double Window Builder} + * @return This {@link Double Window Builder} + */ + @Contract("_ -> this") + S setLowerGui(@NotNull Supplier guiSupplier); + + } + + /** + * A normal {@link Window} builder for {@link Window Windows} of inventories with no special functionality, such + * as chests, hoppers and droppers. + * + * @param The viewer type + * @param The builder type + * + * @see AnvilWindow.Builder + * @see CartographyWindow.Builder + */ + interface Normal> extends Builder { + + /** + * A normal single {@link Window} builder. Combines both {@link Builder.Single} and {@link Builder.Normal} + * for a normal {@link Window} with only one {@link Gui} that does not access the {@link Player Player's} inventory. + * + * @see AnvilWindow.Builder.Single + * @see CartographyWindow.Builder.Single + */ + interface Single extends Builder.Normal, Builder.Single { + + /** + * Sets the viewer of the {@link Window}. + * + * @param viewer The viewer of the {@link Window} + * @return This {@link Normal.Single Window Builder} + */ + @Contract("_ -> this") + Normal.Single setViewer(@NotNull OfflinePlayer viewer); + + } + + /** + * A normal split {@link Window} builder. Combines both {@link Builder.Double} and {@link Builder.Normal} + * for a normal {@link Window} with two {@link Gui Guis}, where the lower {@link Gui} is used to fill the + * {@link Player Player's} inventory. + * + * @see AnvilWindow.Builder.Split + * @see CartographyWindow.Builder.Split + */ + interface Split extends Builder.Normal, Builder.Double {} + + /** + * A normal merged {@link Window} builder. Combines both {@link Builder.Single} and {@link Builder.Normal} + * for a normal {@link Window} with one {@link Gui}, which fills both the upper inventory and the + * {@link Player Player's} inventory. + */ + interface Merged extends Builder.Normal, Builder.Single {} + + } + + } + } diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSingleWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSingleWindowBuilder.java deleted file mode 100644 index 8c4eaf2..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSingleWindowBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.builder.GuiBuilder; -import xyz.xenondevs.invui.window.Window; - -import java.util.function.Supplier; - -public abstract class AbstractSingleWindowBuilder> extends AbstractWindowBuilder { - - protected Supplier guiSupplier; - - @Contract("_ -> this") - public S setGui(@NotNull Supplier guiSupplier) { - this.guiSupplier = guiSupplier; - return getThis(); - } - - @Contract("_ -> this") - public S setGui(@NotNull Gui gui) { - this.guiSupplier = () -> gui; - return getThis(); - } - - @Contract("_ -> this") - public S setGui(@NotNull GuiBuilder builder) { - this.guiSupplier = builder::build; - return getThis(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSplitWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSplitWindowBuilder.java deleted file mode 100644 index c93e435..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractSplitWindowBuilder.java +++ /dev/null @@ -1,52 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.gui.builder.GuiBuilder; -import xyz.xenondevs.invui.window.Window; - -import java.util.function.Supplier; - -public abstract class AbstractSplitWindowBuilder> extends AbstractWindowBuilder { - - protected Supplier upperGuiSupplier; - protected Supplier lowerGuiSupplier; - - @Contract("_ -> this") - public S setUpperGui(@NotNull Supplier guiSupplier) { - this.upperGuiSupplier = guiSupplier; - return getThis(); - } - - @Contract("_ -> this") - public S setUpperGui(@NotNull Gui gui) { - this.upperGuiSupplier = () -> gui; - return getThis(); - } - - @Contract("_ -> this") - public S setUpperGui(@NotNull GuiBuilder builder) { - this.upperGuiSupplier = builder::build; - return getThis(); - } - - @Contract("_ -> this") - public S setLowerGui(@NotNull Supplier guiSupplier) { - this.lowerGuiSupplier = guiSupplier; - return getThis(); - } - - @Contract("_ -> this") - public S setLowerGui(@NotNull Gui gui) { - this.lowerGuiSupplier = () -> gui; - return getThis(); - } - - @Contract("_ -> this") - public S setLowerGui(@NotNull GuiBuilder builder) { - this.lowerGuiSupplier = builder::build; - return getThis(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractWindowBuilder.java deleted file mode 100644 index 27b8eee..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AbstractWindowBuilder.java +++ /dev/null @@ -1,118 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.TextComponent; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.inventoryaccess.component.BaseComponentWrapper; -import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; -import xyz.xenondevs.invui.window.Window; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public abstract class AbstractWindowBuilder> implements WindowBuilder { - - protected V viewer; - protected ComponentWrapper title; - protected boolean closeable = true; - protected boolean retain = false; - protected List closeHandlers; - protected List> modifiers; - - @Contract("_ -> this") - public S setViewer(@NotNull V viewer) { - this.viewer = viewer; - return getThis(); - } - - @Contract("_ -> this") - public S setTitle(@NotNull ComponentWrapper title) { - this.title = title; - return getThis(); - } - - @Contract("_ -> this") - public S setTitle(@NotNull BaseComponent @NotNull [] title) { - this.title = new BaseComponentWrapper(title); - return getThis(); - } - - @Contract("_ -> this") - public S setTitle(@NotNull String title) { - this.title = new BaseComponentWrapper(TextComponent.fromLegacyText(title)); - return getThis(); - } - - @Contract("_ -> this") - public S setCloseable(boolean closeable) { - this.closeable = closeable; - return getThis(); - } - - @Contract("_ -> this") - public S setRetain(boolean retain) { - this.retain = retain; - return getThis(); - } - - @Contract("_ -> this") - public S setCloseHandlers(List closeHandlers) { - this.closeHandlers = closeHandlers; - return getThis(); - } - - @Contract("_ -> this") - public S addCloseHandler(Runnable closeHandler) { - if (closeHandlers == null) - closeHandlers = new ArrayList<>(); - - closeHandlers.add(closeHandler); - return getThis(); - } - - @Contract("_ -> this") - public S setModifiers(List> modifiers) { - this.modifiers = modifiers; - return getThis(); - } - - @Contract("_ -> this") - public S addModifier(Consumer modifier) { - if (modifiers == null) - modifiers = new ArrayList<>(); - - modifiers.add(modifier); - return getThis(); - } - - protected void applyModifiers(W window) { - if (closeHandlers != null) - window.setCloseHandlers(closeHandlers); - - if (modifiers != null) - modifiers.forEach(modifier -> modifier.accept(window)); - } - - @SuppressWarnings("unchecked") - @Override - public @NotNull AbstractWindowBuilder clone() { - try { - var clone = (AbstractWindowBuilder) super.clone(); - if (title != null) - clone.title = title.clone(); - if (closeHandlers != null) - clone.closeHandlers = new ArrayList<>(closeHandlers); - if (modifiers != null) - clone.modifiers = new ArrayList<>(modifiers); - return clone; - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } - - @Contract(value = "-> this", pure = true) - protected abstract S getThis(); - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSingleWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSingleWindowBuilder.java deleted file mode 100644 index 041d134..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSingleWindowBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.AnvilWindow; -import xyz.xenondevs.invui.window.impl.AnvilSingleWindowImpl; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public final class AnvilSingleWindowBuilder extends AbstractSingleWindowBuilder { - - private List> renameHandlers; - - AnvilSingleWindowBuilder() { - } - - @Contract("_ -> this") - public AnvilSingleWindowBuilder setRenameHandlers(@NotNull List<@NotNull Consumer> renameHandlers) { - this.renameHandlers = renameHandlers; - return this; - } - - @Contract("_ -> this") - public AnvilSingleWindowBuilder addRenameHandler(@NotNull Consumer renameHandler) { - if (renameHandlers == null) - renameHandlers = new ArrayList<>(); - - renameHandlers.add(renameHandler); - return this; - } - - @Override - public @NotNull AnvilWindow build() { - if (viewer == null) - throw new IllegalStateException("Viewer is not defined."); - if (guiSupplier == null) - throw new IllegalStateException("Gui is not defined."); - - var window = new AnvilSingleWindowImpl( - viewer, - title, - (AbstractGui) guiSupplier.get(), - renameHandlers, - closeable, - retain - ); - - applyModifiers(window); - - return window; - } - - @Override - protected AnvilSingleWindowBuilder getThis() { - return null; - } - - @Override - public @NotNull AnvilSingleWindowBuilder clone() { - return (AnvilSingleWindowBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSplitWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSplitWindowBuilder.java deleted file mode 100644 index 5cc0e81..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/AnvilSplitWindowBuilder.java +++ /dev/null @@ -1,70 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.AnvilWindow; -import xyz.xenondevs.invui.window.impl.AnvilSplitWindowImpl; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public final class AnvilSplitWindowBuilder extends AbstractSplitWindowBuilder { - - private List> renameHandlers; - - AnvilSplitWindowBuilder() { - } - - @Contract("_ -> this") - public AnvilSplitWindowBuilder setRenameHandlers(@NotNull List<@NotNull Consumer> renameHandlers) { - this.renameHandlers = renameHandlers; - return this; - } - - @Contract("_ -> this") - public AnvilSplitWindowBuilder addRenameHandler(@NotNull Consumer renameHandler) { - if (renameHandlers == null) - renameHandlers = new ArrayList<>(); - - renameHandlers.add(renameHandler); - return this; - } - - @Override - public @NotNull AnvilWindow build() { - if (viewer == null) - throw new IllegalStateException("Viewer is not defined."); - if (upperGuiSupplier == null) - throw new IllegalStateException("Upper Gui is not defined."); - if (lowerGuiSupplier == null) - throw new IllegalStateException("Lower Gui is not defined."); - - var window = new AnvilSplitWindowImpl( - viewer, - title, - (AbstractGui) upperGuiSupplier.get(), - (AbstractGui) lowerGuiSupplier.get(), - renameHandlers, - closeable, - retain - ); - - applyModifiers(window); - - return window; - } - - @Override - protected AnvilSplitWindowBuilder getThis() { - return this; - } - - @Override - public @NotNull AnvilSplitWindowBuilder clone() { - return (AnvilSplitWindowBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySingleWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySingleWindowBuilder.java deleted file mode 100644 index ab76e1d..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySingleWindowBuilder.java +++ /dev/null @@ -1,44 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.CartographyWindow; -import xyz.xenondevs.invui.window.impl.CartographySingleWindowImpl; - -public final class CartographySingleWindowBuilder extends AbstractSingleWindowBuilder { - - CartographySingleWindowBuilder() { - } - - @Override - public @NotNull CartographyWindow build() { - if (viewer == null) - throw new IllegalStateException("Viewer is not defined."); - if (guiSupplier == null) - throw new IllegalStateException("Gui is not defined."); - - var window = new CartographySingleWindowImpl( - viewer, - title, - (AbstractGui) guiSupplier.get(), - closeable, - retain - ); - - applyModifiers(window); - - return window; - } - - @Override - protected CartographySingleWindowBuilder getThis() { - return this; - } - - @Override - public @NotNull CartographySingleWindowBuilder clone() { - return (CartographySingleWindowBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySplitWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySplitWindowBuilder.java deleted file mode 100644 index da179ce..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/CartographySplitWindowBuilder.java +++ /dev/null @@ -1,45 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.CartographyWindow; -import xyz.xenondevs.invui.window.impl.CartographySplitWindowImpl; - -public final class CartographySplitWindowBuilder extends AbstractSplitWindowBuilder { - - CartographySplitWindowBuilder() { - } - - @Override - public @NotNull CartographyWindow build() { - if (viewer == null) - throw new IllegalStateException("Viewer is not defined."); - if (upperGuiSupplier == null) - throw new IllegalStateException("Upper Gui is not defined."); - - var window = new CartographySplitWindowImpl( - viewer, - title, - (AbstractGui) upperGuiSupplier.get(), - (AbstractGui) lowerGuiSupplier.get(), - closeable, - retain - ); - - applyModifiers(window); - - return window; - } - - @Override - protected CartographySplitWindowBuilder getThis() { - return this; - } - - @Override - public @NotNull CartographySplitWindowBuilder clone() { - return (CartographySplitWindowBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalMergedWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalMergedWindowBuilder.java deleted file mode 100644 index 5e778da..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalMergedWindowBuilder.java +++ /dev/null @@ -1,44 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.Window; -import xyz.xenondevs.invui.window.impl.NormalMergedWindowImpl; - -public final class NormalMergedWindowBuilder extends AbstractSingleWindowBuilder { - - NormalMergedWindowBuilder() { - } - - @Override - public @NotNull Window build() { - if (viewer == null) - throw new IllegalStateException("Viewer is not defined."); - if (guiSupplier == null) - throw new IllegalStateException("Gui is not defined."); - - var window = new NormalMergedWindowImpl( - viewer, - title, - (AbstractGui) guiSupplier.get(), - closeable, - retain - ); - - applyModifiers(window); - - return window; - } - - @Override - protected NormalMergedWindowBuilder getThis() { - return this; - } - - @Override - public @NotNull NormalMergedWindowBuilder clone() { - return (NormalMergedWindowBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSingleWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSingleWindowBuilder.java deleted file mode 100644 index 73df9ef..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSingleWindowBuilder.java +++ /dev/null @@ -1,53 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.bukkit.OfflinePlayer; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.Window; -import xyz.xenondevs.invui.window.impl.NormalSingleWindowImpl; - -import java.util.UUID; - -public final class NormalSingleWindowBuilder extends AbstractSingleWindowBuilder { - - NormalSingleWindowBuilder() { - } - - @Contract("_ -> this") - public NormalSingleWindowBuilder setViewer(@NotNull OfflinePlayer player) { - setViewer(player.getUniqueId()); - return this; - } - - @Override - public @NotNull Window build() { - if (viewer == null) - throw new IllegalStateException("Viewer is not defined."); - if (guiSupplier == null) - throw new IllegalStateException("Gui is not defined."); - - var window = new NormalSingleWindowImpl( - viewer, - title, - (AbstractGui) guiSupplier.get(), - closeable, - retain - ); - - applyModifiers(window); - - return window; - } - - @Override - protected NormalSingleWindowBuilder getThis() { - return this; - } - - @Override - public @NotNull NormalSingleWindowBuilder clone() { - return (NormalSingleWindowBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSplitWindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSplitWindowBuilder.java deleted file mode 100644 index dcf76e7..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/NormalSplitWindowBuilder.java +++ /dev/null @@ -1,47 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.Window; -import xyz.xenondevs.invui.window.impl.NormalSplitWindowImpl; - -public final class NormalSplitWindowBuilder extends AbstractSplitWindowBuilder { - - NormalSplitWindowBuilder() { - } - - @Override - public @NotNull Window build() { - if (viewer == null) - throw new IllegalStateException("Viewer is not defined."); - if (upperGuiSupplier == null) - throw new IllegalStateException("Upper Gui is not defined."); - if (lowerGuiSupplier == null) - throw new IllegalStateException("Lower Gui is not defined."); - - var window = new NormalSplitWindowImpl( - viewer, - title, - (AbstractGui) upperGuiSupplier.get(), - (AbstractGui) lowerGuiSupplier.get(), - closeable, - retain - ); - - applyModifiers(window); - - return window; - } - - @Override - protected NormalSplitWindowBuilder getThis() { - return this; - } - - @Override - public @NotNull NormalSplitWindowBuilder clone() { - return (NormalSplitWindowBuilder) super.clone(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowBuilder.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowBuilder.java deleted file mode 100644 index b233364..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowBuilder.java +++ /dev/null @@ -1,15 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.window.Window; - -public interface WindowBuilder extends Cloneable { - - @Contract("-> new") - @NotNull W build(); - - @Contract("-> new") - @NotNull WindowBuilder clone(); - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowType.java b/invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowType.java deleted file mode 100644 index 0a22c9b..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/builder/WindowType.java +++ /dev/null @@ -1,39 +0,0 @@ -package xyz.xenondevs.invui.window.builder; - -import org.jetbrains.annotations.NotNull; -import xyz.xenondevs.invui.window.AnvilWindow; -import xyz.xenondevs.invui.window.CartographyWindow; -import xyz.xenondevs.invui.window.Window; - -import java.util.function.Consumer; - -public interface WindowType> { - - WindowType NORMAL = NormalSingleWindowBuilder::new; - WindowType NORMAL_MERGED = NormalMergedWindowBuilder::new; - WindowType NORMAL_SPLIT = NormalSplitWindowBuilder::new; - WindowType ANVIL = AnvilSingleWindowBuilder::new; - WindowType ANVIL_SPLIT = AnvilSplitWindowBuilder::new; - WindowType CARTOGRAPHY = CartographySingleWindowBuilder::new; - WindowType CARTOGRAPHY_SPLIT = CartographySplitWindowBuilder::new; - - /** - * Creates a new {@link WindowBuilder} for this {@link WindowType}. - * - * @return The new {@link WindowBuilder}. - */ - @NotNull B builder(); - - /** - * Creates a new {@link Window} after modifying the {@link WindowBuilder} with the given {@link Consumer}. - * - * @param builderConsumer The {@link Consumer} which modifies the {@link WindowBuilder}. - * @return The new {@link Window}. - */ - default @NotNull W createWindow(Consumer builderConsumer) { - B builder = builder(); - builderConsumer.accept(builder); - return builder.build(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/impl/AnvilSplitWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/impl/AnvilSplitWindowImpl.java deleted file mode 100644 index 22e0159..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/impl/AnvilSplitWindowImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -package xyz.xenondevs.invui.window.impl; - -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.inventoryaccess.InventoryAccess; -import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; -import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.window.AbstractSplitWindow; -import xyz.xenondevs.invui.window.AnvilWindow; - -import java.util.List; -import java.util.function.Consumer; - -public final class AnvilSplitWindowImpl extends AbstractSplitWindow implements AnvilWindow { - - private final AnvilInventory anvilInventory; - - public AnvilSplitWindowImpl( - @NotNull Player player, - @Nullable ComponentWrapper title, - @NotNull AbstractGui upperGui, - @NotNull AbstractGui lowerGui, - @Nullable List<@NotNull Consumer<@NotNull String>> renameHandlers, - boolean closeable, - boolean retain - ) { - super(player, title, upperGui, lowerGui, null, false, closeable, retain); - - anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandlers); - upperInventory = anvilInventory.getBukkitInventory(); - - initUpperItems(); - register(); - } - - @Override - protected void setUpperInvItem(int slot, ItemStack itemStack) { - anvilInventory.setItem(slot, itemStack); - } - - @Override - public void show() { - if (isRemoved()) throw new IllegalStateException("The Window has already been closed."); - - Player viewer = getViewer(); - if (viewer == null) throw new IllegalStateException("The player is not online."); - anvilInventory.open(); - } - - @Override - public String getRenameText() { - return anvilInventory.getRenameText(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSingleWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSingleWindowImpl.java deleted file mode 100644 index 1d7b33a..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSingleWindowImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package xyz.xenondevs.invui.window.impl; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.util.InventoryUtils; -import xyz.xenondevs.invui.window.AbstractSingleWindow; - -import java.util.UUID; - -public final class NormalSingleWindowImpl extends AbstractSingleWindow { - - public NormalSingleWindowImpl( - @NotNull UUID viewerUUID, - @Nullable ComponentWrapper title, - @NotNull AbstractGui gui, - boolean closeable, - boolean retain - ) { - super(viewerUUID, title, gui, InventoryUtils.createMatchingInventory(gui, ""), true, closeable, retain); - register(); - } - -} diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSplitWindowImpl.java b/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSplitWindowImpl.java deleted file mode 100644 index 2a2e7fb..0000000 --- a/invui/src/main/java/xyz/xenondevs/invui/window/impl/NormalSplitWindowImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package xyz.xenondevs.invui.window.impl; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; -import xyz.xenondevs.invui.gui.AbstractGui; -import xyz.xenondevs.invui.util.InventoryUtils; -import xyz.xenondevs.invui.window.AbstractSplitWindow; - -public final class NormalSplitWindowImpl extends AbstractSplitWindow { - - public NormalSplitWindowImpl( - @NotNull Player player, - @Nullable ComponentWrapper title, - @NotNull AbstractGui upperGui, - @NotNull AbstractGui lowerGui, - boolean closeable, - boolean retain - ) { - super(player, title, upperGui, lowerGui, InventoryUtils.createMatchingInventory(upperGui, ""), true, closeable, retain); - register(); - } - -}