Added CustomSlot, improved various GUI elements, added GUI components.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
package com.willfp.eco.core.gui.component;
|
||||
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A GUI Component is a 2-dimensional set of slots that can be
|
||||
* placed in a menu.
|
||||
*/
|
||||
public interface GUIComponent {
|
||||
/**
|
||||
* Get the amount of rows in the component.
|
||||
*
|
||||
* @return The rows.
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Get the amount of columns in the component.
|
||||
*
|
||||
* @return The columns.
|
||||
*/
|
||||
int getColumns();
|
||||
|
||||
/**
|
||||
* Get the slot at a certain position in the component.
|
||||
*
|
||||
* @param row The row (1-indexed).
|
||||
* @param column The column (1-indexed).
|
||||
* @return The slot, or null if no slot at the location.
|
||||
*/
|
||||
@Nullable
|
||||
Slot getSlotAt(final int row,
|
||||
final int column);
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import com.willfp.eco.core.gui.component.GUIComponent;
|
||||
import com.willfp.eco.core.gui.slot.FillerMask;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -13,6 +15,13 @@ import java.util.function.Consumer;
|
||||
* Builder to create menus.
|
||||
*/
|
||||
public interface MenuBuilder {
|
||||
/**
|
||||
* Get the amount of rows.
|
||||
*
|
||||
* @return The amount of rows.
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Set the menu title.
|
||||
*
|
||||
@@ -33,6 +42,32 @@ public interface MenuBuilder {
|
||||
int column,
|
||||
@NotNull Slot slot);
|
||||
|
||||
/**
|
||||
* Add a component.
|
||||
*
|
||||
* @param row The row of the top left corner.
|
||||
* @param column The column of the top left corner.
|
||||
* @param component The component.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder addComponent(final int row,
|
||||
final int column,
|
||||
@NotNull GUIComponent component) {
|
||||
Validate.isTrue(column + component.getColumns() - 1 <= 9, "Component is too large to be placed here!");
|
||||
Validate.isTrue(row + component.getRows() - 1 <= this.getRows(), "Component is too large to be placed here!");
|
||||
|
||||
for (int currentRow = row; currentRow < row + component.getRows(); currentRow++) {
|
||||
for (int currentCol = column; currentCol < column + component.getColumns(); currentCol++) {
|
||||
Slot slot = component.getSlotAt(currentRow, currentCol);
|
||||
if (slot != null) {
|
||||
setSlot(currentRow, currentCol, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run function to modify the builder.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A slot loaded in from config.
|
||||
*/
|
||||
public class ConfigSlot extends CustomSlot {
|
||||
/**
|
||||
* The config of the slot.
|
||||
*/
|
||||
private final Config config;
|
||||
|
||||
/**
|
||||
* Cached handlers, for performance.
|
||||
*/
|
||||
private final Map<String, List<CommandToDispatch>> handlers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Create a new config slot.
|
||||
*
|
||||
* @param config The config.
|
||||
*/
|
||||
public ConfigSlot(@NotNull final Config config) {
|
||||
this.config = config;
|
||||
|
||||
init(
|
||||
Slot.builder(Items.lookup(config.getString("item")))
|
||||
.onLeftClick(dispatchCommandHandler("left-click"))
|
||||
.onRightClick(dispatchCommandHandler("right-click"))
|
||||
.onShiftLeftClick(dispatchCommandHandler("shift-left-click"))
|
||||
.onShiftRightClick(dispatchCommandHandler("shift-right-click"))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a slot handler for dispatching commands.
|
||||
*
|
||||
* @param configKey The config key.
|
||||
* @return The handler.
|
||||
*/
|
||||
private SlotHandler dispatchCommandHandler(@NotNull final String configKey) {
|
||||
if (!handlers.containsKey(configKey)) {
|
||||
List<CommandToDispatch> commands = new ArrayList<>();
|
||||
|
||||
for (String command : config.getStrings(configKey)) {
|
||||
if (command.startsWith("console:")) {
|
||||
commands.add(new CommandToDispatch(
|
||||
StringUtils.removePrefix("console:", command),
|
||||
true
|
||||
));
|
||||
} else {
|
||||
commands.add(new CommandToDispatch(
|
||||
command,
|
||||
false
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
handlers.put(configKey, commands);
|
||||
}
|
||||
|
||||
List<CommandToDispatch> toDispatch = handlers.get(configKey);
|
||||
|
||||
return (event, slot, menu) -> {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
|
||||
for (CommandToDispatch dispatch : toDispatch) {
|
||||
dispatch.dispatch(player);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Signifies a command to dispatch.
|
||||
*
|
||||
* @param command The command.
|
||||
* @param console If the command should be run as console.
|
||||
*/
|
||||
private record CommandToDispatch(
|
||||
@NotNull String command,
|
||||
boolean console
|
||||
) {
|
||||
/**
|
||||
* Dispatch command.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void dispatch(@NotNull final Player player) {
|
||||
if (console()) {
|
||||
Bukkit.dispatchCommand(
|
||||
Bukkit.getConsoleSender(),
|
||||
command()
|
||||
);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(
|
||||
player,
|
||||
command()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Base class for custom slot implementations.
|
||||
*/
|
||||
public abstract class CustomSlot implements Slot {
|
||||
/**
|
||||
* The internal slot to delegate to.
|
||||
*/
|
||||
private Slot delegate = null;
|
||||
|
||||
/**
|
||||
* Create a new custom slot.
|
||||
*/
|
||||
protected CustomSlot() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the slot with the delegate.
|
||||
*
|
||||
* @param slot The slot to delegate to.
|
||||
*/
|
||||
protected void init(@NotNull final Slot slot) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
this.delegate = slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the delegate slot.
|
||||
* <p>
|
||||
* This is not required to add the slot to a menu, but is instead used internally.
|
||||
*
|
||||
* @return The slot.
|
||||
*/
|
||||
public Slot getDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(@NotNull final Player player) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.getItemStack(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaptive() {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.isCaptive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotCaptiveFor(@NotNull final Player player) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.isNotCaptiveFor(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaptiveFromEmpty() {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.isCaptiveFromEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getRows() {
|
||||
return Slot.super.getRows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getColumns() {
|
||||
return Slot.super.getColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Slot getSlotAt(int row, int column) {
|
||||
return Slot.super.getSlotAt(row, column);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.component.GUIComponent;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -11,8 +13,11 @@ import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A slot is an item in a GUI that can handle clicks.
|
||||
* <p>
|
||||
* Don't create custom Slot implementations directly from this class,
|
||||
* rather extend {@link CustomSlot}.
|
||||
*/
|
||||
public interface Slot {
|
||||
public interface Slot extends GUIComponent {
|
||||
/**
|
||||
* Get the ItemStack that would be shown to a player.
|
||||
*
|
||||
@@ -48,6 +53,22 @@ public interface Slot {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getRows() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getColumns() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
default Slot getSlotAt(final int row,
|
||||
final int column) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder for an ItemStack.
|
||||
*
|
||||
@@ -67,6 +88,16 @@ public interface Slot {
|
||||
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder for a TestableItem.
|
||||
*
|
||||
* @param item The item.
|
||||
* @return The builder.
|
||||
*/
|
||||
static SlotBuilder builder(@NotNull final TestableItem item) {
|
||||
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> item.getItem());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder for a player-specific ItemStack.
|
||||
*
|
||||
|
||||
@@ -85,6 +85,16 @@ fun slot(
|
||||
item: ItemStack
|
||||
): Slot = Slot.builder(item).build()
|
||||
|
||||
/** Kotlin builder for slots. */
|
||||
fun slot(
|
||||
item: TestableItem,
|
||||
init: SlotBuilder.() -> Unit
|
||||
): Slot {
|
||||
val builder = Slot.builder(item)
|
||||
init(builder)
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
/** Kotlin builder for slots. */
|
||||
fun slot(
|
||||
item: TestableItem
|
||||
|
||||
Reference in New Issue
Block a user