cc-mek-scada/graphics/elements/textbox.lua
2024-08-25 20:29:52 -04:00

92 lines
2.6 KiB
Lua

-- Text Box Graphics Element
local util = require("scada-common.util")
local core = require("graphics.core")
local element = require("graphics.element")
local ALIGN = core.ALIGN
---@class textbox_args
---@field text string text to show
---@field alignment? ALIGN text alignment, left by default
---@field anchor? boolean true to use this as an anchor, making it focusable
---@field parent graphics_element
---@field id? string element id
---@field x? integer 1 if omitted
---@field y? integer auto incremented if omitted
---@field width? integer parent width if omitted
---@field height? integer minimum necessary height for wrapped text if omitted
---@field gframe? graphics_frame frame instead of x/y/width/height
---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw
-- new text box
---@param args textbox_args
---@return graphics_element element, element_id id
local function textbox(args)
element.assert(type(args.text) == "string", "text is a required field")
if args.anchor == true then args.can_focus = true end
-- provide a constraint condition to element creation to prevent an pointlessly tall text box
---@param frame graphics_frame
local function constrain(frame)
local new_height = math.max(1, #util.strwrap(args.text, frame.w))
if args.height then
new_height = math.max(frame.h, new_height)
end
return frame.w, new_height
end
-- create new graphics element base object
local e = element.new(args, constrain)
e.value = args.text
local alignment = args.alignment or ALIGN.LEFT
-- draw textbox
function e.redraw()
e.window.clear()
local lines = util.strwrap(e.value, e.frame.w)
for i = 1, #lines do
if i > e.frame.h then break end
-- trim leading/trailing whitespace
lines[i] = util.trim(lines[i])
local len = string.len(lines[i])
-- use cursor position to align this line
if alignment == ALIGN.CENTER then
e.w_set_cur(math.floor((e.frame.w - len) / 2) + 1, i)
elseif alignment == ALIGN.RIGHT then
e.w_set_cur((e.frame.w - len) + 1, i)
else
e.w_set_cur(1, i)
end
e.w_write(lines[i])
end
end
-- set the string value and re-draw the text
---@param val string value
function e.set_value(val)
e.value = val
e.redraw()
end
-- initial draw
e.redraw()
return e.complete()
end
return textbox