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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -96,6 +97,7 @@ public class GUIBuilder<G extends GUI> {
public GUIBuilder<G> addItem(@NotNull Item item) { public GUIBuilder<G> addItem(@NotNull Item item) {
if (!guiType.acceptsItems()) if (!guiType.acceptsItems())
throw new UnsupportedOperationException("Items cannot be set in this gui type."); throw new UnsupportedOperationException("Items cannot be set in this gui type.");
if (context.getItems() == null) context.setItems(new ArrayList<>());
context.getItems().add(item); context.getItems().add(item);
return this; return this;
} }
@ -110,10 +112,18 @@ public class GUIBuilder<G extends GUI> {
public GUIBuilder<G> addGUI(@NotNull GUI gui) { public GUIBuilder<G> addGUI(@NotNull GUI gui) {
if (!guiType.acceptsGUIs()) if (!guiType.acceptsGUIs())
throw new UnsupportedOperationException("GUIs cannot be set in this gui type."); throw new UnsupportedOperationException("GUIs cannot be set in this gui type.");
if (context.getGuis() == null) context.setGuis(new ArrayList<>());
context.getGuis().add(gui); context.getGuis().add(gui);
return this; 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() { public G build() {
if (context.getStructure() == null) throw new IllegalStateException("GUIContext has not been set yet."); if (context.getStructure() == null) throw new IllegalStateException("GUIContext has not been set yet.");
return guiType.createGUI(context); 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.builder.guitype.GUIType;
import de.studiocode.invui.gui.structure.Structure; import de.studiocode.invui.gui.structure.Structure;
import de.studiocode.invui.item.Item; import de.studiocode.invui.item.Item;
import de.studiocode.invui.virtualinventory.VirtualInventory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -18,8 +18,9 @@ public class GUIContext {
private final int width; private final int width;
private final int height; private final int height;
private Structure structure; private Structure structure;
private List<GUI> guis = new ArrayList<>(); private List<GUI> guis;
private List<Item> items = new ArrayList<>(); private List<Item> items;
private VirtualInventory inventory;
public GUIContext(int width, int height) { public GUIContext(int width, int height) {
this.width = width; this.width = width;
@ -58,4 +59,12 @@ public class GUIContext {
this.items = items; 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.builder.GUIContext;
import de.studiocode.invui.gui.impl.*; import de.studiocode.invui.gui.impl.*;
import de.studiocode.invui.item.Item; import de.studiocode.invui.item.Item;
import de.studiocode.invui.virtualinventory.VirtualInventory;
public interface GUIType<G extends GUI> { public interface GUIType<G extends GUI> {
@ -11,7 +12,9 @@ public interface GUIType<G extends GUI> {
GUIType<SimplePagedItemsGUI> PAGED_ITEMS = new PagedItemsGUIType(); GUIType<SimplePagedItemsGUI> PAGED_ITEMS = new PagedItemsGUIType();
GUIType<SimplePagedNestedGUI> PAGED_GUIs = new PagedGUIsGUIType(); GUIType<SimplePagedNestedGUI> PAGED_GUIs = new PagedGUIsGUIType();
GUIType<SimpleTabGUI> TAB = new TabGUIType(); 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} * 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(); 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; return false;
} }
@Override
public boolean acceptsInventory() {
return false;
}
} }

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

@ -20,4 +20,9 @@ class PagedItemsGUIType implements GUIType<SimplePagedItemsGUI> {
return true; 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; 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); UpdateReason updateReason = new PlayerUpdateReason(player, event);
Window window = WindowManager.getInstance().findOpenWindow(player).orElse(null); 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()) { if (!updateEvent.isCancelled()) {
int leftOverAmount; int leftOverAmount;

@ -11,12 +11,14 @@ import java.util.List;
/** /**
* A scrollable {@link GUI} * A scrollable {@link GUI}
* *
* @see SimpleScrollGUI * @see SimpleScrollItemsGUI
* @see SimpleScrollNestedGUI
*/ */
public abstract class ScrollGUI extends BaseGUI { public abstract class ScrollGUI extends BaseGUI {
private final boolean infiniteLines; private final boolean infiniteLines;
private final int lineLength; private final int lineLength;
private final int lineAmount;
private final int[] itemListSlots; private final int[] itemListSlots;
protected int offset; protected int offset;
@ -26,6 +28,7 @@ public abstract class ScrollGUI extends BaseGUI {
this.infiniteLines = infiniteLines; this.infiniteLines = infiniteLines;
this.itemListSlots = itemListSlots; this.itemListSlots = itemListSlots;
this.lineLength = SlotUtils.getLongestLineLength(itemListSlots, width); this.lineLength = SlotUtils.getLongestLineLength(itemListSlots, width);
this.lineAmount = (int) Math.ceil((double) itemListSlots.length / (double) lineLength);
if (lineLength == 0) if (lineLength == 0)
throw new IllegalArgumentException("Line length can't be 0"); throw new IllegalArgumentException("Line length can't be 0");
@ -40,6 +43,10 @@ public abstract class ScrollGUI extends BaseGUI {
applyStructure(structure); applyStructure(structure);
} }
public int getLineLength() {
return lineLength;
}
public int getCurrentLine() { public int getCurrentLine() {
return offset / lineLength; return offset / lineLength;
} }
@ -48,21 +55,12 @@ public abstract class ScrollGUI extends BaseGUI {
this.offset = line * lineLength; 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) { public boolean canScroll(int lines) {
if (lines == 0 || (infiniteLines && lines > 0)) return true; if (lines == 0 || (infiniteLines && lines > 0)) return true;
int line = getCurrentLine() + lines; int line = getCurrentLine() + lines;
int maxLineAmount = getMaxLineIndex(); int maxLineIndex = getMaxLineIndex();
return line >= 0 && line <= maxLineAmount; return line >= 0 && (line + lineAmount - 1) <= maxLineIndex;
} }
public void scroll(int lines) { public void scroll(int lines) {
@ -100,7 +98,7 @@ public abstract class ScrollGUI extends BaseGUI {
} }
private void updateContent() { 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++) { for (int i = 0; i < itemListSlots.length; i++) {
if (slotElements.size() > i) setSlotElement(itemListSlots[i], slotElements.get(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) { public SimplePagedItemsGUI(int width, int height, @Nullable List<Item> items, int... itemListSlots) {
super(width, height, false, itemListSlots); super(width, height, false, itemListSlots);
this.items = items == null ? new ArrayList<>() : items; setItems(items);
update();
} }
public SimplePagedItemsGUI(int width, int height, @Nullable List<Item> items, @NotNull Structure structure) { public SimplePagedItemsGUI(int width, int height, @Nullable List<Item> items, @NotNull Structure structure) {
super(width, height, false, structure); super(width, height, false, structure);
this.items = items == null ? new ArrayList<>() : items; setItems(items);
update();
} }
@Override @Override
@ -50,8 +46,8 @@ public class SimplePagedItemsGUI extends PagedGUI {
return items.subList(from, to).stream().map(ItemSlotElement::new).collect(Collectors.toList()); return items.subList(from, to).stream().map(ItemSlotElement::new).collect(Collectors.toList());
} }
public void setItems(List<Item> items) { public void setItems(@Nullable List<Item> items) {
this.items = items; this.items = items != null ? items : new ArrayList<>();
update(); update();
} }

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