Rename classes to Selectors.

Split single and multiple item selectors for easier implementation.
Update proper locales.
This commit is contained in:
BONNe 2021-09-18 12:51:00 +03:00
parent 5d88c7b1d8
commit 3bb0a30657
16 changed files with 1860 additions and 1259 deletions

View File

@ -0,0 +1,221 @@
package world.bentobox.challenges.panel.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.utils.Constants;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class creates new GUI that allows to select single challenge, which is returned via consumer.
*/
public class ChallengeSelector extends PagedSelector<Challenge>
{
private ChallengeSelector(User user, Material border, Map<Challenge, List<String>> challengesDescriptionMap, BiConsumer<Boolean, Set<Challenge>> consumer)
{
super(user);
this.consumer = consumer;
this.challengesDescriptionMap = challengesDescriptionMap;
this.border = border;
this.elements = challengesDescriptionMap.keySet().stream().toList();
this.selectedElements = new HashSet<>(this.elements.size());
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, Material border, Map<Challenge, List<String>> challengesDescriptionMap, BiConsumer<Boolean, Set<Challenge>> consumer)
{
new ChallengeSelector(user, border, challengesDescriptionMap, consumer).build();
}
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user);
panelBuilder.name(this.user.getTranslation(Constants.TITLE + "challenge-selector"));
GuiUtils.fillBorder(panelBuilder, this.border);
this.populateElements(panelBuilder, this.elements);
panelBuilder.item(3, this.createButton(Button.ACCEPT_SELECTED));
panelBuilder.item(5, this.createButton(Button.CANCEL));
panelBuilder.build();
}
/**
* This method creates PanelItem button of requested type.
* @param button Button which must be created.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton(Button button)
{
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case ACCEPT_SELECTED -> {
if (!this.selectedElements.isEmpty())
{
description.add(this.user.getTranslation(reference + "title"));
this.selectedElements.forEach(challenge -> {
description.add(this.user.getTranslation(reference + "element",
"[element]", challenge.getFriendlyName()));
});
}
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(true, this.selectedElements);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-save"));
}
case CANCEL -> {
icon = new ItemStack(Material.IRON_DOOR);
clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(false, null);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
}
default -> {
icon = new ItemStack(Material.PAPER);
clickHandler = null;
}
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
/**
* This method creates button for given challenge.
* @param challenge challenge which button must be created.
* @return new Button for challenge.
*/
@Override
protected PanelItem createElementButton(Challenge challenge)
{
final String reference = Constants.BUTTON + "entity.";
List<String> description = new ArrayList<>(this.challengesDescriptionMap.get(challenge));
description.add("");
if (this.selectedElements.contains(challenge))
{
description.add(this.user.getTranslation(reference + "selected"));
description.add(this.user.getTranslation(Constants.TIPS + "click-to-deselect"));
}
else
{
description.add(this.user.getTranslation(Constants.TIPS + "click-to-select"));
}
return new PanelItemBuilder().
name(Util.translateColorCodes(challenge.getFriendlyName())).
icon(challenge.getIcon()).
description(description).
clickHandler((panel, user1, clickType, slot) -> {
// On right click change which entities are selected for deletion.
if (!this.selectedElements.add(challenge))
{
// Remove challenge if it is already selected
this.selectedElements.remove(challenge);
}
this.build();
return true;
}).
glow(this.selectedElements.contains(challenge)).
build();
}
/**
* Functional buttons in current GUI.
*/
private enum Button
{
ACCEPT_SELECTED,
CANCEL
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores consumer.
*/
private final BiConsumer<Boolean, Set<Challenge>> consumer;
/**
* Current value.
*/
private final List<Challenge> elements;
/**
* Selected challenges that will be returned to consumer.
*/
private final Set<Challenge> selectedElements;
/**
* Map that contains all challenge descriptions
*/
private final Map<Challenge, List<String>> challengesDescriptionMap;
/**
* Border Material.
*/
private final Material border;
}

View File

@ -1,151 +0,0 @@
//
// Created by BONNe
// Copyright - 2019
//
package world.bentobox.challenges.panel.util;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.requirements.*;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class creates GUI that allows to select challenge type.
*/
public class ChallengeTypeGUI
{
/**
* Default constructor that builds gui.
* @param user User who opens GUI.
* @param lineLength Lore line length
* @param consumer Consumer that allows to get clicked type.
*/
private ChallengeTypeGUI(User user, int lineLength, BiConsumer<Challenge.ChallengeType, Requirements> consumer)
{
this.user = user;
this.lineLength = lineLength;
this.consumer = consumer;
}
/**
* This method opens GUI that allows to select challenge type.
* @param user User who opens GUI.
* @param lineLength Lore line length
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, int lineLength, BiConsumer<Challenge.ChallengeType, Requirements> consumer)
{
new ChallengeTypeGUI(user, lineLength, consumer).build();
}
/**
* This method builds GUI that allows to select challenge type.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().
user(this.user).
type(Panel.Type.HOPPER).
name(this.user.getTranslation("challenges.gui.title.admin.type-select"));
panelBuilder.item(0, this.getButton(Challenge.ChallengeType.INVENTORY));
panelBuilder.item(1, this.getButton(Challenge.ChallengeType.ISLAND));
panelBuilder.item(2, this.getButton(Challenge.ChallengeType.OTHER));
panelBuilder.item(3, this.getButton(Challenge.ChallengeType.STATISTIC));
panelBuilder.build();
}
/**
* Creates ChallengeType button.
* @param type Challenge type which button must be created.
* @return PanelItem button.
*/
private PanelItem getButton(Challenge.ChallengeType type)
{
ItemStack icon;
String name = this.user.getTranslation("challenges.gui.buttons.admin.type." + type.name().toLowerCase());
List<String> description = new ArrayList<>();
description.add(this.user.getTranslation("challenges.gui.descriptions.type." + type.name().toLowerCase()));
PanelItem.ClickHandler clickHandler;
switch (type)
{
case INVENTORY:
icon = new ItemStack(Material.CHEST);
clickHandler = ((panel, user1, clickType, slot) -> {
this.consumer.accept(type, new InventoryRequirements());
return true;
});
break;
case ISLAND:
icon = new ItemStack(Material.GRASS_BLOCK);
clickHandler = ((panel, user1, clickType, slot) -> {
this.consumer.accept(type, new IslandRequirements());
return true;
});
break;
case OTHER:
icon = new ItemStack(Material.EXPERIENCE_BOTTLE);
clickHandler = ((panel, user1, clickType, slot) -> {
this.consumer.accept(type, new OtherRequirements());
return true;
});
break;
case STATISTIC:
icon = new ItemStack(Material.BOOK);
clickHandler = ((panel, user1, clickType, slot) -> {
this.consumer.accept(type, new StatisticRequirements());
return true;
});
break;
default:
return null;
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(GuiUtils.stringSplit(description, this.lineLength)).
clickHandler(clickHandler).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* User who runs GUI.
*/
private final User user;
/**
* Lore line max length.
*/
private final int lineLength;
/**
* Consumer that returns Challenge Type.
*/
private final BiConsumer<Challenge.ChallengeType, Requirements> consumer;
}

View File

@ -0,0 +1,133 @@
//
// Created by BONNe
// Copyright - 2019
//
package world.bentobox.challenges.panel.util;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.requirements.*;
import world.bentobox.challenges.utils.Constants;
/**
* This class creates GUI that allows to select challenge type.
*/
public record ChallengeTypeSelector(User user, BiConsumer<Challenge.ChallengeType, Requirements> consumer)
{
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, BiConsumer<Challenge.ChallengeType, Requirements> consumer)
{
new ChallengeTypeSelector(user, consumer).build();
}
/**
* This method builds GUI that allows to select challenge type.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().
user(this.user).
type(Panel.Type.HOPPER).
name(this.user.getTranslation(Constants.TITLE + "type-selector"));
panelBuilder.item(0, this.getButton(Challenge.ChallengeType.INVENTORY_TYPE));
panelBuilder.item(1, this.getButton(Challenge.ChallengeType.ISLAND_TYPE));
panelBuilder.item(2, this.getButton(Challenge.ChallengeType.OTHER_TYPE));
panelBuilder.item(3, this.getButton(Challenge.ChallengeType.STATISTIC_TYPE));
panelBuilder.build();
}
/**
* Creates ChallengeType button.
*
* @param type Challenge type which button must be created.
* @return PanelItem button.
*/
private PanelItem getButton(Challenge.ChallengeType type)
{
final String reference = Constants.BUTTON + type.name().toLowerCase() + ".";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-select"));
ItemStack icon;
PanelItem.ClickHandler clickHandler;
switch (type)
{
case INVENTORY_TYPE -> {
icon = new ItemStack(Material.CHEST);
clickHandler = (
(panel, user1, clickType, slot) ->
{
this.consumer.accept(type, new InventoryRequirements());
return true;
});
}
case ISLAND_TYPE -> {
icon = new ItemStack(Material.GRASS_BLOCK);
clickHandler = (
(panel, user1, clickType, slot) ->
{
this.consumer.accept(type, new IslandRequirements());
return true;
});
}
case OTHER_TYPE -> {
icon = new ItemStack(Material.EXPERIENCE_BOTTLE);
clickHandler = (
(panel, user1, clickType, slot) ->
{
this.consumer.accept(type, new OtherRequirements());
return true;
});
}
case STATISTIC_TYPE -> {
icon = new ItemStack(Material.BOOK);
clickHandler = (
(panel, user1, clickType, slot) ->
{
this.consumer.accept(type, new StatisticRequirements());
return true;
});
}
default -> {
icon = new ItemStack(Material.PAPER);
clickHandler = null;
}
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
}

View File

@ -0,0 +1,196 @@
package world.bentobox.challenges.panel.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.Constants;
import world.bentobox.challenges.utils.Utils;
/**
* This class creates panel that allows to select and deselect World Environments. On save it runs
* input consumer with true and selected values.
*/
public record EnvironmentSelector(User user, Set<World.Environment> values, BiConsumer<Boolean, Set<World.Environment>> consumer)
{
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, Set<World.Environment> values, BiConsumer<Boolean, Set<World.Environment>> consumer)
{
new EnvironmentSelector(user, values, consumer).build();
}
/**
* This method builds GUI that allows to select challenge type.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().
user(this.user).
type(Panel.Type.HOPPER).
name(this.user.getTranslation(Constants.TITLE + "environment-selector"));
panelBuilder.item(0, this.getButton(World.Environment.NORMAL));
panelBuilder.item(1, this.getButton(World.Environment.NETHER));
panelBuilder.item(2, this.getButton(World.Environment.THE_END));
panelBuilder.item(3, this.getButton(Button.ACCEPT_SELECTED));
panelBuilder.item(4, this.getButton(Button.CANCEL));
panelBuilder.build();
}
/**
* This method create button that does some functionality in current gui.
*
* @param environment Environment
* @return PanelItem.
*/
private PanelItem getButton(World.Environment environment)
{
final String reference = Constants.BUTTON + "environment_element.";
String name = this.user.getTranslation(reference + "name",
"[environment]", Utils.prettifyObject(environment, this.user));
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslationOrNothing(reference + "description",
"[description]", Utils.prettifyDescription(environment, this.user)));
if (this.values.contains(environment))
{
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-deselect"));
}
else
{
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-select"));
}
PanelItem.ClickHandler clickHandler = (panel, user, clickType, slot) ->
{
if (this.values.contains(environment))
{
this.values.remove(environment);
}
else
{
this.values.add(environment);
}
this.build();
return true;
};
ItemStack icon;
switch (environment)
{
case NORMAL -> icon = new ItemStack(Material.DIRT);
case NETHER -> icon = new ItemStack(Material.NETHERRACK);
case THE_END -> icon = new ItemStack(Material.END_STONE);
default -> icon = new ItemStack(Material.PAPER);
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
glow(this.values.contains(environment)).
build();
}
/**
* This method create button that does some functionality in current gui.
*
* @param button Button functionality.
* @return PanelItem.
*/
private PanelItem getButton(Button button)
{
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case ACCEPT_SELECTED -> {
if (!this.values.isEmpty())
{
description.add(this.user.getTranslation(reference + "title"));
this.values.forEach(element -> {
description.add(this.user.getTranslation(reference + "element",
"[element]", Utils.prettifyObject(element, this.user)));
});
}
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user, clickType, slot) ->
{
this.consumer.accept(true, this.values);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-save"));
}
case CANCEL -> {
icon = new ItemStack(Material.IRON_DOOR);
clickHandler = (panel, user, clickType, slot) ->
{
this.consumer.accept(false, Collections.emptySet());
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
}
default -> {
icon = new ItemStack(Material.PAPER);
clickHandler = null;
}
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
/**
* This enum holds all button values in current gui.
*/
private enum Button
{
CANCEL,
ACCEPT_SELECTED
}
}

View File

@ -16,21 +16,23 @@ import world.bentobox.bentobox.api.panels.PanelListener;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.Constants;
/**
* This class allows to change Input ItemStacks to different ItemStacks.
*/
public class ItemSwitchGUI
public record ItemSelector(User user, List<ItemStack> itemStacks, BiConsumer<Boolean, List<ItemStack>> consumer)
{
public ItemSwitchGUI(User user, List<ItemStack> itemStacks, int lineLength, BiConsumer<Boolean, List<ItemStack>> consumer)
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, List<ItemStack> itemStacks, BiConsumer<Boolean, List<ItemStack>> consumer)
{
this.consumer = consumer;
this.user = user;
this.itemStacks = itemStacks;
this.lineLength = lineLength;
this.build();
new ItemSelector(user, itemStacks, consumer).build();
}
@ -39,7 +41,9 @@ public class ItemSwitchGUI
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.title.admin.manage-items"));
PanelBuilder panelBuilder = new PanelBuilder().
user(this.user).
name(this.user.getTranslation(Constants.TITLE + "item-selector"));
// Size of inventory that user can set via GUI.
panelBuilder.size(45);
@ -66,24 +70,27 @@ public class ItemSwitchGUI
/**
* This method create button that does some functionality in current gui.
*
* @param button Button functionality.
* @return PanelItem.
*/
private PanelItem getButton(Button button)
{
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon;
String name;
List<String> description;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case SAVE:
{
name = this.user.getTranslation("challenges.gui.buttons.admin.save");
description = Collections.emptyList();
case SAVE -> {
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user, clickType, slot) -> {
clickHandler = (panel, user, clickType, slot) ->
{
// Magic number 9 - second row. First row is for custom buttons.
// Magic number 45 - This GUI is initialed with 45 elements.
List<ItemStack> returnItems = new ArrayList<>(36);
@ -102,36 +109,37 @@ public class ItemSwitchGUI
return true;
};
break;
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-save"));
}
case CANCEL:
{
name = this.user.getTranslation("challenges.gui.buttons.admin.cancel");
description = Collections.emptyList();
case CANCEL -> {
icon = new ItemStack(Material.IRON_DOOR);
clickHandler = (panel, user, clickType, slot) -> {
clickHandler = (panel, user, clickType, slot) ->
{
this.consumer.accept(false, Collections.emptyList());
return true;
};
break;
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
}
case EMPTY:
{
name = "";
description = Collections.emptyList();
case EMPTY -> {
description.clear();
name = "&r";
icon = new ItemStack(Material.BARRIER);
clickHandler = (panel, user, clickType, slot) -> true;
break;
clickHandler = null;
}
default -> {
icon = new ItemStack(Material.PAPER);
clickHandler = null;
}
default:
return null;
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(GuiUtils.stringSplit(description, this.lineLength)).
glow(false).
description(description).
clickHandler(clickHandler).
build();
}
@ -143,11 +151,10 @@ public class ItemSwitchGUI
/**
* This CustomPanelItem does no lose Item original MetaData. After PanelItem has been
* created it restores original meta data. It also does not allow to change anything that
* could destroy meta data.
* This CustomPanelItem does no lose Item original MetaData. After PanelItem has been created it
* restores original meta data. It also does not allow to change anything that could destroy meta data.
*/
private class CustomPanelItem extends PanelItem
private static class CustomPanelItem extends PanelItem
{
CustomPanelItem(ItemStack item)
{
@ -190,7 +197,7 @@ public class ItemSwitchGUI
/**
* This CustomPanelListener allows to move items in current panel.
*/
private class CustomPanelListener implements PanelListener
private static class CustomPanelListener implements PanelListener
{
@Override
public void setup()
@ -227,30 +234,4 @@ public class ItemSwitchGUI
SAVE,
EMPTY
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* User who opens current gui.
*/
private User user;
/**
* List with original items.
*/
private List<ItemStack> itemStacks;
/**
* Consumer that returns item stacks on save action.
*/
private BiConsumer<Boolean, List<ItemStack>> consumer;
/**
* This variable stores how large line can be, before warp it.
*/
private int lineLength;
}

View File

@ -0,0 +1,263 @@
package world.bentobox.challenges.panel.util;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.Constants;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.Utils;
/**
* This class contains all necessary things that allows to select single block from all ingame blocks. Selected
* block will be returned via BiConsumer.
*/
public class MultiBlockSelector extends PagedSelector<Material>
{
private MultiBlockSelector(User user, Mode mode, Set<Material> excluded, BiConsumer<Boolean, Collection<Material>> consumer)
{
super(user);
this.consumer = consumer;
// Current GUI cannot display air blocks. It crashes with null-pointer
excluded.add(Material.AIR);
excluded.add(Material.CAVE_AIR);
excluded.add(Material.VOID_AIR);
// Piston head and moving piston is not necessary. useless.
excluded.add(Material.PISTON_HEAD);
excluded.add(Material.MOVING_PISTON);
// Barrier cannot be accessible to user.
excluded.add(Material.BARRIER);
this.selectedElements = new HashSet<>();
this.elements = Arrays.stream(Material.values()).
filter(material -> !excluded.contains(material)).
filter(material -> {
switch (mode)
{
case BLOCKS -> {
return material.isBlock();
}
case ITEMS -> {
return material.isItem();
}
default -> {
return true;
}
}
}).
collect(Collectors.toList());
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, Mode mode, Set<Material> excluded, BiConsumer<Boolean, Collection<Material>> consumer)
{
new MultiBlockSelector(user, mode, excluded, consumer).build();
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, BiConsumer<Boolean, Collection<Material>> consumer)
{
new MultiBlockSelector(user, Mode.ANY, new HashSet<>(), consumer).build();
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user);
panelBuilder.name(this.user.getTranslation(Constants.TITLE + "block-selector"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
this.populateElements(panelBuilder, this.elements);
panelBuilder.item(3, this.createButton(Button.ACCEPT_SELECTED));
panelBuilder.item(5, this.createButton(Button.CANCEL));
panelBuilder.build();
}
/**
* This method creates PanelItem button of requested type.
* @param button Button which must be created.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton(Button button)
{
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case ACCEPT_SELECTED -> {
if (!this.selectedElements.isEmpty())
{
description.add(this.user.getTranslation(reference + "title"));
this.selectedElements.forEach(material -> {
description.add(this.user.getTranslation(reference + "element",
"[element]", Utils.prettifyObject(material, this.user)));
});
}
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(true, this.selectedElements);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-save"));
}
case CANCEL -> {
icon = new ItemStack(Material.IRON_DOOR);
clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(false, null);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
}
default -> {
icon = new ItemStack(Material.PAPER);
clickHandler = null;
}
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
/**
* This method creates button for given material.
* @param material material which button must be created.
* @return new Button for material.
*/
@Override
protected PanelItem createElementButton(Material material)
{
final String reference = Constants.BUTTON + "material.";
List<String> description = new ArrayList<>();
description.add(this.user.getTranslation(reference + "description",
"[id]", material.name()));
if (this.selectedElements.contains(material))
{
description.add(this.user.getTranslation(reference + "selected"));
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-deselect"));
}
else
{
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-select"));
}
return new PanelItemBuilder().
name(this.user.getTranslation(reference + "name", "[material]",
Utils.prettifyObject(material, this.user))).
icon(GuiUtils.getMaterialItem(material)).
description(description).
clickHandler((panel, user1, clickType, slot) -> {
// On right click change which entities are selected for deletion.
if (!this.selectedElements.add(material))
{
// Remove material if it is already selected
this.selectedElements.remove(material);
}
this.build();
return true;
}).
glow(this.selectedElements.contains(material)).
build();
}
/**
* Functional buttons in current GUI.
*/
private enum Button
{
ACCEPT_SELECTED,
CANCEL
}
public enum Mode
{
BLOCKS,
ITEMS,
ANY
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private final List<Material> elements;
/**
* Set that contains selected materials.
*/
private final Set<Material> selectedElements;
/**
* This variable stores consumer.
*/
private final BiConsumer<Boolean, Collection<Material>> consumer;
}

View File

@ -0,0 +1,251 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.Constants;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.Utils;
/**
* This class contains all necessary things that allows to select single block from all ingame blocks. Selected
* block will be returned via BiConsumer.
*/
public class MultiEntitySelector extends PagedSelector<EntityType>
{
private MultiEntitySelector(User user, boolean asEgg, Mode mode, Set<EntityType> excluded, BiConsumer<Boolean, Collection<EntityType>> consumer)
{
super(user);
this.consumer = consumer;
this.asEgg = asEgg;
this.selectedElements = new HashSet<>();
this.elements = Arrays.stream(EntityType.values()).
filter(entity -> !excluded.contains(entity)).
filter(entity -> {
if (mode == Mode.ALIVE)
{
return entity.isAlive();
}
else
{
return true;
}
}).
collect(Collectors.toList());
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, boolean asEgg, Mode mode, Set<EntityType> excluded, BiConsumer<Boolean, Collection<EntityType>> consumer)
{
new MultiEntitySelector(user, asEgg, mode, excluded, consumer).build();
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, boolean asEgg, BiConsumer<Boolean, Collection<EntityType>> consumer)
{
new MultiEntitySelector(user, asEgg, Mode.ANY, new HashSet<>(), consumer).build();
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user);
panelBuilder.name(this.user.getTranslation(Constants.TITLE + "entity-selector"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
this.populateElements(panelBuilder, this.elements);
panelBuilder.item(3, this.createButton(Button.ACCEPT_SELECTED));
panelBuilder.item(5, this.createButton(Button.CANCEL));
panelBuilder.build();
}
/**
* This method creates PanelItem button of requested type.
* @param button Button which must be created.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton(Button button)
{
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case ACCEPT_SELECTED -> {
if (!this.selectedElements.isEmpty())
{
description.add(this.user.getTranslation(reference + "title"));
this.selectedElements.forEach(material -> {
description.add(this.user.getTranslation(reference + "element",
"[element]", Utils.prettifyObject(material, this.user)));
});
}
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(true, this.selectedElements);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-save"));
}
case CANCEL -> {
icon = new ItemStack(Material.IRON_DOOR);
clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(false, null);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
}
default -> {
icon = new ItemStack(Material.PAPER);
clickHandler = null;
}
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
/**
* This method creates button for given entity.
* @param entity entity which button must be created.
* @return new Button for entity.
*/
@Override
protected PanelItem createElementButton(EntityType entity)
{
final String reference = Constants.BUTTON + "entity.";
List<String> description = new ArrayList<>();
description.add(this.user.getTranslation(reference + "description",
"[id]", entity.name()));
if (this.selectedElements.contains(entity))
{
description.add(this.user.getTranslation(reference + "selected"));
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-deselect"));
}
else
{
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-select"));
}
return new PanelItemBuilder().
name(this.user.getTranslation(reference + "name", "[entity]",
Utils.prettifyObject(entity, this.user))).
icon(this.asEgg ? GuiUtils.getEntityEgg(entity) : GuiUtils.getEntityHead(entity)).
description(description).
clickHandler((panel, user1, clickType, slot) -> {
// On right click change which entities are selected for deletion.
if (!this.selectedElements.add(entity))
{
// Remove entity if it is already selected
this.selectedElements.remove(entity);
}
this.build();
return true;
}).
glow(this.selectedElements.contains(entity)).
build();
}
/**
* Functional buttons in current GUI.
*/
private enum Button
{
ACCEPT_SELECTED,
CANCEL
}
public enum Mode
{
ALIVE,
ANY
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private final List<EntityType> elements;
/**
* Set that contains selected materials.
*/
private final Set<EntityType> selectedElements;
/**
* This variable stores consumer.
*/
private final BiConsumer<Boolean, Collection<EntityType>> consumer;
/**
* Indicates that entity must be displayed as egg.
*/
private final boolean asEgg;
}

View File

@ -0,0 +1,178 @@
//
// Created by BONNe
// Copyright - 2021
//
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.Constants;
/**
* This single abstract class will manage paged selectors similar to CommonPagedPanel.
*/
public abstract class PagedSelector<T>
{
/**
* Instantiates a new Paged selector.
*
* @param user the user
*/
protected PagedSelector(User user)
{
this.user = user;
}
/**
* Build.
*/
protected abstract void build();
/**
* Create element button panel item.
*
* @param object the object
* @return the panel item
*/
protected abstract PanelItem createElementButton(T object);
/**
* Populate elements.
*
* @param panelBuilder the panel builder
* @param objectList the object list
*/
protected void populateElements(PanelBuilder panelBuilder, List<T> objectList)
{
final int MAX_ELEMENTS = 21;
final int size = objectList.size();
if (this.pageIndex < 0)
{
this.pageIndex = size / MAX_ELEMENTS;
}
else if (this.pageIndex > (size / MAX_ELEMENTS))
{
this.pageIndex = 0;
}
int objectIndex = MAX_ELEMENTS * this.pageIndex;
// I want first row to be only for navigation and return button.
int index = 10;
while (objectIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
objectIndex < size &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createElementButton(objectList.get(objectIndex++)));
}
index++;
}
if (size > MAX_ELEMENTS && !(1.0 * size / MAX_ELEMENTS <= this.pageIndex + 1))
{
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
}
if (this.pageIndex > 0)
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
}
}
/**
* This method returns PanelItem that represents given Button.
* @param button Button that must be returned.
* @return PanelItem with requested functionality.
*/
protected PanelItem getButton(CommonButtons button)
{
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
ItemStack icon;
PanelItem.ClickHandler clickHandler;
if (button == CommonButtons.NEXT)
{
description.add(this.user.getTranslation(reference + "description",
Constants.NUMBER, String.valueOf(this.pageIndex + 2)));
icon = new ItemStack(Material.OAK_SIGN, this.pageIndex + 2);
clickHandler = (panel, user, clickType, slot) ->
{
this.pageIndex++;
this.build();
return true;
};
}
else if (button == CommonButtons.PREVIOUS)
{
description.add(this.user.getTranslation(reference + "description",
Constants.NUMBER, String.valueOf(this.pageIndex)));
icon = new ItemStack(Material.OAK_SIGN, Math.max(1, this.pageIndex));
clickHandler = (panel, user, clickType, slot) ->
{
this.pageIndex--;
this.build();
return true;
};
}
else
{
icon = new ItemStack(Material.PAPER);
clickHandler = null;
}
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
/**
* Next and Previous Buttons.
*/
private enum CommonButtons
{
NEXT,
PREVIOUS
}
/**
* Current page index.
*/
private int pageIndex;
/**
* User who opens gui.
*/
protected final User user;
}

View File

@ -1,276 +0,0 @@
package world.bentobox.challenges.panel.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class contains all necessary things that allows to select single block from all ingame blocks. Selected
* block will be returned via BiConsumer.
*/
public class SelectBlocksGUI
{
public SelectBlocksGUI(User user, BiConsumer<Boolean, Set<Material>> consumer)
{
this(user, false, new HashSet<>(), consumer);
}
public SelectBlocksGUI(User user, boolean singleSelect, BiConsumer<Boolean, Set<Material>> consumer)
{
this.consumer = consumer;
this.user = user;
this.singleSelect = singleSelect;
// Current GUI cannot display air blocks. It crashes with null-pointer
Set<Material> excludedMaterial = new HashSet<>();
excludedMaterial.add(Material.AIR);
excludedMaterial.add(Material.CAVE_AIR);
excludedMaterial.add(Material.VOID_AIR);
// Piston head and moving piston is not necessary. useless.
excludedMaterial.add(Material.PISTON_HEAD);
excludedMaterial.add(Material.MOVING_PISTON);
// Barrier cannot be accessible to user.
excludedMaterial.add(Material.BARRIER);
this.elements = new ArrayList<>();
this.selectedMaterials = new HashSet<>();
for (Material material : Material.values())
{
if (!material.isLegacy() && !excludedMaterial.contains(material))
{
this.elements.add(material);
}
}
this.build(0);
}
public SelectBlocksGUI(User user, boolean singleSelect, Set<Material> excludedMaterial, BiConsumer<Boolean, Set<Material>> consumer)
{
this.consumer = consumer;
this.user = user;
this.singleSelect = singleSelect;
// Current GUI cannot display air blocks. It crashes with null-pointer
excludedMaterial.add(Material.AIR);
excludedMaterial.add(Material.CAVE_AIR);
excludedMaterial.add(Material.VOID_AIR);
// Piston head and moving piston is not necessary. useless.
excludedMaterial.add(Material.PISTON_HEAD);
excludedMaterial.add(Material.MOVING_PISTON);
// Barrier cannot be accessible to user.
excludedMaterial.add(Material.BARRIER);
this.elements = new ArrayList<>();
this.selectedMaterials = new HashSet<>();
for (Material material : Material.values())
{
if (material.isBlock() && !material.isLegacy() && !excludedMaterial.contains(material))
{
this.elements.add(material);
}
}
this.build(0);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
public void build(int pageIndex)
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation("challenges.gui.title.admin.select-block"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
final int MAX_ELEMENTS = 21;
final int correctPage;
if (pageIndex < 0)
{
correctPage = this.elements.size() / MAX_ELEMENTS;
}
else if (pageIndex > (this.elements.size() / MAX_ELEMENTS))
{
correctPage = 0;
}
else
{
correctPage = pageIndex;
}
int entitiesIndex = MAX_ELEMENTS * correctPage;
// I want first row to be only for navigation and return button.
int index = 10;
while (entitiesIndex < ((correctPage + 1) * MAX_ELEMENTS) &&
entitiesIndex < this.elements.size())
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createMaterialButton(this.elements.get(entitiesIndex++)));
}
index++;
}
panelBuilder.item(3,
new PanelItemBuilder().
icon(Material.RED_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.admin.cancel")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
List<String> description = new ArrayList<>();
if (!this.selectedMaterials.isEmpty())
{
description.add(this.user.getTranslation("challenges.gui.descriptions.admin.selected") + ":");
this.selectedMaterials.forEach(material -> description.add(" - " + material.name()));
}
panelBuilder.item(5,
new PanelItemBuilder().
icon(Material.GREEN_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.admin.accept")).
description(description).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(true, this.selectedMaterials);
return true;
}).build());
if (this.elements.size() > MAX_ELEMENTS)
{
// Navigation buttons if necessary
panelBuilder.item(18,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage - 1);
return true;
}).build());
panelBuilder.item(26,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage + 1);
return true;
}).build());
}
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
panelBuilder.build();
}
/**
* This method creates PanelItem that represents given material.
* Some materials is not displayable in Inventory GUI, so they are replaced with "placeholder" items.
* @param material Material which icon must be created.
* @return PanelItem that represents given material.
*/
private PanelItem createMaterialButton(Material material)
{
ItemStack itemStack = GuiUtils.getMaterialItem(material);
return new PanelItemBuilder().
name(WordUtils.capitalize(material.name().toLowerCase().replace("_", " "))).
description(this.selectedMaterials.contains(material) ?
this.user.getTranslation("challenges.gui.descriptions.admin.selected") : "").
icon(itemStack).
clickHandler((panel, user1, clickType, slot) -> {
if (!this.singleSelect && clickType.isRightClick())
{
if (!this.selectedMaterials.add(material))
{
this.selectedMaterials.remove(material);
}
panel.getInventory().setItem(slot, this.createMaterialButton(material).getItem());
}
else
{
this.selectedMaterials.add(material);
this.consumer.accept(true, this.selectedMaterials);
}
return true;
}).
glow(!itemStack.getType().equals(material)).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private List<Material> elements;
/**
* Set that contains selected materials.
*/
private Set<Material> selectedMaterials;
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean, Set<Material>> consumer;
/**
* User who runs GUI.
*/
private User user;
/**
* This indicate that return set must contain only single item.
*/
private boolean singleSelect;
}

View File

@ -1,215 +0,0 @@
package world.bentobox.challenges.panel.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.event.inventory.ClickType;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class creates new GUI that allows to select single challenge, which is returned via consumer.
*/
public class SelectChallengeGUI
{
public SelectChallengeGUI(User user, Map<Challenge, List<String>> challengesDescriptionMap, int lineLength, BiConsumer<Boolean, Set<Challenge>> consumer)
{
this.consumer = consumer;
this.user = user;
this.challengesList = new ArrayList<>(challengesDescriptionMap.keySet());
this.challengesDescriptionMap = challengesDescriptionMap;
this.lineLength = lineLength;
this.selectedChallenges = new HashSet<>(this.challengesList.size());
this.build(0);
}
/**
* This method builds panel that allows to select single challenge from input challenges.
*/
private void build(int pageIndex)
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.title.admin.select-challenge"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
// Maximal elements in page.
final int MAX_ELEMENTS = 21;
final int correctPage;
if (pageIndex < 0)
{
correctPage = this.challengesList.size() / MAX_ELEMENTS;
}
else if (pageIndex > (this.challengesList.size() / MAX_ELEMENTS))
{
correctPage = 0;
}
else
{
correctPage = pageIndex;
}
panelBuilder.item(4,
new PanelItemBuilder().
icon(Material.RED_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
if (this.challengesList.size() > MAX_ELEMENTS)
{
// Navigation buttons if necessary
panelBuilder.item(18,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage - 1);
return true;
}).build());
panelBuilder.item(26,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage + 1);
return true;
}).build());
}
int challengesIndex = MAX_ELEMENTS * correctPage;
// I want first row to be only for navigation and return button.
int index = 10;
while (challengesIndex < ((correctPage + 1) * MAX_ELEMENTS) &&
challengesIndex < this.challengesList.size() &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index,
this.createChallengeButton(this.challengesList.get(challengesIndex++)));
}
index++;
}
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
panelBuilder.build();
}
/**
* This method builds PanelItem for given challenge.
* @param challenge Challenge which PanelItem must be created.
* @return new PanelItem for given Challenge.
*/
private PanelItem createChallengeButton(Challenge challenge)
{
List<String> description;
if (this.selectedChallenges.contains(challenge))
{
description = new ArrayList<>();
description.add(this.user.getTranslation("challenges.gui.descriptions.admin.selected"));
description.addAll(this.challengesDescriptionMap.get(challenge));
}
else
{
description = this.challengesDescriptionMap.get(challenge);
}
return new PanelItemBuilder().
name(ChatColor.translateAlternateColorCodes('&', challenge.getFriendlyName())).
description(GuiUtils.stringSplit(description, this.lineLength)).
icon(challenge.getIcon()).
clickHandler((panel, user1, clickType, slot) -> {
if (clickType == ClickType.RIGHT)
{
// If challenge is not selected, then select :)
if (!this.selectedChallenges.remove(challenge))
{
this.selectedChallenges.add(challenge);
}
// Reset button.
panel.getInventory().setItem(slot, this.createChallengeButton(challenge).getItem());
}
else
{
this.selectedChallenges.add(challenge);
this.consumer.accept(true, this.selectedChallenges);
}
return true;
}).
glow(this.selectedChallenges.contains(challenge)).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean, Set<Challenge>> consumer;
/**
* User who runs GUI.
*/
private User user;
/**
* Current value.
*/
private List<Challenge> challengesList;
/**
* Selected challenges that will be returned to consumer.
*/
private Set<Challenge> selectedChallenges;
/**
* Map that contains all challenge descriptions
*/
private Map<Challenge, List<String>> challengesDescriptionMap;
/**
* This variable stores how large line can be, before warp it.
*/
private int lineLength;
}

View File

@ -1,237 +0,0 @@
package world.bentobox.challenges.panel.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This GUI allows to select single entity and return it via Consumer.
*/
public class SelectEntityGUI
{
public SelectEntityGUI(User user, BiConsumer<Boolean, Set<EntityType>> consumer)
{
this(user, Collections.emptySet(), true, consumer);
}
public SelectEntityGUI(User user, Set<EntityType> excludedEntities, boolean asEggs, BiConsumer<Boolean, Set<EntityType>> consumer)
{
this.consumer = consumer;
this.user = user;
this.asEggs = asEggs;
this.entities = new ArrayList<>(EntityType.values().length);
this.selectedEntities = new HashSet<>(EntityType.values().length);
for (EntityType entityType : EntityType.values())
{
if (entityType.isAlive() && !excludedEntities.contains(entityType))
{
this.entities.add(entityType);
}
}
// Sort mobs by their name for easier search.
this.entities.sort(Comparator.comparing(Enum::name));
this.build(0);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds
*/
private void build(int pageIndex)
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.title.admin.select-entity"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
// Maximal elements in page.
final int MAX_ELEMENTS = 21;
final int correctPage;
if (pageIndex < 0)
{
correctPage = this.entities.size() / MAX_ELEMENTS;
}
else if (pageIndex > (this.entities.size() / MAX_ELEMENTS))
{
correctPage = 0;
}
else
{
correctPage = pageIndex;
}
panelBuilder.item(3,
new PanelItemBuilder().
icon(Material.RED_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.admin.cancel")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
List<String> description = new ArrayList<>();
if (!this.selectedEntities.isEmpty())
{
description.add(this.user.getTranslation("challenges.gui.descriptions.admin.selected") + ":");
this.selectedEntities.forEach(entity -> description.add(" - " + entity.name()));
}
panelBuilder.item(5,
new PanelItemBuilder().
icon(Material.GREEN_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.admin.accept")).
description(description).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(true, this.selectedEntities);
return true;
}).build());
if (this.entities.size() > MAX_ELEMENTS)
{
// Navigation buttons if necessary
panelBuilder.item(18,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage - 1);
return true;
}).build());
panelBuilder.item(26,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage + 1);
return true;
}).build());
}
int entitiesIndex = MAX_ELEMENTS * correctPage;
// I want first row to be only for navigation and return button.
int slot = 10;
while (entitiesIndex < ((correctPage + 1) * MAX_ELEMENTS) &&
entitiesIndex < this.entities.size() &&
slot < 36)
{
if (!panelBuilder.slotOccupied(slot))
{
panelBuilder.item(slot,
this.createEntityButton(this.entities.get(entitiesIndex++)));
}
slot++;
}
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, i) -> {
this.consumer.accept(false, null);
return true;
}).build());
panelBuilder.build();
}
/**
* This method builds PanelItem for given entity.
* @param entity Entity which PanelItem must be created.
* @return new PanelItem for given Entity.
*/
private PanelItem createEntityButton(EntityType entity)
{
ItemStack itemStack = this.asEggs ? GuiUtils.getEntityEgg(entity) : GuiUtils.getEntityHead(entity);
return new PanelItemBuilder().
name(WordUtils.capitalize(entity.name().toLowerCase().replace("_", " "))).
icon(itemStack).
description(this.selectedEntities.contains(entity) ?
this.user.getTranslation("challenges.gui.descriptions.admin.selected") : "").
clickHandler((panel, user1, clickType, slot) -> {
if (clickType.isRightClick())
{
if (!this.selectedEntities.add(entity))
{
this.selectedEntities.remove(entity);
}
panel.getInventory().setItem(slot, this.createEntityButton(entity).getItem());
}
else
{
this.selectedEntities.add(entity);
this.consumer.accept(true, this.selectedEntities);
}
return true;
}).
glow(this.selectedEntities.contains(entity)).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean, Set<EntityType>> consumer;
/**
* Set that contains selected entities.
*/
private Set<EntityType> selectedEntities;
/**
* User who runs GUI.
*/
private User user;
/**
* This variable stores if mobs must be displayed as Eggs "true" or Heads "false".
*/
private boolean asEggs;
/**
* Entities that must be in list.
*/
private List<EntityType> entities;
}

View File

@ -1,148 +0,0 @@
package world.bentobox.challenges.panel.util;
import java.util.Collections;
import java.util.Set;
import java.util.function.BiConsumer;
import org.bukkit.Material;
import org.bukkit.World;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class creates panel that allows to select and deselect World Environments. On save it runs
* input consumer with true and selected values.
*/
public class SelectEnvironmentGUI
{
public SelectEnvironmentGUI(User user, Set<World.Environment> values, BiConsumer<Boolean, Set<World.Environment>> consumer)
{
this.user = user;
this.values = values;
this.consumer = consumer;
this.build();
}
/**
* This method builds environment select panel.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.title.admin.toggle-environment"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
panelBuilder.item(3, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.buttons.admin.save")).
icon(Material.GREEN_STAINED_GLASS_PANE).
clickHandler((panel, user1, clickType, index) -> {
this.consumer.accept(true, this.values);
return true;
}).
build());
panelBuilder.item(5, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.buttons.admin.cancel")).
icon(Material.RED_STAINED_GLASS_PANE).
clickHandler((panel, user1, clickType, i) -> {
this.consumer.accept(false, Collections.emptySet());
return true;
}).
build());
panelBuilder.item(20, new PanelItemBuilder().
name(World.Environment.NETHER.name()).
icon(Material.NETHERRACK).
clickHandler((panel, user1, clickType, i) -> {
if (this.values.contains(World.Environment.NETHER))
{
this.values.remove(World.Environment.NETHER);
}
else
{
this.values.add(World.Environment.NETHER);
}
this.build();
return true;
}).
glow(this.values.contains(World.Environment.NETHER)).
build());
panelBuilder.item(22, new PanelItemBuilder().
name(World.Environment.NORMAL.name()).
icon(Material.DIRT).
clickHandler((panel, user1, clickType, i) -> {
if (this.values.contains(World.Environment.NORMAL))
{
this.values.remove(World.Environment.NORMAL);
}
else
{
this.values.add(World.Environment.NORMAL);
}
this.build();
return true;
}).
glow(this.values.contains(World.Environment.NORMAL)).
build());
panelBuilder.item(24, new PanelItemBuilder().
name(World.Environment.THE_END.name()).
icon(Material.END_STONE).
clickHandler((panel, user1, clickType, i) -> {
if (this.values.contains(World.Environment.THE_END))
{
this.values.remove(World.Environment.THE_END);
}
else
{
this.values.add(World.Environment.THE_END);
}
this.build();
return true;
}).
glow(this.values.contains(World.Environment.THE_END)).
build());
panelBuilder.item(44, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.buttons.return")).
icon(Material.OAK_DOOR).
clickHandler((panel, user1, clickType, i) -> {
this.consumer.accept(false, Collections.emptySet());
return true;
}).
build());
panelBuilder.build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* User who wants to run command.
*/
private User user;
/**
* List with selected environments.
*/
private Set<World.Environment> values;
/**
* Stores current Consumer
*/
private BiConsumer<Boolean, Set<World.Environment>> consumer;
}

View File

@ -1,168 +0,0 @@
package world.bentobox.challenges.panel.util;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.function.BiConsumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class contains all necessary things that allows to select single statistic. Selected
* stats will be returned via BiConsumer.
*/
public class SelectStatisticGUI
{
public SelectStatisticGUI(User user, BiConsumer<Boolean, Statistic> consumer)
{
this.consumer = consumer;
this.user = user;
this.elements = new ArrayList<>();
this.elements.addAll(Arrays.asList(Statistic.values()));
this.build(0);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
public void build(int pageIndex)
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation("challenges.gui.title.admin.select-statistic"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
final int MAX_ELEMENTS = 21;
final int correctPage;
if (pageIndex < 0)
{
correctPage = this.elements.size() / MAX_ELEMENTS;
}
else if (pageIndex > (this.elements.size() / MAX_ELEMENTS))
{
correctPage = 0;
}
else
{
correctPage = pageIndex;
}
int entitiesIndex = MAX_ELEMENTS * correctPage;
// I want first row to be only for navigation and return button.
int index = 10;
while (entitiesIndex < ((correctPage + 1) * MAX_ELEMENTS) &&
entitiesIndex < this.elements.size())
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createStatisticButton(this.elements.get(entitiesIndex++)));
}
index++;
}
panelBuilder.item(3,
new PanelItemBuilder().
icon(Material.RED_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.admin.cancel")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
if (this.elements.size() > MAX_ELEMENTS)
{
// Navigation buttons if necessary
panelBuilder.item(18,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage - 1);
return true;
}).build());
panelBuilder.item(26,
new PanelItemBuilder().
icon(Material.OAK_SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage + 1);
return true;
}).build());
}
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
panelBuilder.build();
}
/**
* This method creates PanelItem that represents given statistic.
* Some materials is not displayable in Inventory GUI, so they are replaced with "placeholder" items.
* @param statistic Material which icon must be created.
* @return PanelItem that represents given statistic.
*/
private PanelItem createStatisticButton(Statistic statistic)
{
ItemStack itemStack = new ItemStack(Material.PAPER);
return new PanelItemBuilder().
name(WordUtils.capitalize(statistic.name().toLowerCase().replace("_", " "))).
icon(itemStack).
clickHandler((panel, user1, clickType, slot) -> {
this.consumer.accept(true, statistic);
return true;
}).
glow(false).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private List<Statistic> elements;
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean,Statistic> consumer;
/**
* User who runs GUI.
*/
private User user;
}

View File

@ -0,0 +1,207 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.Constants;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.Utils;
/**
* This class contains all necessary things that allows to select single block from all ingame blocks. Selected
* block will be returned via BiConsumer.
*/
public class SingleBlockSelector extends PagedSelector<Material>
{
private SingleBlockSelector(User user, Mode mode, Set<Material> excluded, BiConsumer<Boolean, Material> consumer)
{
super(user);
this.consumer = consumer;
// Current GUI cannot display air blocks. It crashes with null-pointer
excluded.add(Material.AIR);
excluded.add(Material.CAVE_AIR);
excluded.add(Material.VOID_AIR);
// Piston head and moving piston is not necessary. useless.
excluded.add(Material.PISTON_HEAD);
excluded.add(Material.MOVING_PISTON);
// Barrier cannot be accessible to user.
excluded.add(Material.BARRIER);
this.elements = Arrays.stream(Material.values()).
filter(material -> !excluded.contains(material)).
filter(material -> {
switch (mode)
{
case BLOCKS -> {
return material.isBlock();
}
case ITEMS -> {
return material.isItem();
}
default -> {
return true;
}
}
}).
collect(Collectors.toList());
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, Mode mode, Set<Material> excluded, BiConsumer<Boolean, Material> consumer)
{
new SingleBlockSelector(user, mode, excluded, consumer).build();
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, BiConsumer<Boolean, Material> consumer)
{
new SingleBlockSelector(user, Mode.ANY, new HashSet<>(), consumer).build();
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, Mode mode, BiConsumer<Boolean, Material> consumer)
{
new SingleBlockSelector(user, mode, new HashSet<>(), consumer).build();
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user);
panelBuilder.name(this.user.getTranslation(Constants.TITLE + "block-selector"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
this.populateElements(panelBuilder, this.elements);
panelBuilder.item(4, this.createButton());
panelBuilder.build();
}
/**
* This method creates PanelItem button of requested type.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton()
{
final String reference = Constants.BUTTON + "cancel.";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon = new ItemStack(Material.IRON_DOOR);
PanelItem.ClickHandler clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(false, null);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
/**
* This method creates button for given material.
* @param material material which button must be created.
* @return new Button for material.
*/
@Override
protected PanelItem createElementButton(Material material)
{
final String reference = Constants.BUTTON + "material.";
List<String> description = new ArrayList<>();
description.add(this.user.getTranslation(reference + "description",
"[id]", material.name()));
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-choose"));
return new PanelItemBuilder().
name(this.user.getTranslation(reference + "name", "[material]",
Utils.prettifyObject(material, this.user))).
icon(GuiUtils.getMaterialItem(material)).
description(description).
clickHandler((panel, user1, clickType, slot) -> {
this.consumer.accept(true, material);
return true;
}).
build();
}
// ---------------------------------------------------------------------
// Section: Mode
// ---------------------------------------------------------------------
public enum Mode
{
BLOCKS,
ITEMS,
ANY
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private final List<Material> elements;
/**
* This variable stores consumer.
*/
private final BiConsumer<Boolean, Material> consumer;
}

View File

@ -0,0 +1,207 @@
package world.bentobox.challenges.panel.util;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.Constants;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.Utils;
/**
* This GUI allows to select single entity and return it via Consumer.
*/
public class SingleEntitySelector extends PagedSelector<EntityType>
{
/**
* Instantiates a new Single entity selector.
*
* @param user the user
* @param asEggs the boolean
* @param mode the mode
* @param excluded the excluded
* @param consumer the consumer
*/
private SingleEntitySelector(User user, boolean asEggs, Mode mode, Set<EntityType> excluded, BiConsumer<Boolean, EntityType> consumer)
{
super(user);
this.consumer = consumer;
this.asEggs = asEggs;
this.elements = Arrays.stream(EntityType.values()).
filter(entity -> !excluded.contains(entity)).
filter(entity -> {
if (mode == Mode.ALIVE)
{
return entity.isAlive();
}
else
{
return true;
}
}).
collect(Collectors.toList());
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, boolean asEggs, Mode mode, Set<EntityType> excluded, BiConsumer<Boolean, EntityType> consumer)
{
new SingleEntitySelector(user, asEggs, mode, excluded, consumer).build();
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, boolean asEggs, BiConsumer<Boolean, EntityType> consumer)
{
new SingleEntitySelector(user, asEggs, Mode.ANY, new HashSet<>(), consumer).build();
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, boolean asEggs, Mode mode, BiConsumer<Boolean, EntityType> consumer)
{
new SingleEntitySelector(user, asEggs, mode, new HashSet<>(), consumer).build();
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds
*/
@Override
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user);
panelBuilder.name(this.user.getTranslation(Constants.TITLE + "entity-selector"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
this.populateElements(panelBuilder, this.elements);
panelBuilder.item(4, this.createButton());
panelBuilder.build();
}
/**
* This method builds PanelItem for given entity.
* @param entity Entity which PanelItem must be created.
* @return new PanelItem for given Entity.
*/
@Override
protected PanelItem createElementButton(EntityType entity)
{
final String reference = Constants.BUTTON + "entity.";
List<String> description = new ArrayList<>();
description.add(this.user.getTranslation(reference + "description",
"[id]", entity.name()));
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-choose"));
return new PanelItemBuilder().
name(this.user.getTranslation(reference + "name", "[entity]",
Utils.prettifyObject(entity, this.user))).
icon(this.asEggs ? GuiUtils.getEntityEgg(entity) : GuiUtils.getEntityHead(entity)).
description(description).
clickHandler((panel, user1, clickType, slot) -> {
this.consumer.accept(true, entity);
return true;
}).
build();
}
/**
* This method creates PanelItem button of requested type.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton()
{
final String reference = Constants.BUTTON + "cancel.";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon = new ItemStack(Material.IRON_DOOR);
PanelItem.ClickHandler clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(false, null);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
// ---------------------------------------------------------------------
// Section: Mode
// ---------------------------------------------------------------------
public enum Mode
{
ALIVE,
ANY
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private final List<EntityType> elements;
/**
* Indicates if entities are displayed as eggs or heads.
*/
private final boolean asEggs;
/**
* This variable stores consumer.
*/
private final BiConsumer<Boolean, EntityType> consumer;
}

View File

@ -0,0 +1,159 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.Constants;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.Utils;
/**
* This class contains all necessary things that allows to select single statistic. Selected
* stats will be returned via BiConsumer.
*/
public class StatisticSelector extends PagedSelector<Statistic>
{
/**
* Instantiates a new Statistic selector.
*
* @param user the user
* @param consumer the consumer
*/
private StatisticSelector(User user, BiConsumer<Boolean, Statistic> consumer)
{
super(user);
this.consumer = consumer;
this.elements = new ArrayList<>(Arrays.asList(Statistic.values()));
this.elements.sort(Comparator.comparing(Statistic::name));
}
/**
* This method opens GUI that allows to select challenge type.
*
* @param user User who opens GUI.
* @param consumer Consumer that allows to get clicked type.
*/
public static void open(User user, BiConsumer<Boolean, Statistic> consumer)
{
new StatisticSelector(user, consumer).build();
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user);
panelBuilder.name(this.user.getTranslation(Constants.TITLE + "statistic-selector"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
this.populateElements(panelBuilder, this.elements);
panelBuilder.item(4, this.createButton());
panelBuilder.build();
}
/**
* This method creates PanelItem that represents given statistic.
* Some materials is not displayable in Inventory GUI, so they are replaced with "placeholder" items.
* @param statistic Material which icon must be created.
* @return PanelItem that represents given statistic.
*/
@Override
protected PanelItem createElementButton(Statistic statistic)
{
final String reference = Constants.BUTTON + "statistic_element.";
List<String> description = new ArrayList<>();
String descriptionText = this.user.getTranslationOrNothing(reference + description,
"[description]", Utils.prettifyDescription(statistic, user));
if (!descriptionText.isEmpty())
{
description.add(descriptionText);
}
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-choose"));
return new PanelItemBuilder().
name(this.user.getTranslation(reference + "name", "[statistic]",
Utils.prettifyObject(statistic, this.user))).
icon(Material.PAPER).
description(description).
clickHandler((panel, user1, clickType, slot) -> {
this.consumer.accept(true, statistic);
return true;
}).
build();
}
/**
* This method creates PanelItem button of requested type.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton()
{
final String reference = Constants.BUTTON + "cancel.";
final String name = this.user.getTranslation(reference + "name");
final List<String> description = new ArrayList<>(3);
description.add(this.user.getTranslation(reference + "description"));
ItemStack icon = new ItemStack(Material.IRON_DOOR);
PanelItem.ClickHandler clickHandler = (panel, user1, clickType, slot) ->
{
this.consumer.accept(false, null);
return true;
};
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel"));
return new PanelItemBuilder().
icon(icon).
name(name).
description(description).
clickHandler(clickHandler).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private final List<Statistic> elements;
/**
* This variable stores consumer.
*/
private final BiConsumer<Boolean, Statistic> consumer;
}