Thomasims / TeardownUMF

Teardown Unofficial Modding Framework
The Unlicense
37 stars 14 forks source link

UI Library #1

Open Thomasims opened 3 years ago

Thomasims commented 3 years ago

The current UI system in teardown is quite rough and tedious to use, this works well enough for simple UI elements but the code quickly becomes cluttered and complicated. It also makes it nearly impossible to extend existing UI, requiring mods to override entire functions.

The goal of this new library is to address this problem by putting a focus on the structure of UI elements code using shorter syntax with less boilerplate. This new syntax should hopefully make elements more modular and easily extensible.

Example of the new syntax:

local window = TDUI.Window { -- A window with an X button.
    title = "My Window";
    width = 350;
    height = 500;
    align = "center center";
    padding = 10; -- Padding is inside, margin is outside. Can be a number, string, or table of values.

    layout = TDUI.StackLayout { -- Layout of sub elements. List of layouts TBD.
        orientation = "vertical";
    };

    TDUI.Button {
        text = "Do Something";
        padding = 10;
        width = "fit-content"; -- Changes to adapt to its contents, using the parent container as a max size.
        height = "fit-content";

        onclick = function(self) -- A simple callback to an event. List of events TBD.
            print("Pressed button 1")
        end;
    };

    TDUI.Button { -- Properties are inherited from TDUI.Button, so they don't always need to be redefined.
        text = "Something else";
        background = Color(1, 0.3, 0.5);
        color = Color(1, 0.3, 0.5);

        onclick = function(self)
            print("Pressed button 2")
        end;
    };
}

window:Popup() -- :Popup() requests user input focus, pausing the game and freeing the cursor.
-- Panels that don't need to capture the mouse can just call :Show() instead, possibly using :RequestFocus() later.

UI elements using this syntax are inherently extensible, for instance if you wanted to make a special button that was red by default you could do:

-- Putting the result in TDUI.RedButton isn't anything special; TDUI is a regular table and simply makes the new button type easier to access in other files.
TDUI.RedButton = TDUI.Button {
        background = Color(1, 0.2, 0.1);
        color = Color(1, 0.2, 0.1);
}
-- You can now use TDUI.RedButton just like TDUI.Button in the previous example.

As well as providing the root panel UI element that handles all the layout, drawing, and input functions, the library should include a reasonable set of generic elements to cover most use cases.