diff --git a/pom.xml b/pom.xml
index eb2580c14..8f539fa74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,12 @@
5.1.0provided
+
+ it.unimi.dsi
+ fastutil
+ 8.5.6
+ provided
+ org.junit.jupiter
diff --git a/src/main/java/com/wolfyscript/utilities/NamespacedKey.java b/src/main/java/com/wolfyscript/utilities/NamespacedKey.java
index 6e58c013f..9545ca225 100644
--- a/src/main/java/com/wolfyscript/utilities/NamespacedKey.java
+++ b/src/main/java/com/wolfyscript/utilities/NamespacedKey.java
@@ -18,6 +18,12 @@
package com.wolfyscript.utilities;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import net.kyori.adventure.key.Key;
+import net.kyori.adventure.key.Namespaced;
+import org.intellij.lang.annotations.Pattern;
+import org.intellij.lang.annotations.Subst;
+
/**
* The NamespacedKey is used to manage and identify resources and prevent conflicts with for example plugins.
* It consists of a unique namespace and a key. (The same key can exist in different namespaces)
@@ -55,6 +61,10 @@ public interface NamespacedKey {
String toString(String separator);
+ default net.kyori.adventure.key.Key toKyoriKey() {
+ return net.kyori.adventure.key.Key.key(toString(":"));
+ }
+
/**
* Represents the key part of the NamespacedKey.
* The idea behind this component is to make it easier to manage folders specified in the key and provide util methods for it.
diff --git a/src/main/java/com/wolfyscript/utilities/Platform.java b/src/main/java/com/wolfyscript/utilities/Platform.java
new file mode 100644
index 000000000..028d64a8a
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/Platform.java
@@ -0,0 +1,27 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities;
+
+public enum Platform {
+
+ SPIGOT,
+ PAPER,
+ SPONGE
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java b/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java
index 1aebe07ca..668045340 100644
--- a/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java
+++ b/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java
@@ -19,8 +19,11 @@
package com.wolfyscript.utilities.common;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.wolfyscript.utilities.Platform;
import com.wolfyscript.utilities.common.chat.Chat;
import com.wolfyscript.utilities.common.registry.Registries;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.platform.AudienceProvider;
import org.reflections.Reflections;
/**
@@ -38,4 +41,6 @@ public interface WolfyCore {
Reflections getReflections();
Registries getRegistries();
+
+ Platform getPlatform();
}
diff --git a/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java b/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java
index 02eef6276..c6d21ce14 100644
--- a/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java
+++ b/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java
@@ -20,12 +20,14 @@
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
import com.wolfyscript.utilities.common.chat.Chat;
+import com.wolfyscript.utilities.common.gui.GuiAPIManager;
import com.wolfyscript.utilities.common.json.jackson.MapperUtil;
import com.wolfyscript.utilities.common.registry.Registries;
import java.util.logging.Logger;
import com.wolfyscript.utilities.common.language.LanguageAPI;
import java.io.File;
+import java.util.regex.Pattern;
/**
* Represents a single API instance that is bound to a plugin or mod.
@@ -68,6 +70,8 @@ public static boolean isProdEnv() {
public abstract Identifiers getIdentifiers();
+ public abstract GuiAPIManager getGUIManager();
+
public Registries getRegistries() {
return getCore().getRegistries();
}
@@ -76,5 +80,7 @@ public MapperUtil getJacksonMapperUtil() {
return mapperUtil;
}
+ public abstract void exportResource(String resourcePath, File destination, boolean replace);
+ public abstract void exportResources(String resourceName, File dir, boolean replace, Pattern filePattern);
}
diff --git a/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java b/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java
index e848b3e82..50cd26417 100644
--- a/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java
+++ b/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java
@@ -22,8 +22,12 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.UUID;
+
public interface Entity {
+ UUID uuid();
+
@NotNull
Location getLocation();
diff --git a/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java b/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java
index 2e0fa5f08..8146a19b4 100644
--- a/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java
+++ b/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java
@@ -18,10 +18,33 @@
package com.wolfyscript.utilities.common.adapters;
+import com.wolfyscript.utilities.NamespacedKey;
+import com.wolfyscript.utilities.common.items.ItemStackConfig;
+
public interface ItemStack {
- Item getItem();
+ /**
+ * The id representing the item of this ItemStack.
+ * Usually e.g.
minecraft:<item_id>
+ *
+ * @return The id of the item.
+ */
+ NamespacedKey getItem();
+ /**
+ * The stack amount of this ItemStack.
+ *
+ * @return The stack amount.
+ */
int getAmount();
+ /**
+ * Creates a snapshot of the whole ItemStack including the full NBT.
+ * This can be quite resource heavy!
+ * The snapshot can be simply written to json using the Json mapper of WolfyUtils.
+ *
+ * @return The snapshot ItemStack config of this ItemStack.
+ */
+ ItemStackConfig> snapshot();
+
}
diff --git a/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java b/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java
index 03a2407b7..af31d8d8c 100644
--- a/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java
+++ b/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java
@@ -20,6 +20,6 @@
public interface Items {
- Item getItem(String key);
+
}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ButtonStateDefault.java b/src/main/java/com/wolfyscript/utilities/common/gui/ButtonStateDefault.java
new file mode 100644
index 000000000..16da727a6
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/ButtonStateDefault.java
@@ -0,0 +1,97 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.google.common.base.Preconditions;
+import com.wolfyscript.utilities.common.gui.callback.InteractionCallback;
+import com.wolfyscript.utilities.common.gui.callback.RenderCallback;
+import com.wolfyscript.utilities.common.gui.components.ButtonState;
+import java.util.Objects;
+
+public class ButtonStateDefault implements ButtonState {
+
+ private final String key;
+ private final InteractionCallback interactionCallback;
+ private final RenderCallback renderCallback;
+
+ protected ButtonStateDefault(String key, InteractionCallback interactionCallback, RenderCallback renderCallback) {
+ this.key = key;
+ this.interactionCallback = interactionCallback;
+ this.renderCallback = renderCallback;
+ }
+
+ @Override
+ public InteractionCallback interactCallback() {
+ return interactionCallback;
+ }
+
+ @Override
+ public RenderCallback renderCallback() {
+ return renderCallback;
+ }
+
+ @Override
+ public String key() {
+ return key;
+ }
+
+ public static class Builder implements ButtonState.Builder {
+
+ private String key;
+ private InteractionCallback interactionCallback;
+ private RenderCallback renderCallback;
+
+ protected Builder(String ownerID) {
+ this.key = ownerID;
+ }
+
+ @Override
+ public Builder subKey(String subKey) {
+ this.key += "." + subKey;
+ return this;
+ }
+
+ @Override
+ public Builder key(String key) {
+ this.key = key;
+ return this;
+ }
+
+ @Override
+ public Builder interact(InteractionCallback interactionCallback) {
+ this.interactionCallback = interactionCallback;
+ return this;
+ }
+
+ @Override
+ public Builder render(RenderCallback renderCallback) {
+ this.renderCallback = renderCallback;
+ return null;
+ }
+
+ @Override
+ public ButtonStateDefault create() {
+ Preconditions.checkNotNull(renderCallback, "Cannot create Component without a RenderCallback!");
+ final var interactCallback = Objects.requireNonNullElseGet(this.interactionCallback, () -> (holder, details) -> InteractionResult.def());
+ final var renderCallback = Objects.requireNonNullElseGet(this.renderCallback, () -> (holder) -> {});
+
+ return new ButtonStateDefault(key, interactCallback, renderCallback);
+ }
+ }
+ }
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GUIClickInteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/ClickInteractionDetails.java
similarity index 75%
rename from src/main/java/com/wolfyscript/utilities/common/gui/GUIClickInteractionDetails.java
rename to src/main/java/com/wolfyscript/utilities/common/gui/ClickInteractionDetails.java
index 245bf92d9..b00ebd050 100644
--- a/src/main/java/com/wolfyscript/utilities/common/gui/GUIClickInteractionDetails.java
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/ClickInteractionDetails.java
@@ -1,6 +1,6 @@
package com.wolfyscript.utilities.common.gui;
-public interface GUIClickInteractionDetails extends GUIInteractionDetails {
+public interface ClickInteractionDetails extends InteractionDetails {
boolean isShift();
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Component.java b/src/main/java/com/wolfyscript/utilities/common/gui/Component.java
new file mode 100644
index 000000000..fc0c31374
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Component.java
@@ -0,0 +1,100 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.wolfyscript.utilities.Keyed;
+import com.wolfyscript.utilities.NamespacedKey;
+import com.wolfyscript.utilities.common.WolfyUtils;
+import it.unimi.dsi.fastutil.ints.IntList;
+
+import java.util.function.Consumer;
+
+public interface Component extends Keyed {
+
+ @JsonIgnore
+ @Override
+ NamespacedKey getNamespacedKey();
+
+ @JsonGetter("type")
+ default NamespacedKey type() {
+ return getNamespacedKey();
+ }
+
+ /**
+ * Gets the unique id (in context of the parent) of this component.
+ *
+ * @return The id of this component.
+ */
+ String getID();
+
+ /**
+ * Gets the global WolfyUtils instance, this component belongs to.
+ *
+ * @return The WolfyUtils API instance.
+ */
+ WolfyUtils getWolfyUtils();
+
+ /**
+ * The parent of this Component, or null if it is a root Component.
+ *
+ * @return The parent; or null if root Component.
+ */
+ Component parent();
+
+ Component construct(GuiHolder holder, GuiViewManager viewManager);
+
+ void remove(GuiHolder holder, GuiViewManager viewManager, RenderContext context);
+
+ /**
+ * Gets the width of this Component in slot count.
+ *
+ * @return The width in slots.
+ */
+ int width();
+
+ /**
+ * Gets the width of this Component in slot count.
+ *
+ * @return The height in slots.
+ */
+ int height();
+
+ Position position();
+
+ default int offset() {
+ Component parent = parent();
+ int totalOffset = 0;
+ while(parent != null && parent.position().type() != Position.Type.ABSOLUTE) {
+ totalOffset += parent.position().slot();
+ parent = parent.parent();
+ }
+ return totalOffset;
+ }
+
+ default void executeForAllSlots(int positionSlot, Consumer slotFunction) {
+ for (int i = 0; i < height(); i++) {
+ for (int j = 0; j < width(); j++) {
+ slotFunction.accept(positionSlot + j + i * (9 - width()));
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilder.java
new file mode 100644
index 000000000..acf83586c
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilder.java
@@ -0,0 +1,65 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
+import com.fasterxml.jackson.databind.annotation.JsonTypeResolver;
+import com.wolfyscript.utilities.Keyed;
+import com.wolfyscript.utilities.NamespacedKey;
+import com.wolfyscript.utilities.common.gui.signal.Signal;
+import com.wolfyscript.utilities.json.KeyedTypeIdResolver;
+import com.wolfyscript.utilities.json.KeyedTypeResolver;
+
+import java.util.List;
+import java.util.Set;
+
+
+@JsonTypeResolver(KeyedTypeResolver.class)
+@JsonTypeIdResolver(KeyedTypeIdResolver.class)
+@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
+@JsonPropertyOrder(value = { "type" })
+@JsonIgnoreProperties(ignoreUnknown = true)
+public interface ComponentBuilder extends Keyed {
+
+ @JsonIgnore
+ @Override
+ NamespacedKey getNamespacedKey();
+
+ default NamespacedKey getType() {
+ return getNamespacedKey();
+ }
+
+ String id();
+
+ Position position();
+
+ /**
+ * Gets the signals that this component builder uses inside the parent construction consumer.
+ *
+ * @return The signals used in this builder.
+ */
+ Set> signals();
+
+ COMPONENT create(PARENT parent);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilderSettings.java b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilderSettings.java
new file mode 100644
index 000000000..115a19d7e
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilderSettings.java
@@ -0,0 +1,34 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ComponentBuilderSettings {
+
+ Class extends Component> component();
+
+ Class extends ComponentBuilder,?>> base();
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GUIDragInteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/DragInteractionDetails.java
similarity index 69%
rename from src/main/java/com/wolfyscript/utilities/common/gui/GUIDragInteractionDetails.java
rename to src/main/java/com/wolfyscript/utilities/common/gui/DragInteractionDetails.java
index ba089c767..7000a5185 100644
--- a/src/main/java/com/wolfyscript/utilities/common/gui/GUIDragInteractionDetails.java
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/DragInteractionDetails.java
@@ -2,7 +2,7 @@
import java.util.Set;
-public interface GUIDragInteractionDetails extends GUIInteractionDetails {
+public interface DragInteractionDetails extends InteractionDetails {
Set getInventorySlots();
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/DynamicConstructor.java b/src/main/java/com/wolfyscript/utilities/common/gui/DynamicConstructor.java
new file mode 100644
index 000000000..73e9c4022
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/DynamicConstructor.java
@@ -0,0 +1,37 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.gui.signal.Signal;
+import com.wolfyscript.utilities.common.gui.signal.Store;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+public interface DynamicConstructor {
+
+ GuiViewManager viewManager();
+
+ GuiHolder holder();
+
+ Signal signal(String key, Class type, Supplier defaultValueFunction);
+
+ Store syncStore(String key, Class type, Supplier getValue, Consumer setValue);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GUIInteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/GUIInteractionDetails.java
deleted file mode 100644
index 7e43063b0..000000000
--- a/src/main/java/com/wolfyscript/utilities/common/gui/GUIInteractionDetails.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.wolfyscript.utilities.common.gui;
-
-public interface GUIInteractionDetails {
-
- boolean isCancelled();
-
- ButtonInteractionResult.ResultType getResultType();
-
-}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManager.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManager.java
new file mode 100644
index 000000000..91b8c7823
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManager.java
@@ -0,0 +1,82 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+/**
+ * Handles the general GUI API and acts as an entry point to the whole creation of {@link Router}s and {@link GuiViewManager}s.
+ * It stores all the registered {@link Router}s and allows to register new clusters via builders.
+ * Additionally, it stores the {@link GuiViewManager}s that handle the views for players.
+ */
+public interface GuiAPIManager {
+
+ /**
+ * Registers a new router under the given id.
+ * The builder consumer provides the newly constructed {@link RouterBuilder}, which can then be used inside that consumer.
+ *
+ * @param id The unique id of the router to register.
+ * @param routerBuilderConsumer The consumer that provides the new builder.
+ */
+ void registerGui(String guiID, Consumer routerBuilderConsumer);
+
+ /**
+ * Registers a new router that it loads from the specified gui data directory.
+ * The consumer function provides that newly constructed {@link RouterBuilder}, which can be used to manipulate the builder.
+ *
+ * @param id The unique id of the router to register.
+ * @param routerBuilderConsumer The function to manipulate the new builder.
+ */
+ void registerGuiFromFiles(String guiID, Consumer routerBuilderConsumer);
+
+ /**
+ * Gets the registered router with the specified id.
+ *
+ * @param id The id of the router.
+ * @return The registered router only if the id matches; otherwise empty Optional.
+ */
+ Optional getGui(String id);
+
+ /**
+ * Creates a new view for the specified viewers, with the specified cluster as its root.
+ * This gets the registered cluster using {@link #getGui(String)}.
+ *
+ * @param clusterId The id of the root cluster.
+ * @param viewers The viewers of this view.
+ * @return The newly created view.
+ */
+ GuiViewManager createView(String guiId, UUID... viewers);
+
+ /**
+ * Same as {@link #createView(String, UUID...)} and opens the entry menu right after the creation of the view.
+ *
+ * @param clusterID The id of the root cluster.
+ * @param viewers The viewers of this view.
+ * @return The newly created view.
+ */
+ GuiViewManager createViewAndOpen(String guiID, UUID... viewers);
+
+ Stream getViewManagersFor(UUID uuid);
+
+ Stream getViewManagersFor(UUID uuid, String guiID);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManagerCommonImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManagerCommonImpl.java
new file mode 100644
index 000000000..9f4041665
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManagerCommonImpl.java
@@ -0,0 +1,53 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.wolfyscript.utilities.common.WolfyUtils;
+import java.util.Optional;
+import java.util.UUID;
+
+public abstract class GuiAPIManagerCommonImpl implements GuiAPIManager {
+
+ protected final WolfyUtils wolfyUtils;
+ private final BiMap clustersMap = HashBiMap.create();
+
+ public GuiAPIManagerCommonImpl(WolfyUtils wolfyUtils) {
+ this.wolfyUtils = wolfyUtils;
+ }
+
+ protected void registerGui(String id, Router router) {
+ Preconditions.checkArgument(!clustersMap.containsKey(router.getID()), "A cluster with the id '" + router.getID() + "' is already registered!");
+ clustersMap.put(id, router);
+ }
+
+ @Override
+ public GuiViewManager createViewAndOpen(String guiId, UUID... players) {
+ GuiViewManager handler = createView(guiId, players);
+ handler.openNew();
+ return handler;
+ }
+
+ @Override
+ public Optional getGui(String id) {
+ return Optional.ofNullable(clustersMap.get(id));
+ }
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolder.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolder.java
new file mode 100644
index 000000000..994f37257
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolder.java
@@ -0,0 +1,31 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.adapters.Player;
+
+public interface GuiHolder {
+
+ GuiViewManager getViewManager();
+
+ Player getPlayer();
+
+ Window getCurrentWindow();
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolderCommonImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolderCommonImpl.java
new file mode 100644
index 000000000..1718520f4
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolderCommonImpl.java
@@ -0,0 +1,40 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+public abstract class GuiHolderCommonImpl implements GuiHolder {
+
+ protected final Window currentWindow;
+ protected final GuiViewManager viewManager;
+
+ public GuiHolderCommonImpl(Window currentWindow, GuiViewManager viewManager) {
+ this.currentWindow = currentWindow;
+ this.viewManager = viewManager;
+ }
+
+ @Override
+ public Window getCurrentWindow() {
+ return currentWindow;
+ }
+
+ @Override
+ public GuiViewManager getViewManager() {
+ return viewManager;
+ }
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManager.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManager.java
new file mode 100644
index 000000000..af31f0953
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManager.java
@@ -0,0 +1,101 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.WolfyUtils;
+import com.wolfyscript.utilities.common.gui.callback.TextInputCallback;
+import com.wolfyscript.utilities.common.gui.callback.TextInputTabCompleteCallback;
+
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * The GuiViewManager, as the name suggests, manages a view of the GUI for one or more players.
+ * It contains the custom Data object that stores all the required data of this view.
+ *
+ * The view is immutable, so you need to create a new view each time you need to add a viewer or change the root.
+ *
+ */
+public interface GuiViewManager {
+
+ /**
+ * Opens a new menu under the specific path.
+ * When the component at the specified path cannot be rendered (is not a window) it'll use the entry of that component.
+ *
+ * @param path The path to the menu to open.
+ */
+ void openNew(String... path);
+
+ /**
+ * Opens the entry menu of this root cluster.
+ */
+ void openNew();
+
+ /**
+ * Opens the currently active menu without updating the history.
+ * In case there is no active menu it opens the entry of the root cluster.
+ */
+ void open();
+
+ /**
+ * Goes back to the previously opened menu and opens it.
+ */
+ void openPrevious();
+
+ /**
+ * The router of this view manager.
+ *
+ * @return The root cluster of this view manager.
+ */
+ Router getRouter();
+
+ /**
+ * Gets the currently active menu.
+ *
+ * @return The currently active menu.
+ */
+ Optional getCurrentMenu();
+
+ /**
+ * Gets the viewers that are handled by this view manager.
+ * When using these UUIDS, make sure the associated player is actually online!
+ *
+ * @return A Set of the viewers, that are handled by this manager.
+ */
+ Set getViewers();
+
+ /**
+ * The API instance this manager belongs to.
+ *
+ * @return The API instance of this manager.
+ */
+ WolfyUtils getWolfyUtils();
+
+ Optional getRenderContext(UUID viewer);
+
+ Optional textInputCallback();
+
+ void setTextInputCallback(TextInputCallback inputCallback);
+
+ Optional textInputTabCompleteCallback();
+
+ void setTextInputTabCompleteCallback(TextInputTabCompleteCallback textInputTabCompleteCallback);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManagerCommonImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManagerCommonImpl.java
new file mode 100644
index 000000000..e8495b6be
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManagerCommonImpl.java
@@ -0,0 +1,103 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.TypeLiteral;
+import com.wolfyscript.utilities.common.WolfyUtils;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+
+public abstract class GuiViewManagerCommonImpl implements GuiViewManager {
+
+ private final WolfyUtils wolfyUtils;
+ private final Router router;
+ private Window currentRoot;
+ private final Deque history;
+ private final Set viewers;
+
+ protected GuiViewManagerCommonImpl(WolfyUtils wolfyUtils, Router router, Set viewers) {
+ this.wolfyUtils = wolfyUtils;
+ this.router = router;
+
+ this.history = new ArrayDeque<>();
+ this.viewers = viewers;
+ // Construct custom data instance
+ Injector injector = Guice.createInjector(binder -> {
+ binder.bind(WolfyUtils.class).toInstance(wolfyUtils);
+ binder.bind(Router.class).toInstance(router);
+ binder.bind(new TypeLiteral() {
+ }).toInstance(this);
+ binder.bind(new TypeLiteral>() {
+ }).toInstance(viewers);
+ });
+ }
+
+ @Override
+ public void openNew() {
+ openNew(new String[0]);
+ }
+
+ @Override
+ public void open() {
+ if (history.isEmpty()) {
+ openNew();
+ } else {
+ getCurrentMenu().ifPresent(window -> window.open(this));
+ }
+ }
+
+ @Override
+ public void openPrevious() {
+ history.poll(); // Remove active current menu
+ setCurrentRoot(history.peek());
+ getCurrentMenu().ifPresent(previous -> {
+ // Do not add menu to history, as it is already available
+ previous.open(this);
+ });
+ }
+
+ public void setCurrentRoot(Window currentRoot) {
+ this.currentRoot = currentRoot;
+ }
+
+ @Override
+ public Optional getCurrentMenu() {
+ return Optional.ofNullable(currentRoot);
+ }
+
+ @Override
+ public WolfyUtils getWolfyUtils() {
+ return wolfyUtils;
+ }
+
+ @Override
+ public Router getRouter() {
+ return router;
+ }
+
+ @Override
+ public Set getViewers() {
+ return Set.copyOf(viewers);
+ }
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Interactable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Interactable.java
new file mode 100644
index 000000000..7e99ee643
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Interactable.java
@@ -0,0 +1,46 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.gui.callback.InteractionCallback;
+
+public interface Interactable {
+
+ /**
+ * Called when an interaction occurs inside the Component.
+ * This may be called if a child Component is interacted with, for example a Button will cause this interaction to
+ * propagate from the root Cluster, down the Windows to the Button that caused the interaction to be called.
+ *
+ * For this behaviour any implementation must first call the parent interaction, before continuing.
+ * Only if there is no parent available (root Component) it continues, going back to the interaction cause.
+ *
+ * @param holder The holder that caused the interaction.
+ * @param interactionDetails The details about the interaction.
+ * @return The interaction result.
+ */
+ InteractionResult interact(GuiHolder holder, InteractionDetails interactionDetails);
+
+ /**
+ * Called whenever an interaction occurs.
+ * This propagates from the root Component to the Component that caused the interaction.
+ *
+ * @return The interaction callback
+ */
+ InteractionCallback interactCallback();
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/InteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionDetails.java
new file mode 100644
index 000000000..79218c734
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionDetails.java
@@ -0,0 +1,10 @@
+package com.wolfyscript.utilities.common.gui;
+
+public interface InteractionDetails {
+
+ boolean isCancelled();
+
+ InteractionResult.ResultType getResultType();
+
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ButtonInteractionResult.java b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionResult.java
similarity index 72%
rename from src/main/java/com/wolfyscript/utilities/common/gui/ButtonInteractionResult.java
rename to src/main/java/com/wolfyscript/utilities/common/gui/InteractionResult.java
index b83dd7851..667bb3a20 100644
--- a/src/main/java/com/wolfyscript/utilities/common/gui/ButtonInteractionResult.java
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionResult.java
@@ -1,14 +1,14 @@
package com.wolfyscript.utilities.common.gui;
-public class ButtonInteractionResult {
+public class InteractionResult {
private ResultType type;
- ButtonInteractionResult() {
+ InteractionResult() {
type = ResultType.DEFAULT;
}
- ButtonInteractionResult(ResultType type) {
+ InteractionResult(ResultType type) {
this.type = type;
}
@@ -28,18 +28,18 @@ public void setType(ResultType type) {
this.type = type;
}
- public static ButtonInteractionResult cancel(boolean cancelled) {
- ButtonInteractionResult result = new ButtonInteractionResult();
+ public static InteractionResult cancel(boolean cancelled) {
+ InteractionResult result = new InteractionResult();
result.setCancelled(cancelled);
return result;
}
- public static ButtonInteractionResult def() {
- return new ButtonInteractionResult();
+ public static InteractionResult def() {
+ return new InteractionResult();
}
- public static ButtonInteractionResult type(ResultType type) {
- return new ButtonInteractionResult(type);
+ public static InteractionResult type(ResultType type) {
+ return new InteractionResult(type);
}
public enum ResultType {
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/NativeRendererModule.java b/src/main/java/com/wolfyscript/utilities/common/gui/NativeRendererModule.java
new file mode 100644
index 000000000..5d750623e
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/NativeRendererModule.java
@@ -0,0 +1,29 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.items.ItemStackConfig;
+
+public interface NativeRendererModule {
+
+ void renderStack(T_STACK stack);
+
+ void renderStack(ItemStackConfig stackConfig);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Position.java b/src/main/java/com/wolfyscript/utilities/common/gui/Position.java
new file mode 100644
index 000000000..567fbeb21
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Position.java
@@ -0,0 +1,108 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.wolfyscript.utilities.json.annotations.OptionalValueDeserializer;
+import com.wolfyscript.utilities.json.annotations.OptionalValueSerializer;
+
+import java.io.IOException;
+
+@OptionalValueDeserializer(deserializer = Position.ValueDeserializer.class)
+@OptionalValueSerializer(serializer = Position.ValueSerializer.class)
+public class Position {
+
+ private final Type type;
+ private final int slot;
+
+ @JsonCreator
+ public Position(@JsonProperty("type") Type type, @JsonProperty("slot") int slot) {
+ this.type = type;
+ this.slot = slot;
+ }
+
+ public Type type() {
+ return type;
+ }
+
+ public int slot() {
+ return slot;
+ }
+
+ public static Position relative(int slot) {
+ return new Position(Type.RELATIVE, slot);
+ }
+
+ public static Position absolute(int slot) {
+ return new Position(Type.ABSOLUTE, slot);
+ }
+
+ public enum Type {
+ /**
+ * Relative position with the parent component as the origin
+ */
+ @JsonAlias("relative")
+ RELATIVE,
+ /**
+ * Absolute position with the Window as the origin
+ */
+ @JsonAlias("absolute")
+ ABSOLUTE
+ }
+
+ public static class ValueDeserializer extends com.wolfyscript.utilities.json.ValueDeserializer {
+
+ public ValueDeserializer() {
+ super(Position.class);
+ }
+
+ @Override
+ public Position deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ if (p.currentToken() == JsonToken.VALUE_NUMBER_INT) {
+ return Position.absolute(p.getIntValue());
+ }
+ return Position.absolute(0);
+ }
+ }
+
+ public static class ValueSerializer extends com.wolfyscript.utilities.json.ValueSerializer {
+
+ public ValueSerializer() {
+ super(Position.class);
+ }
+
+ @Override
+ public boolean serialize(Position targetObject, JsonGenerator generator, SerializerProvider provider) throws IOException {
+ if (targetObject.type() == Type.ABSOLUTE) {
+ generator.writeNumber(targetObject.slot());
+ return true;
+ }
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Positionable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Positionable.java
new file mode 100644
index 000000000..da853af5e
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Positionable.java
@@ -0,0 +1,25 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+public interface Positionable {
+
+ Position position();
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ReactiveRenderBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/ReactiveRenderBuilder.java
new file mode 100644
index 000000000..38de82c94
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/ReactiveRenderBuilder.java
@@ -0,0 +1,35 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import java.util.function.Consumer;
+
+public interface ReactiveRenderBuilder {
+
+ > ReactiveResult render(String id, Class builderType, Consumer builderConsumer);
+
+ > ReactiveResult renderAt(Position position, String id, Class builderType, Consumer builderConsumer);
+
+ interface ReactiveResult {
+
+ Component construct();
+
+ }
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/RenderContext.java b/src/main/java/com/wolfyscript/utilities/common/gui/RenderContext.java
new file mode 100644
index 000000000..e87b4e327
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/RenderContext.java
@@ -0,0 +1,54 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.items.ItemStackConfig;
+
+/**
+ * The data that contains all the information needed to render the Menu.
+ *
+ */
+public interface RenderContext {
+
+ Component getCurrentComponent();
+
+ int currentOffset();
+
+ void setStack(int slot, ItemStackConfig> stackConfig);
+
+ void setNativeStack(int slot, Object nativeStack);
+
+ default boolean checkIfSlotInBounds(int slot) {
+ int outerWidth;
+ int outerHeight;
+ if (getCurrentComponent().parent() != null) {
+ Component parent = getCurrentComponent().parent();
+ outerWidth = parent.width();
+ outerHeight = parent.height();
+ } else {
+ outerWidth = 9;
+ outerHeight = 6;
+ }
+ if (slot >= 0 && slot < outerWidth * outerHeight) {
+ return true;
+ }
+ throw new IllegalArgumentException("Slot " + slot + " out of bounds! Must be in the range of [" + 0 + "..." + (outerWidth * outerHeight - 1) + "] !");
+ }
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Renderable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Renderable.java
new file mode 100644
index 000000000..5d0fe5740
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Renderable.java
@@ -0,0 +1,23 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+public interface Renderable {
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Router.java b/src/main/java/com/wolfyscript/utilities/common/gui/Router.java
new file mode 100644
index 000000000..2dec49d3f
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Router.java
@@ -0,0 +1,56 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.WolfyUtils;
+import java.util.Deque;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ *
+ * The Cluster acts as a structure and root Component for Menus.
+ * It can have both other Clusters and Windows as children.
+ *
+ * The entry is used to define the default menu that is opened.
+ *
+ * @param The type of the data implementation.
+ */
+public interface Router extends Interactable {
+
+ String getID();
+
+ WolfyUtils getWolfyUtils();
+
+ Router parent();
+
+ Optional getSubRoute(String routeID);
+
+ Optional getWindow();
+
+ Window open(GuiViewManager viewManager, String... path);
+
+ /**
+ * Opens this component for the specified view and player.
+ *
+ * @param viewManager The view manager to open.
+ * @param uuid The uuid to open the Window for.
+ */
+ RenderContext createContext(GuiViewManager viewManager, Deque path, UUID uuid);
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/RouterBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/RouterBuilder.java
new file mode 100644
index 000000000..d9f310c85
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/RouterBuilder.java
@@ -0,0 +1,35 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.gui.callback.InteractionCallback;
+
+import java.util.function.Consumer;
+
+public interface RouterBuilder {
+
+ RouterBuilder interact(InteractionCallback interactionCallback);
+
+ RouterBuilder route(String path, Consumer subRouteBuilder);
+
+ RouterBuilder window(Consumer windowBuilder);
+
+ Router create(Router parent);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Signalable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Signalable.java
new file mode 100644
index 000000000..cdabb9ae0
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Signalable.java
@@ -0,0 +1,34 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.gui.signal.Signal;
+
+import java.util.Deque;
+import java.util.Map;
+
+public interface Signalable {
+
+ Map> getSignalValues();
+
+ Deque> updatedSignals();
+
+ void receiveUpdate(Signal> signal);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/SignalledObject.java b/src/main/java/com/wolfyscript/utilities/common/gui/SignalledObject.java
new file mode 100644
index 000000000..4fd69f567
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/SignalledObject.java
@@ -0,0 +1,7 @@
+package com.wolfyscript.utilities.common.gui;
+
+public interface SignalledObject {
+
+ void update(GuiViewManager viewManager, GuiHolder guiHolder, RenderContext renderContext);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/State.java b/src/main/java/com/wolfyscript/utilities/common/gui/State.java
new file mode 100644
index 000000000..bcf7d8247
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/State.java
@@ -0,0 +1,22 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+public interface State {
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/StateSelector.java b/src/main/java/com/wolfyscript/utilities/common/gui/StateSelector.java
new file mode 100644
index 000000000..e9a0c68af
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/StateSelector.java
@@ -0,0 +1,25 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+public interface StateSelector {
+
+ int run(GuiHolder holder, Object data, Component component);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Window.java b/src/main/java/com/wolfyscript/utilities/common/gui/Window.java
new file mode 100644
index 000000000..ab619ccc7
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/Window.java
@@ -0,0 +1,146 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.WolfyUtils;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Consumer;
+
+public interface Window extends Interactable, Renderable {
+
+ /**
+ * Creates the context of this window. The context keeps track of the inventory
+ * and view for the rendering.
+ *
+ * @param viewManager The view manager to open.
+ * @param uuid The uuid to open the Window for.
+ */
+ RenderContext createContext(GuiViewManager viewManager, UUID uuid);
+
+ void open(GuiViewManager viewManager);
+
+ Window construct(GuiHolder holder, GuiViewManager viewManager);
+
+ void render(GuiHolder holder, GuiViewManager viewManager, RenderContext context);
+
+ /**
+ * Gets the type that is configured for this Window.
+ * When this is empty, then {@link #getSize()} will return the specified size.
+ *
+ * @return The specified type; or empty Optional when no type is configured.
+ * @see #getSize()
+ */
+ Optional getType();
+
+ /**
+ * Gets the size that is configured for this Window.
+ *
+ * When this is empty, then {@link #getType()} will return the specified type.
+ *
+ * @return The specified size: or empty Optional when no size is configured.
+ */
+ Optional getSize();
+
+ /**
+ * Creates the title of this window for the specified holder.
+ *
+ * @param holder The holder to create the title for.
+ * @return The title component.
+ */
+ net.kyori.adventure.text.Component createTitle(GuiHolder holder);
+
+ /**
+ * The children of this Component; or an empty Set if there are no children.
+ *
+ * @return The child Components of this Component.
+ */
+ Set extends Component> childComponents();
+
+ /**
+ * Gets the child at the relative path from this Component.
+ * When the path is null or empty then it returns this Component instead.
+ *
+ * @param path The path to the child Component.
+ * @return The child at the specified path; or this Component when the path is null or empty.
+ */
+ default Optional extends Component> getChild(String... path) {
+ if (path == null || path.length == 0) return Optional.empty();
+ return getChild(path[0]).flatMap(component -> {
+ if (component instanceof Window window) {
+ return window.getChild(Arrays.copyOfRange(path, 1, path.length));
+ }
+ return Optional.empty();
+ });
+ }
+
+ /**
+ * Gets the direct child Component, or an empty Optional when it wasn't found.
+ *
+ * @param id The id of the child Component.
+ * @return The child Component; or empty Component.
+ */
+ Optional extends Component> getChild(String id);
+
+ /**
+ * Gets the unique id (in context of the parent) of this component.
+ *
+ * @return The id of this component.
+ */
+ String getID();
+
+ /**
+ * Gets the global WolfyUtils instance, this component belongs to.
+ *
+ * @return The WolfyUtils API instance.
+ */
+ WolfyUtils getWolfyUtils();
+
+ /**
+ * The parent of this Component, or null if it is a root Component.
+ *
+ * @return The parent; or null if root Component.
+ */
+ Router router();
+
+ /**
+ * Gets the width of this Component in slot count.
+ *
+ * @return The width in slots.
+ */
+ int width();
+
+ /**
+ * Gets the width of this Component in slot count.
+ *
+ * @return The height in slots.
+ */
+ int height();
+
+ default void executeForAllSlots(int positionSlot, Consumer slotFunction) {
+ for (int i = 0; i < height(); i++) {
+ for (int j = 0; j < width(); j++) {
+ slotFunction.accept(positionSlot + j + i * (9 - width()));
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/WindowBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/WindowBuilder.java
new file mode 100644
index 000000000..e55653ecc
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/WindowBuilder.java
@@ -0,0 +1,148 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.gui.callback.InteractionCallback;
+import com.wolfyscript.utilities.common.gui.functions.SerializableConsumer;
+import com.wolfyscript.utilities.json.annotations.KeyedBaseType;
+import java.util.function.Consumer;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Builder used to create Window Menus.
+ *
+ */
+@KeyedBaseType(baseType = ComponentBuilder.class)
+public interface WindowBuilder {
+
+ /**
+ * The size of the inventory.
+ * This only applies when the type is not specified.
+ * Either the type or size must be specified!
+ *
+ * @param size The size of the inventory.
+ * @return This builder to allow chaining the methods.
+ */
+ WindowBuilder size(int size);
+
+ /**
+ * The type of the inventory.
+ * When the type is specified the size is ignored.
+ * Either the type or size must be specified!
+ *
+ * @param type
+ * @return This builder to allow chaining the methods.
+ */
+ WindowBuilder type(@Nullable WindowType type);
+
+ /**
+ *
+ * The implementation may work different across platforms.
+ * On plain Spigot servers, the titles do not support all components inside inventory titles, like fonts.
+ * Paper fully supports all Components inside inventory titles.
+ *
+ *
+ * @return This builder to allow chaining the methods
+ */
+ WindowBuilder title(String staticTitle);
+
+ WindowBuilder interact(InteractionCallback interactionCallback);
+
+ /**
+ * Specifies the constructor callback, that is called right before the component is created.
+ *
+ * @param render The consumer to configure the renderer
+ * @return This builder for chaining
+ */
+ WindowBuilder construct(Consumer render);
+
+ /**
+ *
+ * Initializes the specified component with the given id at the given slot.
+ * The component won't yet be constructed nor rendered!
+ *
+ * This is useful if the component has some static parts that are non-reactive.
+ * This is used when loading the components from the config files (.conf)
+ * They can then be extended and rendered inside the {@link #construct(Consumer)} callback.
+ *
+ *
+ *
+ * In case you need to have reactive components, create them inside the {@link #construct(Consumer)} callback.
+ *
+ * @param id The id of the component to render
+ * @param builderType The type of the builder to use
+ * @param builderConsumer The consumer to configure the builder
+ * @return This Builder for chaining
+ * @param The type of the component builder
+ */
+ > WindowBuilder init(Position position, String id, Class builderType, SerializableConsumer builderConsumer);
+
+ /**
+ *
+ * Renders the specified static component with the given id.
+ *
+ *
+ * Static components are constructed directly and are not recreated per {@link GuiViewManager}.
+ * Therefor they improve performance, as they are only created once.
+ * Static components cannot use signals!
+ *
+ *
+ * In case you need to have reactive components, create them inside the {@link #construct(Consumer)} callback.
+ *
+ * @param id The id of the component to render
+ * @param builderType The type of the builder to use
+ * @param builderConsumer The consumer to configure the builder
+ * @return This Builder for chaining
+ * @param The type of the component builder
+ */
+ > WindowBuilder render(String id, Class builderType, SerializableConsumer builderConsumer);
+
+ /**
+ *
+ * Initializes the specified component with the given id at the given slot, and renders it statically.
+ * It basically combines
+ * {@link #init(Position, String, Class, SerializableConsumer)} and
+ * {@link #render(String, Class, SerializableConsumer)}
+ *
+ *
+ * This is only really useful if you need to define positions of components in code.
+ * Usually you should use the config files (.conf), to specify slots.
+ *
+ *
+ *
+ * Static components are constructed directly and are not recreated per {@link GuiViewManager}.
+ * Therefor they improve performance, as they are only created once.
+ * Static components cannot use signals!
+ *
+ *
+ * In case you need to have reactive components, create them inside the {@link #construct(Consumer)} callback.
+ *
+ *
+ * @param position
+ * @param id
+ * @param builderType
+ * @param builderConsumer
+ * @return
+ * @param
+ */
+ > WindowBuilder renderAt(Position position, String id, Class builderType, SerializableConsumer builderConsumer);
+
+ Window create(Router parent);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/WindowDynamicConstructor.java b/src/main/java/com/wolfyscript/utilities/common/gui/WindowDynamicConstructor.java
new file mode 100644
index 000000000..ec0f5b79f
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/WindowDynamicConstructor.java
@@ -0,0 +1,122 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+import com.wolfyscript.utilities.common.gui.functions.SerializableConsumer;
+import com.wolfyscript.utilities.common.gui.functions.SerializableFunction;
+import com.wolfyscript.utilities.common.gui.functions.SerializableSupplier;
+import com.wolfyscript.utilities.common.gui.signal.Signal;
+
+import java.util.function.Consumer;
+
+public interface WindowDynamicConstructor extends DynamicConstructor {
+
+ /**
+ * Specify a dynamic custom title supplier that is used to update the title of the Inventory.
+ *
+ * Any signal used inside the supplier will cause it to update when the signal is updated.
+ *
+ *
+ * @param titleSupplier The supplier that provides the new title of the inventory
+ * @return This builder for chaining
+ */
+ WindowDynamicConstructor title(SerializableSupplier titleSupplier);
+
+ /**
+ * When no dynamic title is used (see {@link #title(SerializableSupplier)}), then this method can be used to
+ * create placeholder resolvers for the static title. The static title can be specified using {@link WindowBuilder#title(String)}.
+ *
+ * The title is updated whenever any of the specified signals are updated.
+ *
+ *
+ *
+ * The placeholder will be equal to the key of the signal.
+ * e.g.
+ *
createSignal("count", () -> 0)
will provide a placeholder
<count>
+ *
+ *
+ *
+ * @param signals The signals to use as placeholders
+ * @return This builder for chaining
+ */
+ WindowDynamicConstructor titleSignals(Signal>... signals);
+
+ /**
+ *
+ * Constructs a reactive function to dynamically render components.
+ * This is only recommended for complex methods, like if switches are required.
+ * If a simple condition is enough {@link #renderWhen(SerializableSupplier, String, Class, SerializableConsumer)} should be used instead!
+ *
+ *
+ * The callback is updated whenever a signal used inside it is updated.
+ *
+ *
+ * @param reactiveFunction The function to run on signal updates.
+ * @return This builder for chaining.
+ */
+ WindowDynamicConstructor reactive(SerializableFunction reactiveFunction);
+
+ /**
+ *
+ * Renders the specified component whenever the condition is met.
+ * Any signal used inside the condition will cause it to update when the signal is updated.
+ *
+ *
+ * The specified component is constructed upon invocation of this method and simply rendered/removed whenever the condition changes.
+ * Further updates to the components need to be handled by using signals.
+ *
+ *
+ * @param condition The condition that is reactive to signals used inside it.
+ * @param id The id of the component to render.
+ * @param builderType The type of builder to use.
+ * @param builderConsumer The consumer to configure the builder.
+ * @param The type of the Component Builder
+ * @return This builder for chaining
+ */
+ > WindowDynamicConstructor renderWhen(SerializableSupplier condition, String id, Class builderType, SerializableConsumer builderConsumer);
+
+ , BI extends ComponentBuilder extends Component, Component>> WindowDynamicConstructor renderWhenElse(SerializableSupplier condition, Class builderValidType, Consumer builderValidConsumer, Class builderInvalidType, SerializableConsumer builderInvalidConsumer);
+
+ /**
+ *
+ *
+ * @param slot
+ * @param id
+ * @param builderType
+ * @param builderConsumer
+ * @return
+ * @param
+ */
+ > WindowDynamicConstructor position(Position position, String id, Class builderType, SerializableConsumer builderConsumer);
+
+ /**
+ *
+ * Renders the specified component with the given id.
+ *
+ *
+ * @param id The id of the component to render
+ * @param builderType The type of the builder to use
+ * @param builderConsumer The consumer to configure the builder
+ * @param The type of the component builder
+ * @return This Builder for chaining
+ */
+ > WindowDynamicConstructor render(String id, Class builderType, SerializableConsumer builderConsumer);
+
+ > WindowDynamicConstructor renderAt(Position position, String id, Class builderType, SerializableConsumer builderConsumer);
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/WindowType.java b/src/main/java/com/wolfyscript/utilities/common/gui/WindowType.java
new file mode 100644
index 000000000..83c621c56
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/WindowType.java
@@ -0,0 +1,28 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui;
+
+public enum WindowType {
+
+ CUSTOM,
+ DISPENSER,
+ DROPPER,
+ HOPPER
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/InteractionCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/InteractionCallback.java
new file mode 100644
index 000000000..ccb78e1ce
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/InteractionCallback.java
@@ -0,0 +1,30 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui.callback;
+
+import com.wolfyscript.utilities.common.gui.GuiHolder;
+import com.wolfyscript.utilities.common.gui.InteractionDetails;
+import com.wolfyscript.utilities.common.gui.InteractionResult;
+
+@FunctionalInterface
+public interface InteractionCallback {
+
+ InteractionResult interact(GuiHolder holder, InteractionDetails details);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/RenderCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/RenderCallback.java
new file mode 100644
index 000000000..1b1c3b33a
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/RenderCallback.java
@@ -0,0 +1,28 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui.callback;
+
+import com.wolfyscript.utilities.common.gui.GuiHolder;
+
+@FunctionalInterface
+public interface RenderCallback {
+
+ void render(GuiHolder holder);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputCallback.java
new file mode 100644
index 000000000..1a363069c
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputCallback.java
@@ -0,0 +1,28 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui.callback;
+
+import com.wolfyscript.utilities.common.adapters.Player;
+import com.wolfyscript.utilities.common.gui.GuiViewManager;
+
+public interface TextInputCallback {
+
+ boolean run(Player player, GuiViewManager viewManager, String input, String[] args);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputTabCompleteCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputTabCompleteCallback.java
new file mode 100644
index 000000000..3434290fb
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputTabCompleteCallback.java
@@ -0,0 +1,30 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui.callback;
+
+import com.wolfyscript.utilities.common.adapters.Player;
+import com.wolfyscript.utilities.common.gui.GuiViewManager;
+
+import java.util.List;
+
+public interface TextInputTabCompleteCallback {
+
+ List apply(Player player, GuiViewManager viewManager, String input, String[] args);
+
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/Button.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/Button.java
new file mode 100644
index 000000000..c663eaa1b
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/Button.java
@@ -0,0 +1,43 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui.components;
+
+import com.wolfyscript.utilities.common.gui.Component;
+import com.wolfyscript.utilities.common.gui.Interactable;
+import com.wolfyscript.utilities.common.gui.Positionable;
+
+/**
+ * A simple button that has an icon (ItemStack) and an interaction callback.
+ * It always has a 1x1 size, because it occupies a single slot.
+ *
+ */
+public interface Button extends Component, Interactable, Positionable {
+
+ @Override
+ default int width() {
+ return 1;
+ }
+
+ @Override
+ default int height() {
+ return 1;
+ }
+
+ ButtonIcon icon();
+}
diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonBuilder.java
new file mode 100644
index 000000000..b0ad7772e
--- /dev/null
+++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonBuilder.java
@@ -0,0 +1,68 @@
+/*
+ * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins
+ * Copyright (C) 2021 WolfyScript
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.wolfyscript.utilities.common.gui.components;
+
+import com.wolfyscript.utilities.common.gui.*;
+import com.wolfyscript.utilities.common.gui.callback.InteractionCallback;
+import com.wolfyscript.utilities.common.gui.functions.SerializableSupplier;
+import com.wolfyscript.utilities.common.gui.signal.Signal;
+import com.wolfyscript.utilities.common.items.ItemStackConfig;
+import net.kyori.adventure.sound.Sound;
+
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * Builder to create a {@link Button} instance.
+ *
+ */
+public interface ButtonBuilder extends ComponentBuilder