WolfyScript / viewportl

A Minecraft Inventory GUI framework, designed to easily create reactive GUIs. Based on the well known Signal Reactivity System.
GNU General Public License v3.0
68 stars 12 forks source link

KyoriPowered/adventure implementation & migration #71

Closed WolfyScript closed 2 years ago

WolfyScript commented 2 years ago

Migration away from the legacy colour format, that is the § (& for input in MC), is long overdue. In order to make it happen, this update completely overhauls the chat message system and uses Adventure to make it easier to create and send chat components (with click actions, hover events, etc.).

Abstracted the Chat handler to hide the code implementation and provide a better overview of the methods.

Deprecated Classes

Various legacy methods in Chat [here]

The methods, that send messages using the legacy format, convert the messages to the new format for backwards compatibility. You should update to the new methods! You can find recommended methods to migrate to in the Javadoc of the deprecated methods.

JsonConfig [here]

This utility class has been deprecated, and it should no longer be used. Its use case is very narrow and Jackson POJO or other methods should be used instead.

PlayerAction [here]

In-case this class is used anywhere outside WolfyUtilities, it should be removed, because it is meant for internal usage only and may be made package private without further notion in the near future.

Button & ButtonState Builder

Previously, you had to use constructors to create buttons. That not only made it ambiguous to find the correct constructor to use, but also difficult to add new features, as those would need additional constructors… That's why this update introduces Builders to easily chain methods and build the desired Button, and it's ButtonState/s.

Get a Button builder instance

The recommended way to get a new Builder instance is via the provided ButtonBuilder in the GuiWindow and GuiCluster https://github.com/WolfyScript/WolfyUtilities/blob/7ca85382a892aa15f08e40f1f5aa8d93dd2f34d7/core/src/main/java/me/wolfyscript/utilities/api/inventory/gui/GuiMenuComponent.java#L87 https://github.com/WolfyScript/WolfyUtilities/blob/7ca85382a892aa15f08e40f1f5aa8d93dd2f34d7/core/src/main/java/me/wolfyscript/utilities/api/inventory/gui/GuiMenuComponent.java#L193

Get a ButtonState builder instance

The button state contains all the information needed to render the button, what to do on an interaction, etc. Some buttons might have multiple states, like the ToggleButton (two states).
The simplest and recommended solution would be to use the dedicated methods of the Button builder and use the state Consumer. https://github.com/WolfyScript/WolfyUtilities/blob/7ca85382a892aa15f08e40f1f5aa8d93dd2f34d7/core/src/main/java/me/wolfyscript/utilities/api/inventory/gui/button/buttons/ActionButton.java#L190 https://github.com/WolfyScript/WolfyUtilities/blob/7ca85382a892aa15f08e40f1f5aa8d93dd2f34d7/core/src/main/java/me/wolfyscript/utilities/api/inventory/gui/button/buttons/ToggleButton.java#L184 https://github.com/WolfyScript/WolfyUtilities/blob/7ca85382a892aa15f08e40f1f5aa8d93dd2f34d7/core/src/main/java/me/wolfyscript/utilities/api/inventory/gui/button/buttons/ToggleButton.java#L189 https://github.com/WolfyScript/WolfyUtilities/blob/7ca85382a892aa15f08e40f1f5aa8d93dd2f34d7/core/src/main/java/me/wolfyscript/utilities/api/inventory/gui/button/buttons/MultipleChoiceButton.java#L179

Example

The easiest way to register a button inside the GuiWindow/GuiCluster onInit():

getButtonBuilder().action("button_id").state(state -> state
                //Set another key (e.g. when you have multiple states) (Default: the button id)
                .key("another_key")
                //Set the icon (Either Material or ItemStack)
                .icon(Material.GRASS_BLOCK)
                //the callback to execute before a button is rendered
                .preRender((cache, guiHandler1, player, inventory, itemStack, slot, helpEnabled) -> {})
                //Manipulate the rendered ItemStack
                .render((values, cache, guiHandler, player, guiInventory, itemStack, slot, help) -> itemStack)
                //Executed when the button was interacted with. Return true to cancel interaction, false to allow the interaction (like picking up the item).
                .action((cache, guiHandler, player, inventory, slot, event) -> true)
                //Cache data or compute other things after the interaction is over.
                .postAction((cache, guiHandler1, player, inventory, itemStack, slot, event) -> {})
        ).register();//All we have to do at the end is to call the button builder register method.

Language

With all those changes to the chat components, it was also time to restructure the LanguageAPI. The languages are all fully loaded using Jackson now (Still extends JsonConfig for backwards compatibility).
In order to improve performance, all Languages that are loaded will read & cache the keys and raw value. Due to placeholders, those raw values still need to be parsed at runtime.

The constructor of the Language class is deprecated and LanguageAPI#loadLangFile should be used instead. To save the language, you can use LanguageAPI#saveLangFile.

Flat Language format

The languages support a flat JSON format now. Flat means that all objects are flattened and reduces the amount of lines of the language file. This flat format doesn't flatten arrays, so arrays are kept as is and the elements are not split into separate properties!

Nested (Default):

{
     "an" : {
         "nested" : {
             "value": 2,
             "array" : [
                 "element",
                 "element1",
                 "element2"
             ]
         }
     }
}

Flat:

{
    "type": "FLAT",
    "an.nested.value": 2,
    "an.nested.array" : [
        "element",
        "element1",
        "element2"
    ]
}

(More info needed)