Added menu pagination
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.core.gui;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
||||
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||
@@ -21,6 +22,7 @@ public interface GUIFactory {
|
||||
* @param provider The provider.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
|
||||
|
||||
/**
|
||||
@@ -29,5 +31,17 @@ public interface GUIFactory {
|
||||
* @param rows The amount of rows.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
MenuBuilder createMenuBuilder(int rows);
|
||||
|
||||
/**
|
||||
* Combine the state of two menus together.
|
||||
*
|
||||
* @param base The base menu.
|
||||
* @param additional The additional state.
|
||||
* @return The menu.
|
||||
*/
|
||||
@NotNull
|
||||
Menu blendMenuState(@NotNull Menu base,
|
||||
@NotNull Menu additional);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package com.willfp.eco.core.gui.component;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.slot.FillerSlot;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -38,9 +35,9 @@ public interface GUIComponent {
|
||||
* @return The slot, or null if no slot at the location.
|
||||
*/
|
||||
@Nullable
|
||||
default Slot getSlotAt(int row,
|
||||
int column) {
|
||||
return new FillerSlot(new ItemStack(Material.AIR));
|
||||
default Slot getSlotAt(final int row,
|
||||
final int column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,10 +55,10 @@ public interface GUIComponent {
|
||||
* @return The slot, or null if no slot at the location.
|
||||
*/
|
||||
@Nullable
|
||||
default Slot getSlotAt(int row,
|
||||
int column,
|
||||
@NotNull Player player,
|
||||
@NotNull Menu menu) {
|
||||
default Slot getSlotAt(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return getSlotAt(row, column);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import com.willfp.eco.core.gui.component.GUIComponent;
|
||||
import com.willfp.eco.core.gui.page.Page;
|
||||
import com.willfp.eco.core.gui.slot.FillerMask;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -9,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Builder to create menus.
|
||||
@@ -70,17 +72,47 @@ public interface MenuBuilder {
|
||||
* @param mask The mask.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder setMask(@NotNull FillerMask mask) {
|
||||
default MenuBuilder setMask(@NotNull final FillerMask mask) {
|
||||
return this.addComponent(0, 0, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a page.
|
||||
*
|
||||
* @param page The page.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder addPage(@NotNull final Page page) {
|
||||
return this.addComponent(0, 0, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max pages.
|
||||
*
|
||||
* @param pages The max pages.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder maxPages(final int pages) {
|
||||
return this.maxPages(player -> pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max pages dynamically for a player.
|
||||
*
|
||||
* @param pages The max pages.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder maxPages(@NotNull final Function<Player, Integer> pages) {
|
||||
return onOpen((player, menu) -> menu.addState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu close handler.
|
||||
*
|
||||
* @param action The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder onClose(@NotNull Consumer<InventoryCloseEvent> action) {
|
||||
default MenuBuilder onClose(@NotNull final Consumer<InventoryCloseEvent> action) {
|
||||
return this.onClose((event, menu) -> action.accept(event));
|
||||
}
|
||||
|
||||
|
||||
115
eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java
Normal file
115
eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package com.willfp.eco.core.gui.page;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.component.GUIComponent;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A page is a component representing another menu.
|
||||
* This allows full component support in pagination.
|
||||
*/
|
||||
public final class Page implements GUIComponent {
|
||||
/**
|
||||
* The Menu state key for the current page.
|
||||
*/
|
||||
public static final String PAGE_KEY = "page";
|
||||
|
||||
/**
|
||||
* The Menu state key for the amount of pages.
|
||||
*/
|
||||
public static final String MAX_PAGE_KEY = "max_page";
|
||||
|
||||
/**
|
||||
* The page number.
|
||||
*/
|
||||
private final int pageNumber;
|
||||
|
||||
/**
|
||||
* The base menu.
|
||||
*/
|
||||
private final Menu page;
|
||||
|
||||
/**
|
||||
* The delegate menu.
|
||||
*/
|
||||
private Menu delegate = null;
|
||||
|
||||
/**
|
||||
* Create a new page.
|
||||
*
|
||||
* @param pageNumber The page number.
|
||||
* @param page The base menu.
|
||||
*/
|
||||
public Page(final int pageNumber,
|
||||
@NotNull final Menu page) {
|
||||
this.pageNumber = pageNumber;
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current page number.
|
||||
*
|
||||
* @return The page number.
|
||||
*/
|
||||
public int getPageNumber() {
|
||||
return this.pageNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Slot getSlotAt(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
if (getPage(player, menu) != pageNumber) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (delegate == null) {
|
||||
delegate = Eco.getHandler().getGUIFactory().blendMenuState(page, menu);
|
||||
}
|
||||
|
||||
return page.getSlot(row, column, player, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRows() {
|
||||
return page.getRows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumns() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the page.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @return The page.
|
||||
*/
|
||||
public static int getPage(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
Integer pageState = menu.getState(player, Page.PAGE_KEY);
|
||||
return Objects.requireNonNullElse(pageState, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the page.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @return The page.
|
||||
*/
|
||||
public static int getMaxPage(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
Integer pageState = menu.getState(player, Page.MAX_PAGE_KEY);
|
||||
return Objects.requireNonNullElse(pageState, Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.willfp.eco.core.gui.page;
|
||||
|
||||
import com.willfp.eco.core.gui.component.GUIComponent;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A slot loaded in from config.
|
||||
*/
|
||||
public final class PageChanger implements GUIComponent {
|
||||
/**
|
||||
* The slot to be shown.
|
||||
*/
|
||||
private final Slot slot;
|
||||
|
||||
/**
|
||||
* The direction to turn the page.
|
||||
*/
|
||||
private final Direction direction;
|
||||
|
||||
/**
|
||||
* Create a new page change slot.
|
||||
*
|
||||
* @param direction The direction.
|
||||
*/
|
||||
public PageChanger(@NotNull final ItemStack itemStack,
|
||||
@NotNull final Direction direction) {
|
||||
this.direction = direction;
|
||||
|
||||
slot = Slot.builder(itemStack)
|
||||
.onLeftClick((event, slot, menu) -> {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
int page = Page.getPage(player, menu);
|
||||
int newPage = Math.max(
|
||||
0,
|
||||
Math.min(
|
||||
page + direction.getChange(),
|
||||
Page.getMaxPage(player, menu)
|
||||
)
|
||||
);
|
||||
menu.addState(player, Page.PAGE_KEY, newPage);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRows() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumns() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Slot getSlotAt(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
int page = Page.getPage(player, menu);
|
||||
int maxPage = Page.getMaxPage(player, menu);
|
||||
|
||||
if (page <= 1 && this.direction == Direction.BACKWARDS) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (page >= maxPage - 1 && this.direction == Direction.FORWARDS) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* The direction to change the page.
|
||||
*/
|
||||
public enum Direction {
|
||||
/**
|
||||
* Increment the page by 1.
|
||||
*/
|
||||
FORWARDS(1),
|
||||
|
||||
/**
|
||||
* Decrement the page by 1.
|
||||
*/
|
||||
BACKWARDS(-1);
|
||||
|
||||
/**
|
||||
* The amount of pages to change by.
|
||||
*/
|
||||
private final int change;
|
||||
|
||||
/**
|
||||
* Create a new direction.
|
||||
*
|
||||
* @param change The amount of pages to change by.
|
||||
*/
|
||||
Direction(final int change) {
|
||||
this.change = change;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of pages to change by.
|
||||
*
|
||||
* @return The change.
|
||||
*/
|
||||
public int getChange() {
|
||||
return change;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package com.willfp.eco.core.gui
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder
|
||||
import com.willfp.eco.core.gui.page.Page
|
||||
import com.willfp.eco.core.gui.slot.Slot
|
||||
import com.willfp.eco.core.gui.slot.SlotBuilder
|
||||
import com.willfp.eco.core.items.TestableItem
|
||||
@@ -131,6 +132,10 @@ fun MenuBuilder.modify(modifier: (MenuBuilder) -> Unit): MenuBuilder =
|
||||
fun MenuBuilder.onRender(action: (Player, Menu) -> Unit): MenuBuilder =
|
||||
this.onRender { a, b -> action(a, b) }
|
||||
|
||||
/** @see MenuBuilder.addPage */
|
||||
fun MenuBuilder.addPage(page: Int, creation: MenuBuilder.() -> MenuBuilder): MenuBuilder =
|
||||
this.addPage(Page(page, Menu.builder(this.rows).creation().build()))
|
||||
|
||||
/** Kotlin builder for menus. */
|
||||
fun menu(
|
||||
rows: Int,
|
||||
|
||||
Reference in New Issue
Block a user