Shiroi Framework UI Wiki

Feb 26, 2017
Shiroi Framework UI Wiki
  • Shiroi Framework UI Wiki

    How to use the UI module of the Shiroi Framework


    HALLO THERE!
    If you where looking for the Shiroi Framework UI Wiki, congrats, you've found it!
    But if you weren't... What the hell are you doing here?
    NONONO WAIT, Don't go away!
    It's- ... I- It's not like I'm ha- happy that you're here or anything! J- JUST FORGET IT!
    Let's get down to the real business! You want to learn, so let's do this shit! I'm your weeb senpai: DDevil-Senpai, and you'll be in my care for now!
    Now, get your ass on my unicorn and let's go on an adventure!
    (Btw, yes, this page is filled with memes, and yes, it isn't a very "serious" page, but I did do my best to try to explain it in a way you wouldn't get bored while you cringe at me, so yeah, hope it helps)
    [​IMG]

    Repositories(top)

    The framework is hosted @
    Here is a gradle and maven build thingy for the lazy ones like me:

    Gradle(top)

    Code (Text):

    repositories {
        mavenCentral()
        maven { url 'http://dev.dcgo.me:8081/repository/maven-snapshots/' }
    }

    dependencies {
        compile group: 'me.ddevil', name: 'shiroi-framework-ui', version: '3.0.0-SNAPSHOT';
    }
     

    Maven(top)

    Code (Text):
    <repositories>
       <repository>
           <id>ddevil-repo</id>
           <url>http://dev.dcgo.me:8081/repository/maven-snapshots/</url>
       </repository>
    </repositories>
    <dependencies>
       <dependency>
               <groupId>me.ddevil</groupId>
               <artifactId>shiroi-framework-ui</artifactId>
               <version>2.1.0-SNAPSHOT</version>
               <scope>provided</scope>
       </dependency>
    </dependencies>

    Basic concepts(top)

    UIPosition(top)

    An UIPosition basically represents a point in a menu (Minecraft Inventory), It works like an Cartesian plane, except that the Y index is inverted, we'll talk about that later.
    [​IMG]
    Hmm? Why is the Y axis inverted? That is due to the way minecraft works, which we'll talk about now

    Minecraft Slots(top)

    But, you probably know that, minecraft inventories doesn't really work this way. The way they work is, actually each slot has a number which acts as it's index. So in the end it looks as something like this:[​IMG]
    This means that slot n°52, is actually UIPosition(7,6). Slot n°13 is UIPosition(5,1) and so on.

    Basic Objects(top)

    For starters, we'll go around on basic objects. They are the base concepts of how the framework behaves.

    UIObjects(top)

    Code (Java):

    package me.ddevil.shiroi.ui.api.component

    /**
    * The base class for every single object in an UI hierarchy, every UI element extends this.
    */

    interface Component {

        /**
         * The unique identifier for the object, used to find specific objects in a hierarchy.
         * There must NOT have two object with the same id in the same hierarchy.
         */

        var id: String?

        /**
         * Called before the component or parent is re-drawn, "rendered", etc.
         */

        fun update()

    }

    This is the base class of every single UI element. It doesn't do much on itself, it just basically has an update() function.
    The update() function is one of most important methods in this framework. This is what you'll use to update every single object in your UI. It gets called everytime something changes in the menu that holds said object.

    You've probably noticed that there is no UIPosition in the Component interface, why is that?
    Every UIObject MUST be able to be placed anywhere in the menu as long as it fits there.
    Oooo ho hooo! That's where you are wrong my friend! Have you ever heard of...
    ~Dramatic pause~
    Area Objects?
    [​IMG]

    AreaObjects(top)

    Not every single object needs to be 1x1 sized, you can actually make object that contains more than one slots! And that my friends, is an AreaObject (A.O.)
    Code (Java):

    /**
    * Represents an {@link UIObject} that can hold more than one minecraft slots inside a menu.
    */

    public interface AreaObject<P extends Holder> extends Holdable<P> {
        /**
         * Redefines the area to fit the desired sizes.
         *
         * @param width The new width
         * @param height The new height
         */

        void redefineArea(int width, int height);

        /**
         * @return A set sorted by the minecraft slot position with all the UIPositions contained by this object.
         */

        SortedSet<UIPosition> getArea();

        /**
         * Checks if the given position is within the relative area of this object.
         *
         * @param position The position to check
         * @return true if the given position is within bounds, false otherwise.
         */

        boolean contains(UIPosition position);

        /**
         * @return The total number of slots that this object contains.
         */

        int getSize();

        /**
         * @return The maximum relative X of this object
         */

        int getMaxX();

        /**
         * @return The maximum relative Y of this object
         */

        int getMaxY();

        /**
         * @return The width of the object
         */

        int getWidth();

        /**
         * @return The height of the object
         */

        int getHeight();
    }
     
    How do they work? It's actually really simple. A.O.s have two very important properties: Width, and Height. These two properties are the ones who will define the actual area that your object will occupy.
    That's also really simple my little kouhai-kun, the slot that you will that into consideration while placing the A.O. is the SLOT CLOSEST TO THE TOP-LEFT! Take a look at picture below to have an idea of how this actually looks like.

    [​IMG]
    That my friend, is possible because an AreaObject is Drawable!

    Drawables(top)

    Finally we get to display something to our players! Are you excited yet?
    Except we don't, we need to learn something else before.
    I totally feel like Blizzard rn, delaying the cool part that everyone wants until they are sick and tired with it,
    Right Blizzard?
    RIGHT BLIZZARD!?

    wr9RdWnDqW4gZXMgJ0REZXZpbF8nPw==

    Position Relativity(top)

    Before we actually start talking about drawables, we need to understald Position Relativity first.
    Oooh don't be my poor kouhai-kun, I promised I won't brainfuck you... A lot...

    What does this pretty name means? Basically, it means that when you draw something, you draw it "relative to itself".
    This means that when a Drawable draws itself, it "ignores" it's own UIPosition and draw what it should look like relative to itself, take a look at this picture and you might understand it:
    [​IMG]
    The brown object is our AreaObject, it is placed in position x=1, y=0, the golden block displayed in purple is one of the objects that will be drawn.
    Relative to the AreaObject, it's position is x=1, y=2. And that's how drawables should be drawn!
    Btw, that object was an LowPannedScrollable, but we'll talk about that later
    Maybe you are giving me a face like this right now:
    [​IMG]
    But don't worry, practice, and you'll get the hang of it in no time.
    Now back to the drawables
    Code (Java):
    /**
    * Represents an object that can be displayed with ItemStacks in a menu
    */

    public interface Drawable extends UIObject {
        /**
         * <b>This is one of the most important functions in this framework. DON'T SCREW IT UP!</b>
         * The drawUI function must return a map that shows where every item should be displayed relatively to itself.
         * For example, a drawable that only contains one slots should return a singleton map where the position points to (0,0).
         *
         * @return The map that will be used to display this object in the menu.
         */

        Map<UIPosition, ItemStack> drawUI();

    }
     
    Well, I guess the javadoc explained pretty much it.
    Let's use the golden block example again.
    What is going to happen when the menu drawns the AreaObject is:
    The AreaObject is placed in position x=1, y=0.
    The GoldenBlock is placed in relative position x=1, y=2
    x = 1 + 1 = 2
    y = 0 + 2 = 2
    The GoldenBlock is drawn at position x=2, y=2.
    Simple isn't it?
    Oooh, that isn't an object actually, in fact, we are going to talk about that now.

    Backgroundables(top)

    Code (Java):
    /**
    * Represents an object that can contain a background.
    */

    public interface Backgroundable extends Drawable {
        /**
         * Sets the given item as the background
         *
         * @param background The background item to be set
         */

        void setBackground(ItemStack background);

        /**
         * @return The item that represents the background
         */

        ItemStack getBackground();

        /**
         * @return true if there is a background set.
         */

        default boolean hasBackground() {
            return getBackground() != null;
        }
    }
    Backgroundables are really simple, they just have... A background
    [​IMG]
    Yeeee boi...
    There is not too much to talk about them, basically everything you need to know is that the background should be put in the drawUI() map.
    Precisely right now you impatient fuck! :D

    Clickables(top)

    Code (Java):

    /**
    * Represents an object that performs an action when clicked;
    */

    public interface Clickable extends UIObject {
        /**
         * This function is mainly used by menus to handle clicks.
         * I don't really see why you would really use it in another
         * case and don't really recommend it, but if you want to, go ahead.
         * As longs as you don't bother me with errors about it is fine :D
         *
         * @return The action to be performed when clicked
         */

        Action getAction();

        /**
         * Sets the action to be performed when clicked.
         *
         * @param action The action to be set.
         */

        void setAction(Action action);
    }
    Clickables are really simple but really important!
    When an object is clicked inside a menu, the menu checks if the object implements clickable, and if it does, it runs the action of the clickable object.
    That's just it... ye...
    The good news is that we are only one step away from reading about our beloved HOLDERS, but first we need to talk about HOLDABLES

    Holdables(top)

    Code (Text):
    /**
    * A holdable is an {@link UIObject} that can be placed inside a {@link Holder}.
    * Simple right?
    * Everything it needs to do is to keep a reference of the parent to itself.
    *
    * @param <P> The expected type of the parent.
    */
    public interface Holdable<P extends Holder> extends Drawable {
        /**
         * @return The parent (holder) of this object
         */
        P getParent();

        /**
         * Sets the parent reference to the desired holder.
         *
         * @param parent The parent to be set
         */
        void setParent(P parent);

        /**
         * @return True if has a parent and is owned by it.
         */
        boolean isPlaced();
    }
     
    Holdables are really simple as well, they must be drawables, and must keep an reference of the parent to itself.
    Holders only accept objects that implement Holdables.

    Now, the time has come, for we to read about the cool kids... I'm talking about the Holders!

    Holders(top)

    So, holders are basically "parent" objects, their purpose is to hold holdables
    [​IMG]
    I know, unbeliaveble right? I'll type it again in a fancier font just so you can believe me.
    Goddammit Spigot! I had to make an image because you didn't have a prettier font!
    So, before I explode your brain with more totally not obvious shit, allow me to explain the interface
    Code (Java):

    /**
    * Represents an object that can hold {@link Holdable}s, like menus and containers.
    */

    public interface Holder<H extends Holdable<?>> extends Clickable, Backgroundable, Drawable {
        /**
         * Adds the given holdable in the first available slot it finds.
         *
         * @param holdable The holdable to add.
         */

        void add(H holdable);

        /**
         * Removes every single holdable that this holder contains
         */

        void clear();

        /**
         * Checks if the given object is contained within this holder.
         *
         * @param obj The object to check
         * @return True if this holder contains the given object, false otherwise.
         */

        boolean isOwnerOf(H obj);

        /**
         * @return Every holdable that is contained in this holder.
         */

        List<H> getAllHoldables();

    }
     
    Actually, fuck this shit, I'll finish it later.

    Containers(top)

    Menus(top)

    Scrollables(top)

    Scrollers(top)

    PanedScrollables(top)

    UnpanedScrollables(top)

  • Loading...
  • Loading...