Configurable menus - Simplix-Softworks/Cirrus GitHub Wiki

Configurable menus

Cirrus enables you to let others decide how the menu should look like. You as the developer are only responsible for creating the logic behind the menu.

AbstractConfigurableMenu

The abstract class dev.simplix.cirrus.common.menu.AbstractConfigurableMenu<T extends MenuConfiguration> is the base class for all configurable menus*. Since AbstractConfigurableMenu extends AbstractMenu you can use the provided replacement {viewer} in the title or item names and descriptions to show the player name of the menu viewer.

To create a configurable single page menu, you just simply create a new menu class that extends AbstractConfigurableMenu<MenuConfiguration>. Example:

public final class ExampleMenu extends AbstractConfigurableMenu<MenuConfiguration> {

  public ExampleMenu(PlayerWrapper player, MenuConfiguration config) {
    super(player, config, Locale.ENGLISH);
  }

}

* MultiPageMenu is not directly extending AbstractConfigurableMenu tho it uses configurations.

MultiPageMenu

Multi page menus are only with the configuration feature available.

public final class ExampleMenu extends MultiPageMenu {

  public ExampleMenu(PlayerWrapper player, MultiPageMenuConfiguration config) {
    super(player, config, Locale.ENGLISH);
  }

}

If you wish to use a MultiPageMenu without creating a configuration file, you can use the empty configuration object:

public final class ExampleMenu extends MultiPageMenu {

  public ExampleMenu(PlayerWrapper player) {
    super(player, new MultiPageMenuConfiguration(), Locale.ENGLISH);
  }

}

Adding items

The multi page menu will automatically create a new page if there is no space left in the last menu page. For adding items you must use the add methods of the MultiPageMenu class.

  
public final class ExampleMultiPageMenu extends MultiPageMenu {  
  
  public ExampleMultiPageMenu(PlayerWrapper player, MultiPageMenuConfiguration configuration) {  
    super(player, configuration, Locale.ENGLISH);  
    registerMyActionHandlers();  
    addItems();  
  }  
  
  private void registerMyActionHandlers() {  
    registerActionHandler("test", click -> {
      player().sendMessage("This is "+click.clickedItem().type().name());  
      return CallResult.DENY_GRABBING;  
    });
  }
  
  private void addItems() {  
    for(ItemType type : ItemType.values()) {  
      if(type.getApplicableMapping(player().protocolVersion()) != null) {  
        add(wrapItemStack(new ItemStack(type)), "test", Collections.emptyList());  
      }
    }
  }
 
}

This example will add every supported item to the menu and will automatically create the needed pages for storing the items.

NOTICE: If you are using the add method of Container, the multi page menu won't create a new page if the container get's full. Please be sure to use the provided add methods of MultiPageMenu.

How the next free slot is determined

As stated in the add method of Container: Sets an item into the next free slot. Free slots are slots where no item has been set and the slot is not marked as reserved. MultiPageMenu respects reserved slots and does not set items by using the add method to reserved slots. In addition: MultiPageMenu also won't set items to the slots where the next and previous page items are located (even if they won't be shown).

Provided replacements (placeholder)

  • {viewer} - The player name of the menu viewer
  • {currentPage} - The page number of the currently opened page
  • {pageCount} - The total amount of pages in this menu

Loading configurations

In order to load configurations from files or resources, you have to gather an instance of ConfigurationFactory. The only way to do so is by using dependency injection.

@Component(MyModule.class)
public final class ConfigurationLoader {

  private final ConfigurationFactory configurationFactory;

  @Inject
  public ConfigurationLoader(ConfigurationFactory configurationFactory) {
    this.configurationLoader = configurationLoader;
  }

  public ExampleMenu createExampleMenu(Player viewer) {
    return new ExampleMenu(Converters.convert(viewer, PlayerWrapper.class), configurationFactory.loadFile("plugins/Example/ExampleMenu.json"));
  }
  
  public ExampleMultiPageMenu createExampleMenu(Player viewer) {
    return new ExampleMultiPageMenu(Converters.convert(viewer, PlayerWrapper.class), configurationFactory.loadFile("plugins/Example/ExampleMultiPageMenu.json", MultiPageMenuConfiguration.class));
  }

}