Added NestedScrollGUI and VIScrollGUI

This commit is contained in:
NichtStudioCode 2022-01-07 20:29:17 +01:00
parent 0a823c33c7
commit eae337ceb9
17 changed files with 270 additions and 67 deletions

@ -12,6 +12,7 @@ import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
@ -96,6 +97,7 @@ public class GUIBuilder<G extends GUI> {
public GUIBuilder<G> addItem(@NotNull Item item) {
if (!guiType.acceptsItems())
throw new UnsupportedOperationException("Items cannot be set in this gui type.");
if (context.getItems() == null) context.setItems(new ArrayList<>());
context.getItems().add(item);
return this;
}
@ -110,10 +112,18 @@ public class GUIBuilder<G extends GUI> {
public GUIBuilder<G> addGUI(@NotNull GUI gui) {
if (!guiType.acceptsGUIs())
throw new UnsupportedOperationException("GUIs cannot be set in this gui type.");
if (context.getGuis() == null) context.setGuis(new ArrayList<>());
context.getGuis().add(gui);
return this;
}
public GUIBuilder<G> setInventory(@NotNull VirtualInventory inventory) {
if (!guiType.acceptsInventory())
throw new UnsupportedOperationException("An inventory cannot be set in this gui type.");
context.setInventory(inventory);
return this;
}
public G build() {
if (context.getStructure() == null) throw new IllegalStateException("GUIContext has not been set yet.");
return guiType.createGUI(context);

@ -4,9 +4,9 @@ import de.studiocode.invui.gui.GUI;
import de.studiocode.invui.gui.builder.guitype.GUIType;
import de.studiocode.invui.gui.structure.Structure;
import de.studiocode.invui.item.Item;
import de.studiocode.invui.virtualinventory.VirtualInventory;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
@ -18,8 +18,9 @@ public class GUIContext {
private final int width;
private final int height;
private Structure structure;
private List<GUI> guis = new ArrayList<>();
private List<Item> items = new ArrayList<>();
private List<GUI> guis;
private List<Item> items;
private VirtualInventory inventory;
public GUIContext(int width, int height) {
this.width = width;
@ -58,4 +59,12 @@ public class GUIContext {
this.items = items;
}
public VirtualInventory getInventory() {
return inventory;
}
public void setInventory(@NotNull VirtualInventory inventory) {
this.inventory = inventory;
}
}

@ -4,6 +4,7 @@ import de.studiocode.invui.gui.GUI;
import de.studiocode.invui.gui.builder.GUIContext;
import de.studiocode.invui.gui.impl.*;
import de.studiocode.invui.item.Item;
import de.studiocode.invui.virtualinventory.VirtualInventory;
public interface GUIType<G extends GUI> {
@ -11,7 +12,9 @@ public interface GUIType<G extends GUI> {
GUIType<SimplePagedItemsGUI> PAGED_ITEMS = new PagedItemsGUIType();
GUIType<SimplePagedNestedGUI> PAGED_GUIs = new PagedGUIsGUIType();
GUIType<SimpleTabGUI> TAB = new TabGUIType();
GUIType<SimpleScrollGUI> SCROLL = new ScrollGUIType();
GUIType<SimpleScrollItemsGUI> SCROLL_ITEMS = new ScrollItemsGUIType();
GUIType<SimpleScrollNestedGUI> SCROLL_GUIS = new ScrollGUIsGUIType();
GUIType<SimpleScrollVIGUI> SCROLL_INVENTORY = new ScrollVIGUIType();
/**
* Creates a {@link GUI} of type {@link G} with the given {@link GUIContext}
@ -31,4 +34,9 @@ public interface GUIType<G extends GUI> {
*/
boolean acceptsItems();
/**
* @return If this {@link GUIType} accepts a {@link VirtualInventory} from the {@link GUIContext}
*/
boolean acceptsInventory();
}

@ -20,4 +20,9 @@ class NormalGUIType implements GUIType<SimpleGUI> {
return false;
}
@Override
public boolean acceptsInventory() {
return false;
}
}

@ -20,4 +20,9 @@ class PagedGUIsGUIType implements GUIType<SimplePagedNestedGUI> {
return false;
}
@Override
public boolean acceptsInventory() {
return false;
}
}

@ -20,4 +20,9 @@ class PagedItemsGUIType implements GUIType<SimplePagedItemsGUI> {
return true;
}
@Override
public boolean acceptsInventory() {
return false;
}
}

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

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

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

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

@ -20,4 +20,9 @@ class TabGUIType implements GUIType<SimpleTabGUI> {
return false;
}
@Override
public boolean acceptsInventory() {
return false;
}
}

@ -209,7 +209,7 @@ public abstract class BaseGUI implements GUI, Controllable {
UpdateReason updateReason = new PlayerUpdateReason(player, event);
Window window = WindowManager.getInstance().findOpenWindow(player).orElse(null);
ItemUpdateEvent updateEvent = inventory.callUpdateEvent(updateReason, slot, clicked, null);
ItemUpdateEvent updateEvent = inventory.callPreUpdateEvent(updateReason, slot, clicked, null);
if (!updateEvent.isCancelled()) {
int leftOverAmount;

@ -11,12 +11,14 @@ import java.util.List;
/**
* A scrollable {@link GUI}
*
* @see SimpleScrollGUI
* @see SimpleScrollItemsGUI
* @see SimpleScrollNestedGUI
*/
public abstract class ScrollGUI extends BaseGUI {
private final boolean infiniteLines;
private final int lineLength;
private final int lineAmount;
private final int[] itemListSlots;
protected int offset;
@ -26,6 +28,7 @@ public abstract class ScrollGUI extends BaseGUI {
this.infiniteLines = infiniteLines;
this.itemListSlots = itemListSlots;
this.lineLength = SlotUtils.getLongestLineLength(itemListSlots, width);
this.lineAmount = (int) Math.ceil((double) itemListSlots.length / (double) lineLength);
if (lineLength == 0)
throw new IllegalArgumentException("Line length can't be 0");
@ -40,6 +43,10 @@ public abstract class ScrollGUI extends BaseGUI {
applyStructure(structure);
}
public int getLineLength() {
return lineLength;
}
public int getCurrentLine() {
return offset / lineLength;
}
@ -48,21 +55,12 @@ public abstract class ScrollGUI extends BaseGUI {
this.offset = line * lineLength;
}
private int getMaxLineIndex() {
int maxLineIndex = (int) Math.ceil((double) getElementAmount() / (double) lineLength);
return Math.max(0, maxLineIndex - getLineAmount());
}
private int getLineAmount() {
return itemListSlots.length / lineLength;
}
public boolean canScroll(int lines) {
if (lines == 0 || (infiniteLines && lines > 0)) return true;
int line = getCurrentLine() + lines;
int maxLineAmount = getMaxLineIndex();
return line >= 0 && line <= maxLineAmount;
int maxLineIndex = getMaxLineIndex();
return line >= 0 && (line + lineAmount - 1) <= maxLineIndex;
}
public void scroll(int lines) {
@ -100,7 +98,7 @@ public abstract class ScrollGUI extends BaseGUI {
}
private void updateContent() {
List<SlotElement> slotElements = getElements(offset, itemListSlots.length + offset);
List<? extends SlotElement> slotElements = getElements(offset, itemListSlots.length + offset);
for (int i = 0; i < itemListSlots.length; i++) {
if (slotElements.size() > i) setSlotElement(itemListSlots[i], slotElements.get(i));
@ -108,8 +106,8 @@ public abstract class ScrollGUI extends BaseGUI {
}
}
abstract protected int getElementAmount();
abstract protected int getMaxLineIndex();
abstract protected List<SlotElement> getElements(int from, int to);
abstract protected List<? extends SlotElement> getElements(int from, int to);
}

@ -24,16 +24,12 @@ public class SimplePagedItemsGUI extends PagedGUI {
public SimplePagedItemsGUI(int width, int height, @Nullable List<Item> items, int... itemListSlots) {
super(width, height, false, itemListSlots);
this.items = items == null ? new ArrayList<>() : items;
update();
setItems(items);
}
public SimplePagedItemsGUI(int width, int height, @Nullable List<Item> items, @NotNull Structure structure) {
super(width, height, false, structure);
this.items = items == null ? new ArrayList<>() : items;
update();
setItems(items);
}
@Override
@ -50,8 +46,8 @@ public class SimplePagedItemsGUI extends PagedGUI {
return items.subList(from, to).stream().map(ItemSlotElement::new).collect(Collectors.toList());
}
public void setItems(List<Item> items) {
this.items = items;
public void setItems(@Nullable List<Item> items) {
this.items = items != null ? items : new ArrayList<>();
update();
}

@ -10,34 +10,25 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class SimpleScrollGUI extends ScrollGUI {
public class SimpleScrollItemsGUI extends ScrollGUI {
private List<Item> items;
public SimpleScrollGUI(int width, int height, @Nullable List<Item> items, int... itemListSlots) {
public SimpleScrollItemsGUI(int width, int height, @Nullable List<Item> items, int... itemListSlots) {
super(width, height, false, itemListSlots);
this.items = items == null ? new ArrayList<>() : items;
update();
setItems(items);
}
public SimpleScrollGUI(int width, int height, @Nullable List<Item> items, @NotNull Structure structure) {
public SimpleScrollItemsGUI(int width, int height, @Nullable List<Item> items, @NotNull Structure structure) {
super(width, height, false, structure);
this.items = items == null ? new ArrayList<>() : items;
update();
setItems(items);
}
public void setItems(List<Item> items) {
this.items = items;
public void setItems(@Nullable List<Item> items) {
this.items = items != null ? items : new ArrayList<>();
update();
}
@Override
protected int getElementAmount() {
return items.size();
}
@Override
protected List<SlotElement> getElements(int from, int to) {
return items.subList(from, Math.min(items.size(), to)).stream()
@ -45,4 +36,9 @@ public class SimpleScrollGUI extends ScrollGUI {
.collect(Collectors.toList());
}
@Override
protected int getMaxLineIndex() {
return (int) Math.ceil((double) items.size() / (double) getLineLength()) - 1;
}
}

@ -0,0 +1,52 @@
package de.studiocode.invui.gui.impl;
import de.studiocode.invui.gui.GUI;
import de.studiocode.invui.gui.SlotElement;
import de.studiocode.invui.gui.structure.Structure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class SimpleScrollNestedGUI extends ScrollGUI {
private List<GUI> guis;
private List<SlotElement.LinkedSlotElement> elements;
public SimpleScrollNestedGUI(int width, int height, @Nullable List<GUI> guis, int... itemListSlots) {
super(width, height, false, itemListSlots);
setGuis(guis);
}
public SimpleScrollNestedGUI(int width, int height, @Nullable List<GUI> guis, @NotNull Structure structure) {
super(width, height, false, structure);
setGuis(guis);
}
public void setGuis(@Nullable List<GUI> guis) {
this.guis = guis != null ? guis : new ArrayList<>();
updateElements();
update();
}
private void updateElements() {
elements = new ArrayList<>();
for (GUI gui : guis) {
for (int i = 0; i < gui.getSize(); i++) {
elements.add(new SlotElement.LinkedSlotElement(gui, i));
}
}
}
@Override
protected List<SlotElement.LinkedSlotElement> getElements(int from, int to) {
return elements.subList(from, Math.min(elements.size(), to));
}
@Override
protected int getMaxLineIndex() {
return guis.size() - 1;
}
}

@ -0,0 +1,53 @@
package de.studiocode.invui.gui.impl;
import de.studiocode.invui.gui.SlotElement;
import de.studiocode.invui.gui.structure.Structure;
import de.studiocode.invui.virtualinventory.VirtualInventory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class SimpleScrollVIGUI extends ScrollGUI {
private VirtualInventory inventory;
public SimpleScrollVIGUI(int width, int height, @Nullable VirtualInventory inventory, int... itemListSlots) {
super(width, height, false, itemListSlots);
this.inventory = inventory;
update();
}
public SimpleScrollVIGUI(int width, int height, @Nullable VirtualInventory inventory, @NotNull Structure structure) {
super(width, height, false, structure);
this.inventory = inventory;
update();
}
public void setInventory(VirtualInventory inventory) {
this.inventory = inventory;
update();
}
@Override
protected List<SlotElement.VISlotElement> getElements(int from, int to) {
ArrayList<SlotElement.VISlotElement> elements = new ArrayList<>();
if (inventory != null) {
for (int i = from; i < to && i < inventory.getSize(); i++) {
elements.add(new SlotElement.VISlotElement(inventory, i));
}
}
return elements;
}
@Override
protected int getMaxLineIndex() {
if (inventory == null) return 0;
return (int) Math.ceil((double) inventory.getSize() / (double) getLineLength()) - 1;
}
}