cc-mek-scada/graphics/elements/controls/hazard_button.lua

207 lines
5.9 KiB
Lua
Raw Normal View History

-- Hazard-bordered Button Graphics Element
2022-06-16 16:17:41 +00:00
local tcd = require("scada-common.tcd")
2022-06-16 16:17:41 +00:00
local core = require("graphics.core")
local element = require("graphics.element")
2022-10-07 14:28:46 +00:00
---@class hazard_button_args
---@field text string text to show on button
---@field accent color accent color for hazard border
---@field dis_colors? cpair text color and border color when disabled
2022-06-16 16:17:41 +00:00
---@field callback function function to call on touch
---@field parent graphics_element
---@field id? string element id
2022-06-16 16:17:41 +00:00
---@field x? integer 1 if omitted
2023-07-10 03:42:44 +00:00
---@field y? integer auto incremented if omitted
2022-07-16 17:25:07 +00:00
---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw
2022-06-16 16:17:41 +00:00
2022-10-07 14:28:46 +00:00
-- new hazard button
---@param args hazard_button_args
---@return graphics_element element, element_id id
2022-10-07 14:28:46 +00:00
local function hazard_button(args)
2023-09-30 15:46:47 +00:00
element.assert(type(args.text) == "string", "text is a required field")
element.assert(type(args.accent) == "number", "accent is a required field")
element.assert(type(args.callback) == "function", "callback is a required field")
2022-06-16 16:17:41 +00:00
args.height = 3
args.width = string.len(args.text) + 4
2022-06-16 16:17:41 +00:00
-- create new graphics element base object
local e = element.new(args)
-- draw border
---@param accent color accent color
local function draw_border(accent)
-- top
2023-08-31 01:11:57 +00:00
e.w_set_fgd(accent)
e.w_set_bkg(args.fg_bg.bkg)
e.w_set_cur(1, 1)
e.w_write("\x99" .. string.rep("\x89", args.width - 2) .. "\x99")
-- center left
2023-08-31 01:11:57 +00:00
e.w_set_cur(1, 2)
e.w_set_fgd(args.fg_bg.bkg)
e.w_set_bkg(accent)
e.w_write("\x99")
-- center right
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.fg_bg.bkg)
e.w_set_bkg(accent)
e.w_set_cur(args.width, 2)
e.w_write("\x99")
-- bottom
2023-08-31 01:11:57 +00:00
e.w_set_fgd(accent)
e.w_set_bkg(args.fg_bg.bkg)
e.w_set_cur(1, 3)
e.w_write("\x99" .. string.rep("\x98", args.width - 2) .. "\x99")
end
2022-06-16 16:17:41 +00:00
-- on request timeout: recursively calls itself to double flash button text
---@param n integer call count
local function on_timeout(n)
-- start at 0
if n == nil then n = 0 end
if n == 0 then
-- go back off
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.fg_bg.fgd)
e.w_set_cur(3, 2)
e.w_write(args.text)
end
if n >= 4 then
-- done
elseif n % 2 == 0 then
-- toggle text color on after 0.25 seconds
tcd.dispatch(0.25, function ()
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.accent)
e.w_set_cur(3, 2)
e.w_write(args.text)
on_timeout(n + 1)
on_timeout(n + 1)
end)
elseif n % 1 then
-- toggle text color off after 0.25 seconds
tcd.dispatch(0.25, function ()
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.fg_bg.fgd)
e.w_set_cur(3, 2)
e.w_write(args.text)
on_timeout(n + 1)
end)
end
end
-- blink routine for success indication
local function on_success()
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.fg_bg.fgd)
e.w_set_cur(3, 2)
e.w_write(args.text)
end
-- blink routine for failure indication
---@param n integer call count
local function on_failure(n)
-- start at 0
if n == nil then n = 0 end
if n == 0 then
-- go back off
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.fg_bg.fgd)
e.w_set_cur(3, 2)
e.w_write(args.text)
end
if n >= 2 then
-- done
elseif n % 2 == 0 then
-- toggle text color on after 0.5 seconds
tcd.dispatch(0.5, function ()
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.accent)
e.w_set_cur(3, 2)
e.w_write(args.text)
on_failure(n + 1)
end)
elseif n % 1 then
-- toggle text color off after 0.25 seconds
tcd.dispatch(0.25, function ()
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.fg_bg.fgd)
e.w_set_cur(3, 2)
e.w_write(args.text)
on_failure(n + 1)
end)
end
end
-- handle mouse interaction
---@param event mouse_interaction mouse event
function e.handle_mouse(event)
if e.enabled then
if core.events.was_clicked(event.type) then
-- change text color to indicate clicked
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.accent)
e.w_set_cur(3, 2)
e.w_write(args.text)
-- abort any other callbacks
tcd.abort(on_timeout)
tcd.abort(on_success)
tcd.abort(on_failure)
-- 1.5 second timeout
tcd.dispatch(1.5, on_timeout)
args.callback()
end
end
end
-- callback on request response
---@param result boolean true for success, false for failure
function e.response_callback(result)
tcd.abort(on_timeout)
if result then on_success() else on_failure(0) end
2022-06-16 16:17:41 +00:00
end
-- set the value (true simulates pressing the button)
---@param val boolean new value
function e.set_value(val)
if val then e.handle_mouse(core.events.mouse_generic(core.events.MOUSE_CLICK.UP, 1, 1)) end
end
-- show the button as disabled
function e.on_disabled()
if args.dis_colors then
draw_border(args.dis_colors.color_a)
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.dis_colors.color_b)
e.w_set_cur(3, 2)
e.w_write(args.text)
end
end
-- show the button as enabled
function e.on_enabled()
draw_border(args.accent)
2023-08-31 01:11:57 +00:00
e.w_set_fgd(args.fg_bg.fgd)
e.w_set_cur(3, 2)
e.w_write(args.text)
end
-- element redraw
function e.redraw()
-- write the button text and draw border
e.w_set_cur(3, 2)
e.w_write(args.text)
draw_border(args.accent)
end
-- initial draw
e.redraw()
2022-10-20 17:53:39 +00:00
return e.complete()
2022-06-16 16:17:41 +00:00
end
2022-10-07 14:28:46 +00:00
return hazard_button