Skip to content

A modular, backend-agnostic framework for building terminal-based UIs in Lua with flexible layouts and unified event handling.

Notifications You must be signed in to change notification settings

CaptainSly/PlasticUI

Repository files navigation

PlasticUI

PlasticUI is a backend-agnostic, modular retained mode TUI built in Lua. It handles event propagation in a unified way as well as provides a flexible way of creating Layouts.

How to use

To implement PlasticUI inside your project, you must implement a few things. First off, this project utilizes a Lua Class snippet to provide OOP functionality through this file. Then add _G.Class = require("Class") to your main script, you can then add require("PlasticUI.PlasticUI") underneath, and PlasticUI is loaded in your project.

All PlasticUI classes are accessed through the PlasticUI table. PlasticUI also provides a default luadoc for a Color class. It is set as the following: ---@class Color:{r: number, g: number, b: number, a: number}. Though any function in PlasticUI that takes a Color will also take a number as well. Hopefully catching all types of colors systems.

After you add the class snippet and have it hooked up properly, you're going to want to create a new Terminal implementation. The Terminal class is what you'll be providing for Plastic to be able to draw, update and handle events.

The Terminal Interface looks like this:

---@class Terminal:Class
---@field application Application
---@field default_fg_color number|Color
---@field default_bg_color number|Color
---@field fg_color number|Color
---@field bg_color number|Color
---@field clear_terminal fun(self: Terminal):nil
---@field clear_line fun(self: Terminal, ypos: number):nil
---@field get_size fun(self: Terminal):number, number Width, Height (Row, Column)
---@field write fun(self: Terminal, text: string):nil
---@field write_at fun(self: Terminal, text: string, xpos: number, ypos: number, fg_color?: number|Color, bg_color?: number|Color):nil
---@field fill fun(self: Terminal, char: string, xpos: number, ypos: number, width: number, height: number, fg_color?: number|Color, bg_color?: number|Color):nil
---@field draw_vert_line fun(self: Terminal, xpos: number, ypos: number, length: number, fg_color?: number|Color, bg_color?: number|Color):nil
---@field draw_horiz_line fun(self: Terminal, xpos: number, ypos: number, length: number, fg_color?: number|Color, bg_color?: number|Color):nil
---@field draw_box fun(self: Terminal, xpos: number, ypos: number, width: number, height: number, fg_color?: number|Color, bg_color?: number|Color, filled?: boolean):nil
---@field reset_colors fun(self: Terminal):nil
---@field set_default_background_color fun(self: Terminal, bg_color: number):nil
---@field set_default_foreground_color fun(self: Terminal, fg_color: number):nil
---@field set_background_color fun(self: Terminal, bg_color?: number|Color):nil
---@field set_foreground_color fun(self: Terminal, fg_color?: number|Color):nil
---@field set_cursor_pos fun(self: Terminal, xpos: number, ypos: number): nil
---@field get_cursor_pos fun(self: Terminal):number, number xpos, ypos
---@field translate_event fun(self: Terminal, event: table):Event
---@field init fun(self: Terminal)
PlasticUI.Terminal = Class(function(self) end)

A Posix Implementation can be done like such (not a full working implementation)

PosixTerminal = Class(PlasticUI.Terminal, function(self)
    PlasticUI.Terminal.init(self)
    -- Basic Implementation, full impl needs to handle cursor state, colors, etc.,
end)

function PosixTerminal:set_cursor_pos(xpos, ypos)
    io.write("\x1b["..xpos..";"..ypos.."H")
end

PlasticUI doesn't keep track of your cursor position, or the background/foreground color, though does provide you with the ability to do so.

About

A modular, backend-agnostic framework for building terminal-based UIs in Lua with flexible layouts and unified event handling.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages