mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-27 05:05:18 +01:00
Merge branch 'develop' of https://github.com/BentoBoxWorld/BentoBox.git into develop
This commit is contained in:
commit
6bff4c8132
@ -0,0 +1,527 @@
|
|||||||
|
//
|
||||||
|
// Created by BONNe
|
||||||
|
// Copyright - 2021
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
package world.bentobox.bentobox.api.panels;
|
||||||
|
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.TemplatedPanelBuilder;
|
||||||
|
import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord;
|
||||||
|
import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class creates a new Panel from the template record.
|
||||||
|
* @author BONNe
|
||||||
|
* @since 1.17.3
|
||||||
|
*/
|
||||||
|
public class TemplatedPanel extends Panel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* TemplatedPanel constructor class which generates functional panel.
|
||||||
|
* @param builder Builder that contains all information about the panel that must be generated.
|
||||||
|
*/
|
||||||
|
public TemplatedPanel(@NonNull TemplatedPanelBuilder builder)
|
||||||
|
{
|
||||||
|
this.user = builder.getUser();
|
||||||
|
this.setWorld(builder.getWorld());
|
||||||
|
this.setListener(builder.getListener());
|
||||||
|
|
||||||
|
this.panelTemplate = builder.getPanelTemplate();
|
||||||
|
// Init type creators
|
||||||
|
this.typeCreators = new HashMap<>(builder.getObjectCreatorMap());
|
||||||
|
this.typeIndex = new HashMap<>(builder.getObjectCreatorMap().size());
|
||||||
|
this.typeSlotMap = new HashMap<>(builder.getObjectCreatorMap().size());
|
||||||
|
|
||||||
|
if (this.panelTemplate == null)
|
||||||
|
{
|
||||||
|
BentoBox.getInstance().logError("Cannot generate panel because template is not loaded.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.generatePanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates the panel from the template.
|
||||||
|
*/
|
||||||
|
private void generatePanel()
|
||||||
|
{
|
||||||
|
Map<Integer, PanelItem> items = switch (this.panelTemplate.type())
|
||||||
|
{
|
||||||
|
case INVENTORY -> this.populateInventoryPanel();
|
||||||
|
case HOPPER -> this.populateHopperPanel();
|
||||||
|
case DROPPER -> this.populateDropperPanel();
|
||||||
|
};
|
||||||
|
|
||||||
|
super.makePanel(this.user.getTranslation(this.panelTemplate.title()),
|
||||||
|
items,
|
||||||
|
items.keySet().stream().max(Comparator.naturalOrder()).orElse(9),
|
||||||
|
this.user,
|
||||||
|
this.getListener().orElse(null),
|
||||||
|
this.panelTemplate.type());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates map with item indexes and their icons that will be added into
|
||||||
|
* Inventory Panel.
|
||||||
|
* @return Map that contains indexes linked to the correct panel item.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private Map<Integer, PanelItem> populateInventoryPanel()
|
||||||
|
{
|
||||||
|
// Init item array with the max available size.
|
||||||
|
PanelItem[][] itemArray = new PanelItem[6][9];
|
||||||
|
|
||||||
|
// Analyze the GUI button layout a bit.
|
||||||
|
for (int i = 0; i < this.panelTemplate.content().length; i++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < this.panelTemplate.content()[i].length; k++)
|
||||||
|
{
|
||||||
|
ItemTemplateRecord record = this.panelTemplate.content()[i][k];
|
||||||
|
|
||||||
|
if (record != null && record.dataMap().containsKey("type"))
|
||||||
|
{
|
||||||
|
String type = String.valueOf(record.dataMap().get("type"));
|
||||||
|
|
||||||
|
int counter = this.typeSlotMap.computeIfAbsent(type, key -> 1);
|
||||||
|
this.typeSlotMap.put(type, counter + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make buttons for the GUI
|
||||||
|
for (int i = 0; i < this.panelTemplate.content().length; i++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < this.panelTemplate.content()[i].length; k++)
|
||||||
|
{
|
||||||
|
itemArray[i][k] = this.makeButton(this.panelTemplate.content()[i][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After items are created, remove empty lines.
|
||||||
|
boolean[] showLine = this.panelTemplate.forcedRows();
|
||||||
|
|
||||||
|
for (int i = 0; i < this.panelTemplate.content().length; i++)
|
||||||
|
{
|
||||||
|
boolean emptyLine = true;
|
||||||
|
|
||||||
|
for (int k = 0; emptyLine && k < this.panelTemplate.content()[i].length; k++)
|
||||||
|
{
|
||||||
|
emptyLine = itemArray[i][k] == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not generate fallback for "empty" lines.
|
||||||
|
showLine[i] = showLine[i] || !emptyLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now fill the border.
|
||||||
|
if (this.panelTemplate.border() != null)
|
||||||
|
{
|
||||||
|
PanelItem template = this.makeTemplate(this.panelTemplate.border());
|
||||||
|
|
||||||
|
// Hard codded 6
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (i == 0 || i == 5)
|
||||||
|
{
|
||||||
|
// Fill first and last row completely with border.
|
||||||
|
for (int k = 0; k < 9; k++)
|
||||||
|
{
|
||||||
|
if (itemArray[i][k] == null)
|
||||||
|
{
|
||||||
|
itemArray[i][k] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fill first and last element in row with border.
|
||||||
|
if (itemArray[i][0] == null)
|
||||||
|
{
|
||||||
|
itemArray[i][0] = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemArray[i][8] == null)
|
||||||
|
{
|
||||||
|
itemArray[i][8] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showLine[0] = true;
|
||||||
|
showLine[5] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now fill the background.
|
||||||
|
if (this.panelTemplate.background() != null)
|
||||||
|
{
|
||||||
|
PanelItem template = this.makeTemplate(this.panelTemplate.background());
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 9; k++)
|
||||||
|
{
|
||||||
|
if (itemArray[i][k] == null)
|
||||||
|
{
|
||||||
|
itemArray[i][k] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now place all panel items with their indexes into item map.
|
||||||
|
Map<Integer, PanelItem> itemMap = new HashMap<>(6 * 9);
|
||||||
|
|
||||||
|
int correctIndex = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < itemArray.length; i++)
|
||||||
|
{
|
||||||
|
final boolean iterate = showLine[i];
|
||||||
|
|
||||||
|
for (int k = 0; iterate && k < itemArray[i].length; k++)
|
||||||
|
{
|
||||||
|
if (itemArray[i][k] != null)
|
||||||
|
{
|
||||||
|
itemMap.put(correctIndex, itemArray[i][k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
correctIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates map with item indexes and their icons that will be added into
|
||||||
|
* hopper Panel.
|
||||||
|
* @return Map that contains indexes linked to the correct panel item.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private Map<Integer, PanelItem> populateHopperPanel()
|
||||||
|
{
|
||||||
|
// Init item array with the max available size.
|
||||||
|
PanelItem[] itemArray = new PanelItem[5];
|
||||||
|
|
||||||
|
// Analyze the template
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
ItemTemplateRecord record = this.panelTemplate.content()[0][i];
|
||||||
|
|
||||||
|
if (record != null && record.dataMap().containsKey("type"))
|
||||||
|
{
|
||||||
|
String type = String.valueOf(record.dataMap().get("type"));
|
||||||
|
|
||||||
|
int counter = this.typeSlotMap.computeIfAbsent(type, key -> 1);
|
||||||
|
this.typeSlotMap.put(type, counter + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make buttons
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
itemArray[i] = this.makeButton(this.panelTemplate.content()[0][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now fill the background.
|
||||||
|
if (this.panelTemplate.background() != null)
|
||||||
|
{
|
||||||
|
PanelItem template = this.makeTemplate(this.panelTemplate.background());
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
if (itemArray[i] == null)
|
||||||
|
{
|
||||||
|
itemArray[i] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now place all panel items with their indexes into item map.
|
||||||
|
Map<Integer, PanelItem> itemMap = new HashMap<>(5);
|
||||||
|
|
||||||
|
int correctIndex = 0;
|
||||||
|
|
||||||
|
for (PanelItem panelItem : itemArray)
|
||||||
|
{
|
||||||
|
if (panelItem != null)
|
||||||
|
{
|
||||||
|
itemMap.put(correctIndex, panelItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
correctIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates map with item indexes and their icons that will be added into
|
||||||
|
* dropper Panel.
|
||||||
|
* @return Map that contains indexes linked to the correct panel item.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private Map<Integer, PanelItem> populateDropperPanel()
|
||||||
|
{
|
||||||
|
// Analyze the template
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
ItemTemplateRecord record = this.panelTemplate.content()[i][k];
|
||||||
|
|
||||||
|
if (record != null && record.dataMap().containsKey("type"))
|
||||||
|
{
|
||||||
|
String type = String.valueOf(record.dataMap().get("type"));
|
||||||
|
|
||||||
|
int counter = this.typeSlotMap.computeIfAbsent(type, key -> 1);
|
||||||
|
this.typeSlotMap.put(type, counter + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init item array with the max available size.
|
||||||
|
PanelItem[][] itemArray = new PanelItem[3][3];
|
||||||
|
|
||||||
|
// Make buttons
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
itemArray[i][k] = this.makeButton(this.panelTemplate.content()[i][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now fill the background.
|
||||||
|
if (this.panelTemplate.background() != null)
|
||||||
|
{
|
||||||
|
PanelItem template = this.makeTemplate(this.panelTemplate.background());
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
if (itemArray[i][k] == null)
|
||||||
|
{
|
||||||
|
itemArray[i][k] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init item map with the max available size.
|
||||||
|
Map<Integer, PanelItem> itemMap = new HashMap<>(9);
|
||||||
|
|
||||||
|
int correctIndex = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
if (itemArray[i][k] != null)
|
||||||
|
{
|
||||||
|
itemMap.put(correctIndex, itemArray[i][k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
correctIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method passes button creation from given record template.
|
||||||
|
* @param record Template of the button that must be created.
|
||||||
|
* @return PanelItem of the template, otherwise null.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private PanelItem makeButton(@Nullable ItemTemplateRecord record)
|
||||||
|
{
|
||||||
|
if (record == null)
|
||||||
|
{
|
||||||
|
// Immediate exit if record is null.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.dataMap().containsKey("type"))
|
||||||
|
{
|
||||||
|
// If dataMap is not null, and it is not empty, then pass button to the object creator function.
|
||||||
|
|
||||||
|
return this.makeAddonButton(record);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PanelItemBuilder itemBuilder = new PanelItemBuilder();
|
||||||
|
|
||||||
|
if (record.icon() != null)
|
||||||
|
{
|
||||||
|
itemBuilder.icon(record.icon().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.title() != null)
|
||||||
|
{
|
||||||
|
itemBuilder.name(this.user.getTranslation(record.title()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.description() != null)
|
||||||
|
{
|
||||||
|
itemBuilder.description(this.user.getTranslation(record.description()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are generic click handlers that could be added, then this is a place
|
||||||
|
// where to process them.
|
||||||
|
|
||||||
|
// Click Handlers are managed by custom addon buttons.
|
||||||
|
return itemBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method passes button to the type creator, if that exists.
|
||||||
|
* @param record Template of the button that must be created.
|
||||||
|
* @return PanelItem of the button created by typeCreator, otherwise null.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private PanelItem makeAddonButton(@NonNull ItemTemplateRecord record)
|
||||||
|
{
|
||||||
|
// Get object type.
|
||||||
|
String type = String.valueOf(record.dataMap().getOrDefault("type", ""));
|
||||||
|
|
||||||
|
if (!this.typeCreators.containsKey(type))
|
||||||
|
{
|
||||||
|
// There are no object with a given type.
|
||||||
|
return this.makeFallBack(record.fallback());
|
||||||
|
}
|
||||||
|
|
||||||
|
BiFunction<ItemTemplateRecord, ItemSlot, PanelItem> buttonBuilder = this.typeCreators.get(type);
|
||||||
|
|
||||||
|
// Get next slot index.
|
||||||
|
ItemSlot itemSlot = this.typeIndex.containsKey(type) ?
|
||||||
|
this.typeIndex.get(type) :
|
||||||
|
new ItemSlot(0, this.typeSlotMap);
|
||||||
|
this.typeIndex.put(type, itemSlot.nextItemSlot());
|
||||||
|
|
||||||
|
// Try to get next object.
|
||||||
|
PanelItem item = buttonBuilder.apply(record, itemSlot);
|
||||||
|
return item == null ? this.makeFallBack(record.fallback()) : item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates a fall back button for given record.
|
||||||
|
* @param record Record which fallback must be created.
|
||||||
|
* @return PanelItem if fallback was creates successfully, otherwise null.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private PanelItem makeFallBack(@Nullable ItemTemplateRecord record)
|
||||||
|
{
|
||||||
|
return record == null ? null : this.makeButton(record.fallback());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method translates template record into a panel item.
|
||||||
|
* @param record Record that must be translated.
|
||||||
|
* @return PanelItem that contains all information from the record.
|
||||||
|
*/
|
||||||
|
private PanelItem makeTemplate(PanelTemplateRecord.TemplateItem record)
|
||||||
|
{
|
||||||
|
PanelItemBuilder itemBuilder = new PanelItemBuilder();
|
||||||
|
|
||||||
|
// Read icon only if it is not null.
|
||||||
|
if (record.icon() != null)
|
||||||
|
{
|
||||||
|
itemBuilder.icon(record.icon().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read title only if it is not null.
|
||||||
|
if (record.title() != null)
|
||||||
|
{
|
||||||
|
itemBuilder.name(this.user.getTranslation(record.title()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read description only if it is not null.
|
||||||
|
if (record.description() != null)
|
||||||
|
{
|
||||||
|
itemBuilder.description(this.user.getTranslation(record.description()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Click Handlers are managed by custom addon buttons.
|
||||||
|
return itemBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Classes
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This record contains current slot object and map that links types with a number of slots in
|
||||||
|
* panel with it.
|
||||||
|
* Some buttons need information about all types, like previous/next.
|
||||||
|
* @param slot Index of object in current panel.
|
||||||
|
* @param amountMap Map that links types with number of objects in panel.
|
||||||
|
*/
|
||||||
|
public record ItemSlot(int slot, Map<String, Integer> amountMap)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This method returns new record object with iterative slot index.
|
||||||
|
* @return New ItemSlot object that has increased slot index by 1.
|
||||||
|
*/
|
||||||
|
ItemSlot nextItemSlot()
|
||||||
|
{
|
||||||
|
return new ItemSlot(this.slot() + 1, this.amountMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Variables
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The GUI template record.
|
||||||
|
*/
|
||||||
|
private final PanelTemplateRecord panelTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user who opens the GUI.
|
||||||
|
*/
|
||||||
|
private final User user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This map links custom types with their info object.
|
||||||
|
*/
|
||||||
|
private final Map<String, BiFunction<ItemTemplateRecord, ItemSlot, PanelItem>> typeCreators;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the item slot information for each type.
|
||||||
|
*/
|
||||||
|
private final Map<String, ItemSlot> typeIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the number of items with given type in whole panel.
|
||||||
|
*/
|
||||||
|
private final Map<String, Integer> typeSlotMap;
|
||||||
|
}
|
@ -0,0 +1,203 @@
|
|||||||
|
//
|
||||||
|
// Created by BONNe
|
||||||
|
// Copyright - 2021
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
package world.bentobox.bentobox.api.panels.builders;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.api.panels.PanelItem;
|
||||||
|
import world.bentobox.bentobox.api.panels.PanelListener;
|
||||||
|
import world.bentobox.bentobox.api.panels.TemplatedPanel;
|
||||||
|
import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord;
|
||||||
|
import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord;
|
||||||
|
import world.bentobox.bentobox.api.panels.reader.TemplateReader;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds {@link TemplatedPanel}'s
|
||||||
|
* @author BONNe
|
||||||
|
* @since 1.17.3
|
||||||
|
*/
|
||||||
|
public class TemplatedPanelBuilder
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Builder
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the template that must be loaded for Template panel builder.
|
||||||
|
*
|
||||||
|
* @param guiName the gui name
|
||||||
|
* @param dataFolder the data folder
|
||||||
|
* @return the template panel builder
|
||||||
|
*/
|
||||||
|
public TemplatedPanelBuilder template(String guiName, File dataFolder)
|
||||||
|
{
|
||||||
|
this.panelTemplate = TemplateReader.readTemplatePanel(guiName, dataFolder);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the user for template panel builder.
|
||||||
|
*
|
||||||
|
* @param user the user
|
||||||
|
* @return the template panel builder
|
||||||
|
*/
|
||||||
|
public TemplatedPanelBuilder user(User user)
|
||||||
|
{
|
||||||
|
this.user = user;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the world for template panel builder.
|
||||||
|
*
|
||||||
|
* @param world the world
|
||||||
|
* @return the template panel builder
|
||||||
|
*/
|
||||||
|
public TemplatedPanelBuilder world(World world)
|
||||||
|
{
|
||||||
|
this.world = world;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the panel listener for template panel builder.
|
||||||
|
*
|
||||||
|
* @param listener the listener
|
||||||
|
* @return the template panel builder
|
||||||
|
*/
|
||||||
|
public TemplatedPanelBuilder listener(PanelListener listener)
|
||||||
|
{
|
||||||
|
this.listener = listener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers new button type builder for template panel builder.
|
||||||
|
*
|
||||||
|
* @param type the type
|
||||||
|
* @param buttonCreator the button creator
|
||||||
|
* @return the template panel builder
|
||||||
|
*/
|
||||||
|
public TemplatedPanelBuilder registerTypeBuilder(String type, BiFunction<ItemTemplateRecord, TemplatedPanel.ItemSlot, PanelItem> buttonCreator)
|
||||||
|
{
|
||||||
|
this.objectCreatorMap.put(type, buttonCreator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build templated panel.
|
||||||
|
*
|
||||||
|
* @return the templated panel
|
||||||
|
*/
|
||||||
|
public TemplatedPanel build()
|
||||||
|
{
|
||||||
|
return new TemplatedPanel(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Getters
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets panel template.
|
||||||
|
*
|
||||||
|
* @return the panel template
|
||||||
|
*/
|
||||||
|
public PanelTemplateRecord getPanelTemplate()
|
||||||
|
{
|
||||||
|
return this.panelTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets user.
|
||||||
|
*
|
||||||
|
* @return the user
|
||||||
|
*/
|
||||||
|
public User getUser()
|
||||||
|
{
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets world.
|
||||||
|
*
|
||||||
|
* @return the world
|
||||||
|
*/
|
||||||
|
public World getWorld()
|
||||||
|
{
|
||||||
|
return this.world;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets listener.
|
||||||
|
*
|
||||||
|
* @return the listener
|
||||||
|
*/
|
||||||
|
public PanelListener getListener()
|
||||||
|
{
|
||||||
|
return this.listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets object creator map.
|
||||||
|
*
|
||||||
|
* @return the object creator map
|
||||||
|
*/
|
||||||
|
public Map<String, BiFunction<ItemTemplateRecord, TemplatedPanel.ItemSlot, PanelItem>> getObjectCreatorMap()
|
||||||
|
{
|
||||||
|
return this.objectCreatorMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Variables
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The GUI template record.
|
||||||
|
*/
|
||||||
|
private PanelTemplateRecord panelTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user who opens the GUI.
|
||||||
|
*/
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The world where GUI operates.
|
||||||
|
*/
|
||||||
|
private World world;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel Listener
|
||||||
|
*/
|
||||||
|
private PanelListener listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map that links objects with their panel item creators.
|
||||||
|
*/
|
||||||
|
private final Map<String, BiFunction<ItemTemplateRecord, TemplatedPanel.ItemSlot, PanelItem>> objectCreatorMap = new HashMap<>();
|
||||||
|
}
|
@ -9,6 +9,8 @@ package world.bentobox.bentobox.api.panels.reader;
|
|||||||
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
import org.bukkit.event.inventory.ClickType;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -27,12 +29,12 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* @since 1.17.3
|
* @since 1.17.3
|
||||||
*/
|
*/
|
||||||
public record ItemTemplateRecord(ItemStack icon,
|
public record ItemTemplateRecord(@Nullable ItemStack icon,
|
||||||
String title,
|
@Nullable String title,
|
||||||
String description,
|
@Nullable String description,
|
||||||
List<ActionRecords> actions,
|
@NonNull List<ActionRecords> actions,
|
||||||
Map<String, Object> dataMap,
|
@NonNull Map<String, Object> dataMap,
|
||||||
ItemTemplateRecord fallback)
|
@Nullable ItemTemplateRecord fallback)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Instantiates a new Item template record without actions and data map.
|
* Instantiates a new Item template record without actions and data map.
|
||||||
|
@ -8,6 +8,8 @@ package world.bentobox.bentobox.api.panels.reader;
|
|||||||
|
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.panels.Panel;
|
import world.bentobox.bentobox.api.panels.Panel;
|
||||||
|
|
||||||
@ -20,15 +22,17 @@ import world.bentobox.bentobox.api.panels.Panel;
|
|||||||
* @param title the title of GUI
|
* @param title the title of GUI
|
||||||
* @param border the border block for GUI
|
* @param border the border block for GUI
|
||||||
* @param background the background block for GUI.
|
* @param background the background block for GUI.
|
||||||
|
* @param forcedRows the array of boolean that indicate which rows must be force loaded.
|
||||||
* @param content The 2D array of ItemTemplateRecords
|
* @param content The 2D array of ItemTemplateRecords
|
||||||
*
|
*
|
||||||
* @since 1.17.3
|
* @since 1.17.3
|
||||||
*/
|
*/
|
||||||
public record PanelTemplateRecord(Panel.Type type,
|
public record PanelTemplateRecord(Panel.Type type,
|
||||||
String title,
|
@Nullable String title,
|
||||||
TemplateItem border,
|
@Nullable TemplateItem border,
|
||||||
TemplateItem background,
|
@Nullable TemplateItem background,
|
||||||
ItemTemplateRecord[][] content)
|
boolean[] forcedRows,
|
||||||
|
@NonNull ItemTemplateRecord[][] content)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Instantiates a new Panel template record with empty content.
|
* Instantiates a new Panel template record with empty content.
|
||||||
@ -37,10 +41,11 @@ public record PanelTemplateRecord(Panel.Type type,
|
|||||||
* @param title the title
|
* @param title the title
|
||||||
* @param border the border
|
* @param border the border
|
||||||
* @param background the background
|
* @param background the background
|
||||||
|
* @param forcedRows the forced rows array
|
||||||
*/
|
*/
|
||||||
public PanelTemplateRecord(Panel.Type type, String title, TemplateItem border, TemplateItem background)
|
public PanelTemplateRecord(Panel.Type type, String title, TemplateItem border, TemplateItem background, boolean[] forcedRows)
|
||||||
{
|
{
|
||||||
this(type, title, border, background, new ItemTemplateRecord[6][9]);
|
this(type, title, border, background, forcedRows, new ItemTemplateRecord[6][9]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,7 +96,9 @@ public class TemplateReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
String title = configurationSection.getString("title");
|
String title = configurationSection.getString("title");
|
||||||
Panel.Type type = configurationSection.getObject("type", Panel.Type.class);
|
Panel.Type type =
|
||||||
|
Enums.getIfPresent(Panel.Type.class, configurationSection.getString("type", "INVENTORY")).
|
||||||
|
or(Panel.Type.INVENTORY);
|
||||||
|
|
||||||
PanelTemplateRecord.TemplateItem borderItem = null;
|
PanelTemplateRecord.TemplateItem borderItem = null;
|
||||||
|
|
||||||
@ -110,7 +112,7 @@ public class TemplateReader
|
|||||||
{
|
{
|
||||||
borderItem = new PanelTemplateRecord.TemplateItem(
|
borderItem = new PanelTemplateRecord.TemplateItem(
|
||||||
ItemParser.parse((borderSection.getString("icon", Material.AIR.name()))),
|
ItemParser.parse((borderSection.getString("icon", Material.AIR.name()))),
|
||||||
borderSection.getString("name", null),
|
borderSection.getString("title", null),
|
||||||
borderSection.getString("description", null));
|
borderSection.getString("description", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +136,7 @@ public class TemplateReader
|
|||||||
{
|
{
|
||||||
backgroundItem = new PanelTemplateRecord.TemplateItem(
|
backgroundItem = new PanelTemplateRecord.TemplateItem(
|
||||||
ItemParser.parse((backgroundSection.getString("icon", Material.AIR.name()))),
|
ItemParser.parse((backgroundSection.getString("icon", Material.AIR.name()))),
|
||||||
backgroundSection.getString("name", null),
|
backgroundSection.getString("title", null),
|
||||||
backgroundSection.getString("description", null));
|
backgroundSection.getString("description", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,8 +159,11 @@ public class TemplateReader
|
|||||||
readPanelItemTemplate(reusable.getConfigurationSection(key), key, panelItemDataMap));
|
readPanelItemTemplate(reusable.getConfigurationSection(key), key, panelItemDataMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read content
|
||||||
|
boolean[] forcedRows = readForcedRows(configurationSection);
|
||||||
|
|
||||||
// Create template record.
|
// Create template record.
|
||||||
PanelTemplateRecord template = new PanelTemplateRecord(type, title, borderItem, backgroundItem);
|
PanelTemplateRecord template = new PanelTemplateRecord(type, title, borderItem, backgroundItem, forcedRows);
|
||||||
|
|
||||||
// Read content
|
// Read content
|
||||||
ConfigurationSection content = configurationSection.getConfigurationSection("content");
|
ConfigurationSection content = configurationSection.getConfigurationSection("content");
|
||||||
@ -207,6 +212,41 @@ public class TemplateReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method reads force shown rows that must be always displayed.
|
||||||
|
* @param section Configuration section that contains force-shown path.
|
||||||
|
* @return boolean array that contains which lines are force loaded.
|
||||||
|
*/
|
||||||
|
private static boolean[] readForcedRows(@Nullable ConfigurationSection section)
|
||||||
|
{
|
||||||
|
boolean[] forceShow = new boolean[6];
|
||||||
|
|
||||||
|
if (section != null && section.contains("force-shown"))
|
||||||
|
{
|
||||||
|
if (section.isInt("force-shown"))
|
||||||
|
{
|
||||||
|
int value = section.getInt("force-shown");
|
||||||
|
|
||||||
|
if (value > 0 && value < 7)
|
||||||
|
{
|
||||||
|
forceShow[value-1] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (section.isList("force-shown"))
|
||||||
|
{
|
||||||
|
section.getIntegerList("force-shown").forEach(number -> {
|
||||||
|
if (number > 0 && number < 7)
|
||||||
|
{
|
||||||
|
forceShow[number-1] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return forceShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method creates PanelItemTemplate from a given configuration section.
|
* This method creates PanelItemTemplate from a given configuration section.
|
||||||
* @param section Section that should contain all information about the panel item template.
|
* @param section Section that should contain all information about the panel item template.
|
||||||
|
@ -171,7 +171,7 @@ public class ItemParser {
|
|||||||
boolean isExtended = part[3].equalsIgnoreCase("EXTENDED");
|
boolean isExtended = part[3].equalsIgnoreCase("EXTENDED");
|
||||||
PotionData data = new PotionData(type, isExtended, isUpgraded);
|
PotionData data = new PotionData(type, isExtended, isUpgraded);
|
||||||
potionMeta.setBasePotionData(data);
|
potionMeta.setBasePotionData(data);
|
||||||
|
result.setItemMeta(potionMeta);
|
||||||
result.setAmount(Integer.parseInt(part[5]));
|
result.setAmount(Integer.parseInt(part[5]));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user