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.
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.