mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#344 element redraws and shorter assert messages
This commit is contained in:
parent
70831b49d2
commit
ed4180a072
@ -360,6 +360,8 @@ function element.new(args, child_offset_x, child_offset_y)
|
|||||||
---@param result any
|
---@param result any
|
||||||
function protected.response_callback(result) end
|
function protected.response_callback(result) end
|
||||||
|
|
||||||
|
-- accessors and control --
|
||||||
|
|
||||||
-- get value
|
-- get value
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function protected.get_value() return protected.value end
|
function protected.get_value() return protected.value end
|
||||||
@ -387,6 +389,9 @@ function element.new(args, child_offset_x, child_offset_y)
|
|||||||
-- luacheck: pop
|
-- luacheck: pop
|
||||||
---@diagnostic enable: unused-local, unused-vararg
|
---@diagnostic enable: unused-local, unused-vararg
|
||||||
|
|
||||||
|
-- re-draw this element
|
||||||
|
function protected.redraw() end
|
||||||
|
|
||||||
-- start animations
|
-- start animations
|
||||||
function protected.start_anim() end
|
function protected.start_anim() end
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
-- Color Map Graphics Element
|
-- Color Map Graphics Element
|
||||||
|
|
||||||
local util = require("scada-common.util")
|
|
||||||
|
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
|
|
||||||
---@class colormap_args
|
---@class colormap_args
|
||||||
@ -16,7 +14,7 @@ local element = require("graphics.element")
|
|||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function colormap(args)
|
local function colormap(args)
|
||||||
local bkg = "008877FFCCEE114455DD9933BBAA2266"
|
local bkg = "008877FFCCEE114455DD9933BBAA2266"
|
||||||
local spaces = util.spaces(32)
|
local spaces = string.rep(" ", 32)
|
||||||
|
|
||||||
args.width = 32
|
args.width = 32
|
||||||
args.height = 1
|
args.height = 1
|
||||||
@ -25,8 +23,13 @@ local function colormap(args)
|
|||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- draw color map
|
-- draw color map
|
||||||
e.w_set_cur(1, 1)
|
function e.redraw()
|
||||||
e.w_blit(spaces, bkg, bkg)
|
e.w_set_cur(1, 1)
|
||||||
|
e.w_blit(spaces, bkg, bkg)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -24,21 +24,17 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
|
|||||||
---@param args app_button_args
|
---@param args app_button_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function app_button(args)
|
local function app_button(args)
|
||||||
assert(type(args.text) == "string", "graphics.elements.controls.app: text is a required field")
|
assert(type(args.text) == "string", "controls.app: text is a required field")
|
||||||
assert(type(args.title) == "string", "graphics.elements.controls.app: title is a required field")
|
assert(type(args.title) == "string", "controls.app: title is a required field")
|
||||||
assert(type(args.callback) == "function", "graphics.elements.controls.app: callback is a required field")
|
assert(type(args.callback) == "function", "controls.app: callback is a required field")
|
||||||
assert(type(args.app_fg_bg) == "table", "graphics.elements.controls.app: app_fg_bg is a required field")
|
assert(type(args.app_fg_bg) == "table", "controls.app: app_fg_bg is a required field")
|
||||||
|
|
||||||
args.height = 4
|
args.height = 4
|
||||||
args.width = 5
|
args.width = 5
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- write app title, centered
|
|
||||||
e.w_set_cur(math.floor((e.frame.w - string.len(args.title)) / 2) + 1, 4)
|
|
||||||
e.w_write(args.title)
|
|
||||||
|
|
||||||
-- draw the app button
|
-- draw the app button
|
||||||
local function draw()
|
local function draw()
|
||||||
local fgd = args.app_fg_bg.fgd
|
local fgd = args.app_fg_bg.fgd
|
||||||
@ -120,8 +116,18 @@ local function app_button(args)
|
|||||||
if val then e.handle_mouse(core.events.mouse_generic(core.events.MOUSE_CLICK.UP, 1, 1)) end
|
if val then e.handle_mouse(core.events.mouse_generic(core.events.MOUSE_CLICK.UP, 1, 1)) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- element redraw
|
||||||
|
function e.redraw()
|
||||||
|
-- write app title, centered
|
||||||
|
e.w_set_cur(math.floor((e.frame.w - string.len(args.title)) / 2) + 1, 4)
|
||||||
|
e.w_write(args.title)
|
||||||
|
|
||||||
|
-- draw button
|
||||||
|
draw()
|
||||||
|
end
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
draw()
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -18,8 +18,8 @@ local element = require("graphics.element")
|
|||||||
---@param args checkbox_args
|
---@param args checkbox_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function checkbox(args)
|
local function checkbox(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.controls.checkbox: label is a required field")
|
assert(type(args.label) == "string", "controls.checkbox: label is a required field")
|
||||||
assert(type(args.box_fg_bg) == "table", "graphics.elements.controls.checkbox: box_fg_bg is a required field")
|
assert(type(args.box_fg_bg) == "table", "controls.checkbox: box_fg_bg is a required field")
|
||||||
|
|
||||||
args.can_focus = true
|
args.can_focus = true
|
||||||
args.height = 1
|
args.height = 1
|
||||||
@ -105,9 +105,14 @@ local function checkbox(args)
|
|||||||
e.on_enabled = draw_label
|
e.on_enabled = draw_label
|
||||||
e.on_disabled = draw_label
|
e.on_disabled = draw_label
|
||||||
|
|
||||||
|
-- element redraw
|
||||||
|
function e.redraw()
|
||||||
|
draw()
|
||||||
|
draw_label()
|
||||||
|
end
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
draw()
|
e.redraw()
|
||||||
draw_label()
|
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -21,21 +21,16 @@ local element = require("graphics.element")
|
|||||||
---@param args hazard_button_args
|
---@param args hazard_button_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function hazard_button(args)
|
local function hazard_button(args)
|
||||||
assert(type(args.text) == "string", "graphics.elements.controls.hazard_button: text is a required field")
|
assert(type(args.text) == "string", "controls.hazard_button: text is a required field")
|
||||||
assert(type(args.accent) == "number", "graphics.elements.controls.hazard_button: accent is a required field")
|
assert(type(args.accent) == "number", "controls.hazard_button: accent is a required field")
|
||||||
assert(type(args.callback) == "function", "graphics.elements.controls.hazard_button: callback is a required field")
|
assert(type(args.callback) == "function", "controls.hazard_button: callback is a required field")
|
||||||
|
|
||||||
-- static dimensions
|
|
||||||
args.height = 3
|
args.height = 3
|
||||||
args.width = string.len(args.text) + 4
|
args.width = string.len(args.text) + 4
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- write the button text
|
|
||||||
e.w_set_cur(3, 2)
|
|
||||||
e.w_write(args.text)
|
|
||||||
|
|
||||||
-- draw border
|
-- draw border
|
||||||
---@param accent color accent color
|
---@param accent color accent color
|
||||||
local function draw_border(accent)
|
local function draw_border(accent)
|
||||||
@ -158,7 +153,6 @@ local function hazard_button(args)
|
|||||||
-- 1.5 second timeout
|
-- 1.5 second timeout
|
||||||
tcd.dispatch(1.5, on_timeout)
|
tcd.dispatch(1.5, on_timeout)
|
||||||
|
|
||||||
-- call the touch callback
|
|
||||||
args.callback()
|
args.callback()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -195,8 +189,16 @@ local function hazard_button(args)
|
|||||||
e.w_write(args.text)
|
e.w_write(args.text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial draw of border
|
-- element redraw
|
||||||
draw_border(args.accent)
|
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()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -29,13 +29,11 @@ local element = require("graphics.element")
|
|||||||
---@param args multi_button_args
|
---@param args multi_button_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function multi_button(args)
|
local function multi_button(args)
|
||||||
assert(type(args.options) == "table", "graphics.elements.controls.multi_button: options is a required field")
|
assert(type(args.options) == "table", "controls.multi_button: options is a required field")
|
||||||
assert(#args.options > 0, "graphics.elements.controls.multi_button: at least one option is required")
|
assert(#args.options > 0, "controls.multi_button: at least one option is required")
|
||||||
assert(type(args.callback) == "function", "graphics.elements.controls.multi_button: callback is a required field")
|
assert(type(args.callback) == "function", "controls.multi_button: callback is a required field")
|
||||||
assert(type(args.default) == "nil" or (type(args.default) == "number" and args.default > 0),
|
assert(type(args.default) == "nil" or (type(args.default) == "number" and args.default > 0), "controls.multi_button: default must be nil or a number > 0")
|
||||||
"graphics.elements.controls.multi_button: default must be nil or a number > 0")
|
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), "controls.multi_button: min_width must be nil or a number > 0")
|
||||||
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
|
||||||
"graphics.elements.controls.multi_button: min_width must be nil or a number > 0")
|
|
||||||
|
|
||||||
-- single line
|
-- single line
|
||||||
args.height = 1
|
args.height = 1
|
||||||
@ -71,7 +69,7 @@ local function multi_button(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- show the button state
|
-- show the button state
|
||||||
local function draw()
|
function e.redraw()
|
||||||
for i = 1, #args.options do
|
for i = 1, #args.options do
|
||||||
local opt = args.options[i] ---@type button_option
|
local opt = args.options[i] ---@type button_option
|
||||||
|
|
||||||
@ -115,7 +113,7 @@ local function multi_button(args)
|
|||||||
-- tap always has identical coordinates, so this always passes for taps
|
-- tap always has identical coordinates, so this always passes for taps
|
||||||
if button_ini == button_cur and button_cur ~= nil then
|
if button_ini == button_cur and button_cur ~= nil then
|
||||||
e.value = button_cur
|
e.value = button_cur
|
||||||
draw()
|
e.redraw()
|
||||||
args.callback(e.value)
|
args.callback(e.value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -125,11 +123,11 @@ local function multi_button(args)
|
|||||||
---@param val integer new value
|
---@param val integer new value
|
||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
e.value = val
|
e.value = val
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
draw()
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -26,10 +26,9 @@ local KEY_CLICK = core.events.KEY_CLICK
|
|||||||
---@param args push_button_args
|
---@param args push_button_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function push_button(args)
|
local function push_button(args)
|
||||||
assert(type(args.text) == "string", "graphics.elements.controls.push_button: text is a required field")
|
assert(type(args.text) == "string", "controls.push_button: text is a required field")
|
||||||
assert(type(args.callback) == "function", "graphics.elements.controls.push_button: callback is a required field")
|
assert(type(args.callback) == "function", "controls.push_button: callback is a required field")
|
||||||
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), "controls.push_button: min_width must be nil or a number > 0")
|
||||||
"graphics.elements.controls.push_button: min_width must be nil or a number > 0")
|
|
||||||
|
|
||||||
local text_width = string.len(args.text)
|
local text_width = string.len(args.text)
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ local function push_button(args)
|
|||||||
local v_pad = math.floor(e.frame.h / 2) + 1
|
local v_pad = math.floor(e.frame.h / 2) + 1
|
||||||
|
|
||||||
-- draw the button
|
-- draw the button
|
||||||
local function draw()
|
function e.redraw()
|
||||||
e.window.clear()
|
e.window.clear()
|
||||||
|
|
||||||
-- write the button text
|
-- write the button text
|
||||||
@ -60,7 +59,7 @@ local function push_button(args)
|
|||||||
e.value = true
|
e.value = true
|
||||||
e.w_set_fgd(args.active_fg_bg.fgd)
|
e.w_set_fgd(args.active_fg_bg.fgd)
|
||||||
e.w_set_bkg(args.active_fg_bg.bkg)
|
e.w_set_bkg(args.active_fg_bg.bkg)
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -70,7 +69,7 @@ local function push_button(args)
|
|||||||
e.value = false
|
e.value = false
|
||||||
e.w_set_fgd(e.fg_bg.fgd)
|
e.w_set_fgd(e.fg_bg.fgd)
|
||||||
e.w_set_bkg(e.fg_bg.bkg)
|
e.w_set_bkg(e.fg_bg.bkg)
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -117,7 +116,7 @@ local function push_button(args)
|
|||||||
e.value = false
|
e.value = false
|
||||||
e.w_set_fgd(e.fg_bg.fgd)
|
e.w_set_fgd(e.fg_bg.fgd)
|
||||||
e.w_set_bkg(e.fg_bg.bkg)
|
e.w_set_bkg(e.fg_bg.bkg)
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -127,7 +126,7 @@ local function push_button(args)
|
|||||||
e.value = false
|
e.value = false
|
||||||
e.w_set_fgd(args.dis_fg_bg.fgd)
|
e.w_set_fgd(args.dis_fg_bg.fgd)
|
||||||
e.w_set_bkg(args.dis_fg_bg.bkg)
|
e.w_set_bkg(args.dis_fg_bg.bkg)
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -136,7 +135,7 @@ local function push_button(args)
|
|||||||
e.on_unfocused = show_unpressed
|
e.on_unfocused = show_unpressed
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
draw()
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -27,11 +27,12 @@ local element = require("graphics.element")
|
|||||||
---@param args radio_2d_args
|
---@param args radio_2d_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function radio_2d_button(args)
|
local function radio_2d_button(args)
|
||||||
assert(type(args.options) == "table" and #args.options > 0, "graphics.elements.controls.radio_2d: options should be a table with length >= 1")
|
assert(type(args.options) == "table" and #args.options > 0, "controls.radio_2d: options should be a table with length >= 1")
|
||||||
assert(type(args.radio_colors) == "table", "graphics.elements.controls.radio_2d: radio_colors is a required field")
|
assert(util.is_int(args.rows) and util.is_int(args.columns), "controls.radio_2d: rows/columns must be integers")
|
||||||
assert(type(args.select_color) == "number" or type(args.color_map) == "table", "graphics.elements.controls.radio_2d: select_color or color_map is required")
|
assert((args.rows * args.columns) >= #args.options, "controls.radio_2d: rows x columns size insufficient for provided number of options")
|
||||||
assert(type(args.default) == "nil" or (type(args.default) == "number" and args.default > 0),
|
assert(type(args.radio_colors) == "table", "controls.radio_2d: radio_colors is a required field")
|
||||||
"graphics.elements.controls.radio_2d: default must be nil or a number > 0")
|
assert(type(args.select_color) == "number" or type(args.color_map) == "table", "controls.radio_2d: select_color or color_map is required")
|
||||||
|
assert(type(args.default) == "nil" or (type(args.default) == "number" and args.default > 0), "controls.radio_2d: default must be nil or a number > 0")
|
||||||
|
|
||||||
local array = {}
|
local array = {}
|
||||||
local col_widths = {}
|
local col_widths = {}
|
||||||
@ -74,8 +75,8 @@ local function radio_2d_button(args)
|
|||||||
-- selected option (convert nil to 1 if missing)
|
-- selected option (convert nil to 1 if missing)
|
||||||
e.value = args.default or 1
|
e.value = args.default or 1
|
||||||
|
|
||||||
-- show the args.options/states
|
-- draw the element
|
||||||
local function draw()
|
function e.redraw()
|
||||||
local col_x = 1
|
local col_x = 1
|
||||||
|
|
||||||
local radio_color_b = util.trinary(type(args.disable_color) == "number" and not e.enabled, args.disable_color, args.radio_colors.color_b)
|
local radio_color_b = util.trinary(type(args.disable_color) == "number" and not e.enabled, args.disable_color, args.radio_colors.color_b)
|
||||||
@ -135,7 +136,7 @@ local function radio_2d_button(args)
|
|||||||
if elem ~= nil and event.initial.x >= elem.x_1 and event.initial.x <= elem.x_2 and event.current.x >= elem.x_1 and event.current.x <= elem.x_2 then
|
if elem ~= nil and event.initial.x >= elem.x_1 and event.initial.x <= elem.x_2 and event.current.x >= elem.x_1 and event.current.x <= elem.x_2 then
|
||||||
e.value = elem.id
|
e.value = elem.id
|
||||||
focused_opt = elem.id
|
focused_opt = elem.id
|
||||||
draw()
|
e.redraw()
|
||||||
if type(args.callback) == "function" then args.callback(e.value) end
|
if type(args.callback) == "function" then args.callback(e.value) end
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -149,30 +150,30 @@ local function radio_2d_button(args)
|
|||||||
if event.type == core.events.KEY_CLICK.DOWN or event.type == core.events.KEY_CLICK.HELD then
|
if event.type == core.events.KEY_CLICK.DOWN or event.type == core.events.KEY_CLICK.HELD then
|
||||||
if event.type == core.events.KEY_CLICK.DOWN and (event.key == keys.space or event.key == keys.enter or event.key == keys.numPadEnter) then
|
if event.type == core.events.KEY_CLICK.DOWN and (event.key == keys.space or event.key == keys.enter or event.key == keys.numPadEnter) then
|
||||||
e.value = focused_opt
|
e.value = focused_opt
|
||||||
draw()
|
e.redraw()
|
||||||
if type(args.callback) == "function" then args.callback(e.value) end
|
if type(args.callback) == "function" then args.callback(e.value) end
|
||||||
elseif event.key == keys.down then
|
elseif event.key == keys.down then
|
||||||
if focused_opt < #args.options then
|
if focused_opt < #args.options then
|
||||||
focused_opt = focused_opt + 1
|
focused_opt = focused_opt + 1
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
elseif event.key == keys.up then
|
elseif event.key == keys.up then
|
||||||
if focused_opt > 1 then
|
if focused_opt > 1 then
|
||||||
focused_opt = focused_opt - 1
|
focused_opt = focused_opt - 1
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
elseif event.key == keys.right then
|
elseif event.key == keys.right then
|
||||||
if array[focus_y + 1] and array[focus_y + 1][focus_x] then
|
if array[focus_y + 1] and array[focus_y + 1][focus_x] then
|
||||||
focused_opt = array[focus_y + 1][focus_x].id
|
focused_opt = array[focus_y + 1][focus_x].id
|
||||||
else focused_opt = array[1][focus_x].id end
|
else focused_opt = array[1][focus_x].id end
|
||||||
draw()
|
e.redraw()
|
||||||
elseif event.key == keys.left then
|
elseif event.key == keys.left then
|
||||||
if array[focus_y - 1] and array[focus_y - 1][focus_x] then
|
if array[focus_y - 1] and array[focus_y - 1][focus_x] then
|
||||||
focused_opt = array[focus_y - 1][focus_x].id
|
focused_opt = array[focus_y - 1][focus_x].id
|
||||||
draw()
|
e.redraw()
|
||||||
elseif array[#array][focus_x] then
|
elseif array[#array][focus_x] then
|
||||||
focused_opt = array[#array][focus_x].id
|
focused_opt = array[#array][focus_x].id
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -183,20 +184,20 @@ local function radio_2d_button(args)
|
|||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
if val > 0 and val <= #args.options then
|
if val > 0 and val <= #args.options then
|
||||||
e.value = val
|
e.value = val
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle focus
|
-- handle focus
|
||||||
e.on_focused = draw
|
e.on_focused = e.redraw
|
||||||
e.on_unfocused = draw
|
e.on_unfocused = e.redraw
|
||||||
|
|
||||||
-- handle enable
|
-- handle enable
|
||||||
e.on_enabled = draw
|
e.on_enabled = e.redraw
|
||||||
e.on_disabled = draw
|
e.on_disabled = e.redraw
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
draw()
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -25,14 +25,14 @@ local KEY_CLICK = core.events.KEY_CLICK
|
|||||||
---@param args radio_button_args
|
---@param args radio_button_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function radio_button(args)
|
local function radio_button(args)
|
||||||
assert(type(args.options) == "table", "graphics.elements.controls.radio_button: options is a required field")
|
assert(type(args.options) == "table", "controls.radio_button: options is a required field")
|
||||||
assert(#args.options > 0, "graphics.elements.controls.radio_button: at least one option is required")
|
assert(#args.options > 0, "controls.radio_button: at least one option is required")
|
||||||
assert(type(args.radio_colors) == "table", "graphics.elements.controls.radio_button: radio_colors is a required field")
|
assert(type(args.radio_colors) == "table", "controls.radio_button: radio_colors is a required field")
|
||||||
assert(type(args.select_color) == "number", "graphics.elements.controls.radio_button: select_color is a required field")
|
assert(type(args.select_color) == "number", "controls.radio_button: select_color is a required field")
|
||||||
assert(type(args.default) == "nil" or (type(args.default) == "number" and args.default > 0),
|
assert(type(args.default) == "nil" or (type(args.default) == "number" and args.default > 0),
|
||||||
"graphics.elements.controls.radio_button: default must be nil or a number > 0")
|
"controls.radio_button: default must be nil or a number > 0")
|
||||||
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
||||||
"graphics.elements.controls.radio_button: min_width must be nil or a number > 0")
|
"controls.radio_button: min_width must be nil or a number > 0")
|
||||||
|
|
||||||
-- determine widths
|
-- determine widths
|
||||||
local max_width = 1
|
local max_width = 1
|
||||||
@ -59,7 +59,7 @@ local function radio_button(args)
|
|||||||
e.value = args.default or 1
|
e.value = args.default or 1
|
||||||
|
|
||||||
-- show the button state
|
-- show the button state
|
||||||
local function draw()
|
function e.redraw()
|
||||||
for i = 1, #args.options do
|
for i = 1, #args.options do
|
||||||
local opt = args.options[i] ---@type string
|
local opt = args.options[i] ---@type string
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ local function radio_button(args)
|
|||||||
if args.options[event.current.y] ~= nil then
|
if args.options[event.current.y] ~= nil then
|
||||||
e.value = event.current.y
|
e.value = event.current.y
|
||||||
focused_opt = e.value
|
focused_opt = e.value
|
||||||
draw()
|
e.redraw()
|
||||||
if type(args.callback) == "function" then args.callback(e.value) end
|
if type(args.callback) == "function" then args.callback(e.value) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -109,17 +109,17 @@ local function radio_button(args)
|
|||||||
if event.type == KEY_CLICK.DOWN or event.type == KEY_CLICK.HELD then
|
if event.type == KEY_CLICK.DOWN or event.type == KEY_CLICK.HELD then
|
||||||
if event.type == KEY_CLICK.DOWN and (event.key == keys.space or event.key == keys.enter or event.key == keys.numPadEnter) then
|
if event.type == KEY_CLICK.DOWN and (event.key == keys.space or event.key == keys.enter or event.key == keys.numPadEnter) then
|
||||||
e.value = focused_opt
|
e.value = focused_opt
|
||||||
draw()
|
e.redraw()
|
||||||
if type(args.callback) == "function" then args.callback(e.value) end
|
if type(args.callback) == "function" then args.callback(e.value) end
|
||||||
elseif event.key == keys.down then
|
elseif event.key == keys.down then
|
||||||
if focused_opt < #args.options then
|
if focused_opt < #args.options then
|
||||||
focused_opt = focused_opt + 1
|
focused_opt = focused_opt + 1
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
elseif event.key == keys.up then
|
elseif event.key == keys.up then
|
||||||
if focused_opt > 1 then
|
if focused_opt > 1 then
|
||||||
focused_opt = focused_opt - 1
|
focused_opt = focused_opt - 1
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -130,20 +130,20 @@ local function radio_button(args)
|
|||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
if val > 0 and val <= #args.options then
|
if val > 0 and val <= #args.options then
|
||||||
e.value = val
|
e.value = val
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle focus
|
-- handle focus
|
||||||
e.on_focused = draw
|
e.on_focused = e.redraw
|
||||||
e.on_unfocused = draw
|
e.on_unfocused = e.redraw
|
||||||
|
|
||||||
-- handle enable
|
-- handle enable
|
||||||
e.on_enabled = draw
|
e.on_enabled = e.redraw
|
||||||
e.on_disabled = draw
|
e.on_disabled = e.redraw
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
draw()
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
-- Sidebar Graphics Element
|
-- Sidebar Graphics Element
|
||||||
|
|
||||||
local tcd = require("scada-common.tcd")
|
local tcd = require("scada-common.tcd")
|
||||||
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local core = require("graphics.core")
|
local core = require("graphics.core")
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
@ -26,11 +27,10 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
|
|||||||
---@param args sidebar_args
|
---@param args sidebar_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function sidebar(args)
|
local function sidebar(args)
|
||||||
assert(type(args.tabs) == "table", "graphics.elements.controls.sidebar: tabs is a required field")
|
assert(type(args.tabs) == "table", "controls.sidebar: tabs is a required field")
|
||||||
assert(#args.tabs > 0, "graphics.elements.controls.sidebar: at least one tab is required")
|
assert(#args.tabs > 0, "controls.sidebar: at least one tab is required")
|
||||||
assert(type(args.callback) == "function", "graphics.elements.controls.sidebar: callback is a required field")
|
assert(type(args.callback) == "function", "controls.sidebar: callback is a required field")
|
||||||
|
|
||||||
-- always 3 wide
|
|
||||||
args.width = 3
|
args.width = 3
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
@ -41,10 +41,14 @@ local function sidebar(args)
|
|||||||
-- default to 1st tab
|
-- default to 1st tab
|
||||||
e.value = 1
|
e.value = 1
|
||||||
|
|
||||||
|
local was_pressed = false
|
||||||
|
|
||||||
-- show the button state
|
-- show the button state
|
||||||
---@param pressed boolean if the currently selected tab should appear as actively pressed
|
---@param pressed? boolean if the currently selected tab should appear as actively pressed
|
||||||
---@param pressed_idx? integer optional index to show as held (that is not yet selected)
|
---@param pressed_idx? integer optional index to show as held (that is not yet selected)
|
||||||
local function draw(pressed, pressed_idx)
|
local function draw(pressed, pressed_idx)
|
||||||
|
pressed = util.trinary(pressed == nil, was_pressed, pressed)
|
||||||
|
was_pressed = pressed
|
||||||
pressed_idx = pressed_idx or e.value
|
pressed_idx = pressed_idx or e.value
|
||||||
|
|
||||||
for i = 1, #args.tabs do
|
for i = 1, #args.tabs do
|
||||||
@ -65,12 +69,8 @@ local function sidebar(args)
|
|||||||
e.w_write(" ")
|
e.w_write(" ")
|
||||||
e.w_set_cur(1, y + 1)
|
e.w_set_cur(1, y + 1)
|
||||||
if e.value == i then
|
if e.value == i then
|
||||||
-- show as selected
|
|
||||||
e.w_write(" " .. tab.char .. "\x10")
|
e.w_write(" " .. tab.char .. "\x10")
|
||||||
else
|
else e.w_write(" " .. tab.char .. " ") end
|
||||||
-- show as unselected
|
|
||||||
e.w_write(" " .. tab.char .. " ")
|
|
||||||
end
|
|
||||||
e.w_set_cur(1, y + 2)
|
e.w_set_cur(1, y + 2)
|
||||||
e.w_write(" ")
|
e.w_write(" ")
|
||||||
end
|
end
|
||||||
@ -113,8 +113,10 @@ local function sidebar(args)
|
|||||||
draw(false)
|
draw(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial draw
|
-- element redraw
|
||||||
draw(false)
|
e.redraw = draw
|
||||||
|
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -29,8 +29,8 @@ local function spinbox(args)
|
|||||||
local wn_prec = args.whole_num_precision
|
local wn_prec = args.whole_num_precision
|
||||||
local fr_prec = args.fractional_precision
|
local fr_prec = args.fractional_precision
|
||||||
|
|
||||||
assert(util.is_int(wn_prec), "graphics.element.controls.spinbox_numeric: whole number precision must be an integer")
|
assert(util.is_int(wn_prec), "controls.spinbox_numeric: whole number precision must be an integer")
|
||||||
assert(util.is_int(fr_prec), "graphics.element.controls.spinbox_numeric: fractional precision must be an integer")
|
assert(util.is_int(fr_prec), "controls.spinbox_numeric: fractional precision must be an integer")
|
||||||
|
|
||||||
local fmt, fmt_init ---@type string, string
|
local fmt, fmt_init ---@type string, string
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ local function spinbox(args)
|
|||||||
|
|
||||||
local dec_point_x = args.whole_num_precision + 1
|
local dec_point_x = args.whole_num_precision + 1
|
||||||
|
|
||||||
assert(type(args.arrow_fg_bg) == "table", "graphics.element.spinbox_numeric: arrow_fg_bg is a required field")
|
assert(type(args.arrow_fg_bg) == "table", "controls.spinbox_numeric: arrow_fg_bg is a required field")
|
||||||
|
|
||||||
-- determine widths
|
-- determine widths
|
||||||
args.width = wn_prec + fr_prec + util.trinary(fr_prec > 0, 1, 0)
|
args.width = wn_prec + fr_prec + util.trinary(fr_prec > 0, 1, 0)
|
||||||
@ -72,8 +72,6 @@ local function spinbox(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
draw_arrows(args.arrow_fg_bg.fgd)
|
|
||||||
|
|
||||||
-- populate digits from current value
|
-- populate digits from current value
|
||||||
local function set_digits()
|
local function set_digits()
|
||||||
local initial_str = util.sprintf(fmt_init, e.value)
|
local initial_str = util.sprintf(fmt_init, e.value)
|
||||||
@ -125,9 +123,6 @@ local function spinbox(args)
|
|||||||
e.w_write(util.sprintf(fmt, e.value))
|
e.w_write(util.sprintf(fmt, e.value))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- init with the default value
|
|
||||||
show_num()
|
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- handle mouse interaction
|
||||||
---@param event mouse_interaction mouse event
|
---@param event mouse_interaction mouse event
|
||||||
function e.handle_mouse(event)
|
function e.handle_mouse(event)
|
||||||
@ -138,10 +133,8 @@ local function spinbox(args)
|
|||||||
local idx = util.trinary(event.current.x > dec_point_x, event.current.x - 1, event.current.x)
|
local idx = util.trinary(event.current.x > dec_point_x, event.current.x - 1, event.current.x)
|
||||||
if digits[idx] ~= nil then
|
if digits[idx] ~= nil then
|
||||||
if event.current.y == 1 then
|
if event.current.y == 1 then
|
||||||
-- increment
|
|
||||||
digits[idx] = digits[idx] + 1
|
digits[idx] = digits[idx] + 1
|
||||||
elseif event.current.y == 3 then
|
elseif event.current.y == 3 then
|
||||||
-- decrement
|
|
||||||
digits[idx] = digits[idx] - 1
|
digits[idx] = digits[idx] - 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -176,18 +169,19 @@ local function spinbox(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- enable this input
|
-- enable this input
|
||||||
function e.on_enabled()
|
function e.on_enabled() draw_arrows(args.arrow_fg_bg.fgd) end
|
||||||
draw_arrows(args.arrow_fg_bg.fgd)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- disable this input
|
-- disable this input
|
||||||
function e.on_disabled()
|
function e.on_disabled() draw_arrows(args.arrow_disable or colors.lightGray) end
|
||||||
draw_arrows(args.arrow_disable or colors.lightGray)
|
|
||||||
|
-- element redraw
|
||||||
|
function e.redraw()
|
||||||
|
show_num()
|
||||||
|
draw_arrows(util.trinary(e.enabled, args.arrow_fg_bg.fgd, args.arrow_disable or colors.lightGray))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- default to zero, init digits table
|
-- initial draw
|
||||||
e.value = 0
|
e.redraw()
|
||||||
set_digits()
|
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -21,15 +21,13 @@ local element = require("graphics.element")
|
|||||||
---@param args switch_button_args
|
---@param args switch_button_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function switch_button(args)
|
local function switch_button(args)
|
||||||
assert(type(args.text) == "string", "graphics.elements.controls.switch_button: text is a required field")
|
assert(type(args.text) == "string", "controls.switch_button: text is a required field")
|
||||||
assert(type(args.callback) == "function", "graphics.elements.controls.switch_button: callback is a required field")
|
assert(type(args.callback) == "function", "controls.switch_button: callback is a required field")
|
||||||
assert(type(args.active_fg_bg) == "table", "graphics.elements.controls.switch_button: active_fg_bg is a required field")
|
assert(type(args.active_fg_bg) == "table", "controls.switch_button: active_fg_bg is a required field")
|
||||||
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), "controls.switch_button: min_width must be nil or a number > 0")
|
||||||
"graphics.elements.controls.switch_button: min_width must be nil or a number > 0")
|
|
||||||
|
|
||||||
local text_width = string.len(args.text)
|
local text_width = string.len(args.text)
|
||||||
|
|
||||||
-- single line height, calculate width
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
args.min_width = args.min_width or 0
|
args.min_width = args.min_width or 0
|
||||||
args.width = math.max(text_width, args.min_width)
|
args.width = math.max(text_width, args.min_width)
|
||||||
@ -37,44 +35,32 @@ local function switch_button(args)
|
|||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- button state (convert nil to false if missing)
|
|
||||||
e.value = args.default or false
|
e.value = args.default or false
|
||||||
|
|
||||||
local h_pad = math.floor((e.frame.w - text_width) / 2) + 1
|
local h_pad = math.floor((e.frame.w - text_width) / 2) + 1
|
||||||
local v_pad = math.floor(e.frame.h / 2) + 1
|
local v_pad = math.floor(e.frame.h / 2) + 1
|
||||||
|
|
||||||
-- show the button state
|
-- show the button state
|
||||||
local function draw_state()
|
function e.redraw()
|
||||||
if e.value then
|
if e.value then
|
||||||
-- show as pressed
|
|
||||||
e.w_set_fgd(args.active_fg_bg.fgd)
|
e.w_set_fgd(args.active_fg_bg.fgd)
|
||||||
e.w_set_bkg(args.active_fg_bg.bkg)
|
e.w_set_bkg(args.active_fg_bg.bkg)
|
||||||
else
|
else
|
||||||
-- show as unpressed
|
|
||||||
e.w_set_fgd(e.fg_bg.fgd)
|
e.w_set_fgd(e.fg_bg.fgd)
|
||||||
e.w_set_bkg(e.fg_bg.bkg)
|
e.w_set_bkg(e.fg_bg.bkg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- clear to redraw background
|
|
||||||
e.window.clear()
|
e.window.clear()
|
||||||
|
|
||||||
-- write the button text
|
|
||||||
e.w_set_cur(h_pad, v_pad)
|
e.w_set_cur(h_pad, v_pad)
|
||||||
e.w_write(args.text)
|
e.w_write(args.text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial draw
|
|
||||||
draw_state()
|
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- handle mouse interaction
|
||||||
---@param event mouse_interaction mouse event
|
---@param event mouse_interaction mouse event
|
||||||
function e.handle_mouse(event)
|
function e.handle_mouse(event)
|
||||||
if e.enabled and core.events.was_clicked(event.type) then
|
if e.enabled and core.events.was_clicked(event.type) then
|
||||||
-- toggle state
|
|
||||||
e.value = not e.value
|
e.value = not e.value
|
||||||
draw_state()
|
e.redraw()
|
||||||
|
|
||||||
-- call the touch callback with state
|
|
||||||
args.callback(e.value)
|
args.callback(e.value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -82,11 +68,13 @@ local function switch_button(args)
|
|||||||
-- set the value
|
-- set the value
|
||||||
---@param val boolean new value
|
---@param val boolean new value
|
||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
-- set state
|
|
||||||
e.value = val
|
e.value = val
|
||||||
draw_state()
|
e.redraw()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,13 +27,11 @@ local element = require("graphics.element")
|
|||||||
---@param args tabbar_args
|
---@param args tabbar_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function tabbar(args)
|
local function tabbar(args)
|
||||||
assert(type(args.tabs) == "table", "graphics.elements.controls.tabbar: tabs is a required field")
|
assert(type(args.tabs) == "table", "controls.tabbar: tabs is a required field")
|
||||||
assert(#args.tabs > 0, "graphics.elements.controls.tabbar: at least one tab is required")
|
assert(#args.tabs > 0, "controls.tabbar: at least one tab is required")
|
||||||
assert(type(args.callback) == "function", "graphics.elements.controls.tabbar: callback is a required field")
|
assert(type(args.callback) == "function", "controls.tabbar: callback is a required field")
|
||||||
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), "controls.tabbar: min_width must be nil or a number > 0")
|
||||||
"graphics.elements.controls.tabbar: min_width must be nil or a number > 0")
|
|
||||||
|
|
||||||
-- always 1 tall
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- determine widths
|
-- determine widths
|
||||||
@ -67,7 +65,7 @@ local function tabbar(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- show the tab state
|
-- show the tab state
|
||||||
local function draw()
|
function e.redraw()
|
||||||
for i = 1, #args.tabs do
|
for i = 1, #args.tabs do
|
||||||
local tab = args.tabs[i] ---@type tabbar_tab
|
local tab = args.tabs[i] ---@type tabbar_tab
|
||||||
|
|
||||||
@ -109,7 +107,7 @@ local function tabbar(args)
|
|||||||
-- tap always has identical coordinates, so this always passes for taps
|
-- tap always has identical coordinates, so this always passes for taps
|
||||||
if tab_ini == tab_cur and tab_cur ~= nil then
|
if tab_ini == tab_cur and tab_cur ~= nil then
|
||||||
e.value = tab_cur
|
e.value = tab_cur
|
||||||
draw()
|
e.redraw()
|
||||||
args.callback(e.value)
|
args.callback(e.value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -119,11 +117,11 @@ local function tabbar(args)
|
|||||||
---@param val integer new value
|
---@param val integer new value
|
||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
e.value = val
|
e.value = val
|
||||||
draw()
|
e.redraw()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
draw()
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -42,30 +42,6 @@ local function number_field(args)
|
|||||||
-- make an interactive field manager
|
-- make an interactive field manager
|
||||||
local ifield = core.new_ifield(e, args.max_digits, args.fg_bg, args.dis_fg_bg)
|
local ifield = core.new_ifield(e, args.max_digits, args.fg_bg, args.dis_fg_bg)
|
||||||
|
|
||||||
|
|
||||||
-- draw input
|
|
||||||
local function show()
|
|
||||||
if e.enabled then
|
|
||||||
e.w_set_bkg(args.fg_bg.bkg)
|
|
||||||
e.w_set_fgd(args.fg_bg.fgd)
|
|
||||||
else
|
|
||||||
e.w_set_bkg(args.dis_fg_bg.bkg)
|
|
||||||
e.w_set_fgd(args.dis_fg_bg.fgd)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- clear and print
|
|
||||||
e.w_set_cur(1, 1)
|
|
||||||
e.w_write(string.rep(" ", e.frame.w))
|
|
||||||
e.w_set_cur(1, 1)
|
|
||||||
e.w_write(e.value)
|
|
||||||
|
|
||||||
-- show cursor if focused
|
|
||||||
if e.is_focused() and e.enabled then
|
|
||||||
e.w_set_fgd(colors.lightGray)
|
|
||||||
e.w_write("_")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- handle mouse interaction
|
||||||
---@param event mouse_interaction mouse event
|
---@param event mouse_interaction mouse event
|
||||||
function e.handle_mouse(event)
|
function e.handle_mouse(event)
|
||||||
@ -117,9 +93,7 @@ local function number_field(args)
|
|||||||
-- set the value (must be a number)
|
-- set the value (must be a number)
|
||||||
---@param val number number to show
|
---@param val number number to show
|
||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
if tonumber(val) then
|
if tonumber(val) then ifield.set_value("" .. tonumber(val)) end
|
||||||
ifield.set_value("" .. tonumber(val))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set minimum input value
|
-- set minimum input value
|
||||||
@ -140,9 +114,6 @@ local function number_field(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle focused
|
|
||||||
e.on_focused = show
|
|
||||||
|
|
||||||
-- handle unfocused
|
-- handle unfocused
|
||||||
function e.on_unfocused()
|
function e.on_unfocused()
|
||||||
local val = tonumber(e.value)
|
local val = tonumber(e.value)
|
||||||
@ -162,12 +133,14 @@ local function number_field(args)
|
|||||||
ifield.show()
|
ifield.show()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle enable
|
-- handle focus (not unfocus), enable, and redraw with show()
|
||||||
|
e.on_focused = ifield.show
|
||||||
e.on_enabled = ifield.show
|
e.on_enabled = ifield.show
|
||||||
e.on_disabled = ifield.show
|
e.on_disabled = ifield.show
|
||||||
|
e.redraw = ifield.show
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
ifield.show()
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -88,16 +88,15 @@ local function text_field(args)
|
|||||||
ifield.set_value(text)
|
ifield.set_value(text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle focus
|
-- handle focus, enable, and redraw with show()
|
||||||
e.on_focused = ifield.show
|
e.on_focused = ifield.show
|
||||||
e.on_unfocused = ifield.show
|
e.on_unfocused = ifield.show
|
||||||
|
|
||||||
-- handle enable
|
|
||||||
e.on_enabled = ifield.show
|
e.on_enabled = ifield.show
|
||||||
e.on_disabled = ifield.show
|
e.on_disabled = ifield.show
|
||||||
|
e.redraw = ifield.show
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
ifield.show()
|
e.redraw()
|
||||||
|
|
||||||
local elem, id = e.complete()
|
local elem, id = e.complete()
|
||||||
return elem, id, ifield.censor
|
return elem, id, ifield.censor
|
||||||
|
@ -25,13 +25,13 @@ local flasher = require("graphics.flasher")
|
|||||||
---@param args alarm_indicator_light
|
---@param args alarm_indicator_light
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function alarm_indicator_light(args)
|
local function alarm_indicator_light(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.alight: label is a required field")
|
assert(type(args.label) == "string", "indicators.alight: label is a required field")
|
||||||
assert(type(args.c1) == "number", "graphics.elements.indicators.alight: c1 is a required field")
|
assert(type(args.c1) == "number", "indicators.alight: c1 is a required field")
|
||||||
assert(type(args.c2) == "number", "graphics.elements.indicators.alight: c2 is a required field")
|
assert(type(args.c2) == "number", "indicators.alight: c2 is a required field")
|
||||||
assert(type(args.c3) == "number", "graphics.elements.indicators.alight: c3 is a required field")
|
assert(type(args.c3) == "number", "indicators.alight: c3 is a required field")
|
||||||
|
|
||||||
if args.flash then
|
if args.flash then
|
||||||
assert(util.is_int(args.period), "graphics.elements.indicators.alight: period is a required field if flash is enabled")
|
assert(util.is_int(args.period), "indicators.alight: period is a required field if flash is enabled")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- single line
|
-- single line
|
||||||
@ -51,6 +51,8 @@ local function alarm_indicator_light(args)
|
|||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = 1
|
||||||
|
|
||||||
-- called by flasher when enabled
|
-- called by flasher when enabled
|
||||||
local function flash_callback()
|
local function flash_callback()
|
||||||
e.w_set_cur(1, 1)
|
e.w_set_cur(1, 1)
|
||||||
@ -105,9 +107,14 @@ local function alarm_indicator_light(args)
|
|||||||
---@param val integer indicator state
|
---@param val integer indicator state
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- write label and initial indicator light
|
-- draw label and indicator light
|
||||||
e.on_update(1)
|
function e.redraw()
|
||||||
e.w_write(args.label)
|
e.on_update(e.value)
|
||||||
|
e.w_write(args.label)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -18,8 +18,8 @@ local element = require("graphics.element")
|
|||||||
---@param args core_map_args
|
---@param args core_map_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function core_map(args)
|
local function core_map(args)
|
||||||
assert(util.is_int(args.reactor_l), "graphics.elements.indicators.coremap: reactor_l is a required field")
|
assert(util.is_int(args.reactor_l), "indicators.coremap: reactor_l is a required field")
|
||||||
assert(util.is_int(args.reactor_w), "graphics.elements.indicators.coremap: reactor_w is a required field")
|
assert(util.is_int(args.reactor_w), "indicators.coremap: reactor_w is a required field")
|
||||||
|
|
||||||
-- require max dimensions
|
-- require max dimensions
|
||||||
args.width = 18
|
args.width = 18
|
||||||
@ -31,6 +31,8 @@ local function core_map(args)
|
|||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = 0
|
||||||
|
|
||||||
local alternator = true
|
local alternator = true
|
||||||
|
|
||||||
local core_l = args.reactor_l - 2
|
local core_l = args.reactor_l - 2
|
||||||
@ -157,11 +159,14 @@ local function core_map(args)
|
|||||||
e.on_update(e.value)
|
e.on_update(e.value)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial (one-time except for resize()) frame draw
|
-- redraw both frame and core
|
||||||
draw_frame()
|
function e.redraw()
|
||||||
|
draw_frame()
|
||||||
|
draw_core(e.value)
|
||||||
|
end
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
e.on_update(0)
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -24,25 +24,17 @@ local element = require("graphics.element")
|
|||||||
---@param args data_indicator_args
|
---@param args data_indicator_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function data(args)
|
local function data(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.data: label is a required field")
|
assert(type(args.label) == "string", "indicators.data: label is a required field")
|
||||||
assert(type(args.format) == "string", "graphics.elements.indicators.data: format is a required field")
|
assert(type(args.format) == "string", "indicators.data: format is a required field")
|
||||||
assert(args.value ~= nil, "graphics.elements.indicators.data: value is a required field")
|
assert(args.value ~= nil, "indicators.data: value is a required field")
|
||||||
assert(util.is_int(args.width), "graphics.elements.indicators.data: width is a required field")
|
assert(util.is_int(args.width), "indicators.data: width is a required field")
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- label color
|
e.value = args.value
|
||||||
if args.lu_colors ~= nil then
|
|
||||||
e.w_set_fgd(args.lu_colors.color_a)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- write label
|
|
||||||
e.w_set_cur(1, 1)
|
|
||||||
e.w_write(args.label)
|
|
||||||
|
|
||||||
local value_color = e.fg_bg.fgd
|
local value_color = e.fg_bg.fgd
|
||||||
local label_len = string.len(args.label)
|
local label_len = string.len(args.label)
|
||||||
@ -93,8 +85,17 @@ local function data(args)
|
|||||||
e.on_update(e.value)
|
e.on_update(e.value)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial value draw
|
-- element redraw
|
||||||
e.on_update(args.value)
|
function e.redraw()
|
||||||
|
if args.lu_colors ~= nil then e.w_set_fgd(args.lu_colors.color_a) end
|
||||||
|
e.w_set_cur(1, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
|
||||||
|
e.on_update(e.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -28,10 +28,12 @@ local function hbar(args)
|
|||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = 0.0
|
||||||
|
|
||||||
-- bar width is width - 5 characters for " 100%" if showing percent
|
-- bar width is width - 5 characters for " 100%" if showing percent
|
||||||
local bar_width = util.trinary(args.show_percent, e.frame.w - 5, e.frame.w)
|
local bar_width = util.trinary(args.show_percent, e.frame.w - 5, e.frame.w)
|
||||||
|
|
||||||
assert(bar_width > 0, "graphics.elements.indicators.hbar: too small for bar")
|
assert(bar_width > 0, "indicators.hbar: too small for bar")
|
||||||
|
|
||||||
-- determine bar colors
|
-- determine bar colors
|
||||||
local bar_bkg = e.fg_bg.blit_bkg
|
local bar_bkg = e.fg_bg.blit_bkg
|
||||||
@ -105,20 +107,21 @@ local function hbar(args)
|
|||||||
function e.recolor(bar_fg_bg)
|
function e.recolor(bar_fg_bg)
|
||||||
bar_bkg = bar_fg_bg.blit_bkg
|
bar_bkg = bar_fg_bg.blit_bkg
|
||||||
bar_fgd = bar_fg_bg.blit_fgd
|
bar_fgd = bar_fg_bg.blit_fgd
|
||||||
|
e.redraw()
|
||||||
-- re-draw
|
|
||||||
last_num_bars = 0
|
|
||||||
if type(e.value) == "number" then
|
|
||||||
e.on_update(e.value)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set the percentage value
|
-- set the percentage value
|
||||||
---@param val number 0.0 to 1.0
|
---@param val number 0.0 to 1.0
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- initialize to 0
|
-- element redraw
|
||||||
e.on_update(0)
|
function e.redraw()
|
||||||
|
last_num_bars = -1
|
||||||
|
e.on_update(e.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -23,18 +23,17 @@ local element = require("graphics.element")
|
|||||||
---@param args icon_indicator_args
|
---@param args icon_indicator_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function icon(args)
|
local function icon(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.icon: label is a required field")
|
assert(type(args.label) == "string", "indicators.icon: label is a required field")
|
||||||
assert(type(args.states) == "table", "graphics.elements.indicators.icon: states is a required field")
|
assert(type(args.states) == "table", "indicators.icon: states is a required field")
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- determine width
|
|
||||||
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 4
|
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 4
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = args.value or 1
|
||||||
|
|
||||||
-- state blit strings
|
-- state blit strings
|
||||||
local state_blit_cmds = {}
|
local state_blit_cmds = {}
|
||||||
for i = 1, #args.states do
|
for i = 1, #args.states do
|
||||||
@ -47,10 +46,6 @@ local function icon(args)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- write label and initial indicator light
|
|
||||||
e.w_set_cur(5, 1)
|
|
||||||
e.w_write(args.label)
|
|
||||||
|
|
||||||
-- on state change
|
-- on state change
|
||||||
---@param new_state integer indicator state
|
---@param new_state integer indicator state
|
||||||
function e.on_update(new_state)
|
function e.on_update(new_state)
|
||||||
@ -64,8 +59,16 @@ local function icon(args)
|
|||||||
---@param val integer indicator state
|
---@param val integer indicator state
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- initial icon draw
|
-- element redraw
|
||||||
e.on_update(args.value or 1)
|
function e.redraw()
|
||||||
|
e.w_set_cur(5, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
|
||||||
|
e.on_update(e.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -23,25 +23,23 @@ local flasher = require("graphics.flasher")
|
|||||||
---@param args indicator_led_args
|
---@param args indicator_led_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function indicator_led(args)
|
local function indicator_led(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.led: label is a required field")
|
assert(type(args.label) == "string", "indicators.led: label is a required field")
|
||||||
assert(type(args.colors) == "table", "graphics.elements.indicators.led: colors is a required field")
|
assert(type(args.colors) == "table", "indicators.led: colors is a required field")
|
||||||
|
|
||||||
if args.flash then
|
if args.flash then
|
||||||
assert(util.is_int(args.period), "graphics.elements.indicators.led: period is a required field if flash is enabled")
|
assert(util.is_int(args.period), "indicators.led: period is a required field if flash is enabled")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- determine width
|
|
||||||
args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2
|
args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2
|
||||||
|
|
||||||
-- flasher state
|
|
||||||
local flash_on = true
|
local flash_on = true
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = false
|
||||||
|
|
||||||
-- called by flasher when enabled
|
-- called by flasher when enabled
|
||||||
local function flash_callback()
|
local function flash_callback()
|
||||||
e.w_set_cur(1, 1)
|
e.w_set_cur(1, 1)
|
||||||
@ -88,13 +86,18 @@ local function indicator_led(args)
|
|||||||
---@param val boolean indicator state
|
---@param val boolean indicator state
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- write label and initial indicator light
|
-- draw label and indicator light
|
||||||
e.on_update(false)
|
function e.redraw()
|
||||||
if string.len(args.label) > 0 then
|
e.on_update(e.value)
|
||||||
e.w_set_cur(3, 1)
|
if string.len(args.label) > 0 then
|
||||||
e.w_write(args.label)
|
e.w_set_cur(3, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,25 +25,20 @@ local flasher = require("graphics.flasher")
|
|||||||
---@param args indicator_led_pair_args
|
---@param args indicator_led_pair_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function indicator_led_pair(args)
|
local function indicator_led_pair(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.ledpair: label is a required field")
|
assert(type(args.label) == "string", "indicators.ledpair: label is a required field")
|
||||||
assert(type(args.off) == "number", "graphics.elements.indicators.ledpair: off is a required field")
|
assert(type(args.off) == "number", "indicators.ledpair: off is a required field")
|
||||||
assert(type(args.c1) == "number", "graphics.elements.indicators.ledpair: c1 is a required field")
|
assert(type(args.c1) == "number", "indicators.ledpair: c1 is a required field")
|
||||||
assert(type(args.c2) == "number", "graphics.elements.indicators.ledpair: c2 is a required field")
|
assert(type(args.c2) == "number", "indicators.ledpair: c2 is a required field")
|
||||||
|
|
||||||
if args.flash then
|
if args.flash then
|
||||||
assert(util.is_int(args.period), "graphics.elements.indicators.ledpair: period is a required field if flash is enabled")
|
assert(util.is_int(args.period), "indicators.ledpair: period is a required field if flash is enabled")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- determine width
|
|
||||||
args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2
|
args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2
|
||||||
|
|
||||||
-- flasher state
|
|
||||||
local flash_on = true
|
local flash_on = true
|
||||||
|
|
||||||
-- blit translations
|
|
||||||
local co = colors.toBlit(args.off)
|
local co = colors.toBlit(args.off)
|
||||||
local c1 = colors.toBlit(args.c1)
|
local c1 = colors.toBlit(args.c1)
|
||||||
local c2 = colors.toBlit(args.c2)
|
local c2 = colors.toBlit(args.c2)
|
||||||
@ -51,7 +46,6 @@ local function indicator_led_pair(args)
|
|||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- init value for initial check in on_update
|
|
||||||
e.value = 1
|
e.value = 1
|
||||||
|
|
||||||
-- called by flasher when enabled
|
-- called by flasher when enabled
|
||||||
@ -86,7 +80,6 @@ local function indicator_led_pair(args)
|
|||||||
elseif new_state <= 1 then
|
elseif new_state <= 1 then
|
||||||
flash_on = false
|
flash_on = false
|
||||||
flasher.stop(flash_callback)
|
flasher.stop(flash_callback)
|
||||||
|
|
||||||
e.w_blit("\x8c", co, e.fg_bg.blit_bkg)
|
e.w_blit("\x8c", co, e.fg_bg.blit_bkg)
|
||||||
end
|
end
|
||||||
elseif new_state == 2 then
|
elseif new_state == 2 then
|
||||||
@ -102,13 +95,18 @@ local function indicator_led_pair(args)
|
|||||||
---@param val integer indicator state
|
---@param val integer indicator state
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- write label and initial indicator light
|
-- draw label and indicator light
|
||||||
e.on_update(1)
|
function e.redraw()
|
||||||
if string.len(args.label) > 0 then
|
e.on_update(e.value)
|
||||||
e.w_set_cur(3, 1)
|
if string.len(args.label) > 0 then
|
||||||
e.w_write(args.label)
|
e.w_set_cur(3, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -18,19 +18,15 @@ local element = require("graphics.element")
|
|||||||
---@param args indicator_led_rgb_args
|
---@param args indicator_led_rgb_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function indicator_led_rgb(args)
|
local function indicator_led_rgb(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.ledrgb: label is a required field")
|
assert(type(args.label) == "string", "indicators.ledrgb: label is a required field")
|
||||||
assert(type(args.colors) == "table", "graphics.elements.indicators.ledrgb: colors is a required field")
|
assert(type(args.colors) == "table", "indicators.ledrgb: colors is a required field")
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- determine width
|
|
||||||
args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2
|
args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- init value for initial check in on_update
|
|
||||||
e.value = 1
|
e.value = 1
|
||||||
|
|
||||||
-- on state change
|
-- on state change
|
||||||
@ -47,13 +43,18 @@ local function indicator_led_rgb(args)
|
|||||||
---@param val integer indicator state
|
---@param val integer indicator state
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- write label and initial indicator light
|
-- draw label and indicator light
|
||||||
e.on_update(1)
|
function e.redraw()
|
||||||
if string.len(args.label) > 0 then
|
e.on_update(e.value)
|
||||||
e.w_set_cur(3, 1)
|
if string.len(args.label) > 0 then
|
||||||
e.w_write(args.label)
|
e.w_set_cur(3, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -23,25 +23,23 @@ local flasher = require("graphics.flasher")
|
|||||||
---@param args indicator_light_args
|
---@param args indicator_light_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function indicator_light(args)
|
local function indicator_light(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.light: label is a required field")
|
assert(type(args.label) == "string", "indicators.light: label is a required field")
|
||||||
assert(type(args.colors) == "table", "graphics.elements.indicators.light: colors is a required field")
|
assert(type(args.colors) == "table", "indicators.light: colors is a required field")
|
||||||
|
|
||||||
if args.flash then
|
if args.flash then
|
||||||
assert(util.is_int(args.period), "graphics.elements.indicators.light: period is a required field if flash is enabled")
|
assert(util.is_int(args.period), "indicators.light: period is a required field if flash is enabled")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- determine width
|
|
||||||
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2
|
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2
|
||||||
|
|
||||||
-- flasher state
|
|
||||||
local flash_on = true
|
local flash_on = true
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = false
|
||||||
|
|
||||||
-- called by flasher when enabled
|
-- called by flasher when enabled
|
||||||
local function flash_callback()
|
local function flash_callback()
|
||||||
e.w_set_cur(1, 1)
|
e.w_set_cur(1, 1)
|
||||||
@ -88,10 +86,15 @@ local function indicator_light(args)
|
|||||||
---@param val boolean indicator state
|
---@param val boolean indicator state
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- write label and initial indicator light
|
-- draw label and indicator light
|
||||||
e.on_update(false)
|
function e.redraw()
|
||||||
e.w_set_cur(3, 1)
|
e.on_update(false)
|
||||||
e.w_write(args.label)
|
e.w_set_cur(3, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -9,7 +9,7 @@ local element = require("graphics.element")
|
|||||||
---@field format string power format override (lua string format)
|
---@field format string power format override (lua string format)
|
||||||
---@field rate boolean? whether to append /t to the end (power per tick)
|
---@field rate boolean? whether to append /t to the end (power per tick)
|
||||||
---@field lu_colors? cpair label foreground color (a), unit foreground color (b)
|
---@field lu_colors? cpair label foreground color (a), unit foreground color (b)
|
||||||
---@field value any default value
|
---@field value number default value
|
||||||
---@field parent graphics_element
|
---@field parent graphics_element
|
||||||
---@field id? string element id
|
---@field id? string element id
|
||||||
---@field x? integer 1 if omitted
|
---@field x? integer 1 if omitted
|
||||||
@ -23,26 +23,17 @@ local element = require("graphics.element")
|
|||||||
---@param args power_indicator_args
|
---@param args power_indicator_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function power(args)
|
local function power(args)
|
||||||
assert(args.value ~= nil, "graphics.elements.indicators.power: value is a required field")
|
assert(type(args.value) == "number", "indicators.power: value is a required number field")
|
||||||
assert(util.is_int(args.width), "graphics.elements.indicators.power: width is a required field")
|
assert(util.is_int(args.width), "indicators.power: width is a required field")
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- label color
|
e.value = args.value
|
||||||
if args.lu_colors ~= nil then
|
|
||||||
e.w_set_fgd(args.lu_colors.color_a)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- write label
|
local data_start = 0
|
||||||
e.w_set_cur(1, 1)
|
|
||||||
e.w_write(args.label)
|
|
||||||
|
|
||||||
local data_start = string.len(args.label) + 2
|
|
||||||
if string.len(args.label) == 0 then data_start = 1 end
|
|
||||||
|
|
||||||
-- on state change
|
-- on state change
|
||||||
---@param value any new value
|
---@param value any new value
|
||||||
@ -77,8 +68,20 @@ local function power(args)
|
|||||||
---@param val any new value
|
---@param val any new value
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- initial value draw
|
-- element redraw
|
||||||
e.on_update(args.value)
|
function e.redraw()
|
||||||
|
if args.lu_colors ~= nil then e.w_set_fgd(args.lu_colors.color_a) end
|
||||||
|
e.w_set_cur(1, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
|
||||||
|
data_start = string.len(args.label) + 2
|
||||||
|
if string.len(args.label) == 0 then data_start = 1 end
|
||||||
|
|
||||||
|
e.on_update(e.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -10,7 +10,7 @@ local element = require("graphics.element")
|
|||||||
---@field format string data format (lua string format)
|
---@field format string data format (lua string format)
|
||||||
---@field commas? boolean whether to use commas if a number is given (default to false)
|
---@field commas? boolean whether to use commas if a number is given (default to false)
|
||||||
---@field lu_colors? cpair label foreground color (a), unit foreground color (b)
|
---@field lu_colors? cpair label foreground color (a), unit foreground color (b)
|
||||||
---@field value any default value
|
---@field value number default value
|
||||||
---@field parent graphics_element
|
---@field parent graphics_element
|
||||||
---@field id? string element id
|
---@field id? string element id
|
||||||
---@field x? integer 1 if omitted
|
---@field x? integer 1 if omitted
|
||||||
@ -24,24 +24,17 @@ local element = require("graphics.element")
|
|||||||
---@param args rad_indicator_args
|
---@param args rad_indicator_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function rad(args)
|
local function rad(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.rad: label is a required field")
|
assert(type(args.value) ~= "number", "indicators.rad: value is a required number field")
|
||||||
assert(type(args.format) == "string", "graphics.elements.indicators.rad: format is a required field")
|
assert(type(args.label) == "string", "indicators.rad: label is a required field")
|
||||||
assert(util.is_int(args.width), "graphics.elements.indicators.rad: width is a required field")
|
assert(type(args.format) == "string", "indicators.rad: format is a required field")
|
||||||
|
assert(util.is_int(args.width), "indicators.rad: width is a required field")
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- label color
|
e.value = types.new_zero_radiation_reading()
|
||||||
if args.lu_colors ~= nil then
|
|
||||||
e.w_set_fgd(args.lu_colors.color_a)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- write label
|
|
||||||
e.w_set_cur(1, 1)
|
|
||||||
e.w_write(args.label)
|
|
||||||
|
|
||||||
local label_len = string.len(args.label)
|
local label_len = string.len(args.label)
|
||||||
local data_start = 1
|
local data_start = 1
|
||||||
@ -82,8 +75,17 @@ local function rad(args)
|
|||||||
---@param val any new value
|
---@param val any new value
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- initial value draw
|
-- element redraw
|
||||||
e.on_update(types.new_zero_radiation_reading())
|
function e.redraw()
|
||||||
|
if args.lu_colors ~= nil then e.w_set_fgd(args.lu_colors.color_a) end
|
||||||
|
e.w_set_cur(1, 1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
|
||||||
|
e.on_update(e.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -25,16 +25,14 @@ local element = require("graphics.element")
|
|||||||
---@param args state_indicator_args
|
---@param args state_indicator_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function state_indicator(args)
|
local function state_indicator(args)
|
||||||
assert(type(args.states) == "table", "graphics.elements.indicators.state: states is a required field")
|
assert(type(args.states) == "table", "indicators.state: states is a required field")
|
||||||
|
|
||||||
-- determine height
|
|
||||||
if util.is_int(args.height) then
|
if util.is_int(args.height) then
|
||||||
assert(args.height % 2 == 1, "graphics.elements.indicators.state: height should be an odd number")
|
assert(args.height % 2 == 1, "indicators.state: height should be an odd number")
|
||||||
else
|
else
|
||||||
args.height = 1
|
args.height = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initial guess at width
|
|
||||||
args.width = args.min_width or 1
|
args.width = args.min_width or 1
|
||||||
|
|
||||||
-- state blit strings
|
-- state blit strings
|
||||||
@ -42,7 +40,6 @@ local function state_indicator(args)
|
|||||||
for i = 1, #args.states do
|
for i = 1, #args.states do
|
||||||
local state_def = args.states[i] ---@type state_text_color
|
local state_def = args.states[i] ---@type state_text_color
|
||||||
|
|
||||||
-- re-determine width
|
|
||||||
if string.len(state_def.text) > args.width then
|
if string.len(state_def.text) > args.width then
|
||||||
args.width = string.len(state_def.text)
|
args.width = string.len(state_def.text)
|
||||||
end
|
end
|
||||||
@ -59,13 +56,20 @@ local function state_indicator(args)
|
|||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = args.value or 1
|
||||||
|
|
||||||
|
-- element redraw
|
||||||
|
function e.redraw()
|
||||||
|
local blit_cmd = state_blit_cmds[e.value]
|
||||||
|
e.w_set_cur(1, 1)
|
||||||
|
e.w_blit(blit_cmd.text, blit_cmd.fgd, blit_cmd.bkg)
|
||||||
|
end
|
||||||
|
|
||||||
-- on state change
|
-- on state change
|
||||||
---@param new_state integer indicator state
|
---@param new_state integer indicator state
|
||||||
function e.on_update(new_state)
|
function e.on_update(new_state)
|
||||||
local blit_cmd = state_blit_cmds[new_state]
|
|
||||||
e.value = new_state
|
e.value = new_state
|
||||||
e.w_set_cur(1, 1)
|
e.redraw()
|
||||||
e.w_blit(blit_cmd.text, blit_cmd.fgd, blit_cmd.bkg)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set indicator state
|
-- set indicator state
|
||||||
@ -73,7 +77,7 @@ local function state_indicator(args)
|
|||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- initial draw
|
-- initial draw
|
||||||
e.on_update(args.value or 1)
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -25,35 +25,29 @@ local flasher = require("graphics.flasher")
|
|||||||
---@param args tristate_indicator_light_args
|
---@param args tristate_indicator_light_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function tristate_indicator_light(args)
|
local function tristate_indicator_light(args)
|
||||||
assert(type(args.label) == "string", "graphics.elements.indicators.trilight: label is a required field")
|
assert(type(args.label) == "string", "indicators.trilight: label is a required field")
|
||||||
assert(type(args.c1) == "number", "graphics.elements.indicators.trilight: c1 is a required field")
|
assert(type(args.c1) == "number", "indicators.trilight: c1 is a required field")
|
||||||
assert(type(args.c2) == "number", "graphics.elements.indicators.trilight: c2 is a required field")
|
assert(type(args.c2) == "number", "indicators.trilight: c2 is a required field")
|
||||||
assert(type(args.c3) == "number", "graphics.elements.indicators.trilight: c3 is a required field")
|
assert(type(args.c3) == "number", "indicators.trilight: c3 is a required field")
|
||||||
|
|
||||||
if args.flash then
|
if args.flash then
|
||||||
assert(util.is_int(args.period), "graphics.elements.indicators.trilight: period is a required field if flash is enabled")
|
assert(util.is_int(args.period), "indicators.trilight: period is a required field if flash is enabled")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
args.height = 1
|
||||||
|
|
||||||
-- determine width
|
|
||||||
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2
|
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2
|
||||||
|
|
||||||
-- flasher state
|
|
||||||
local flash_on = true
|
|
||||||
|
|
||||||
-- blit translations
|
|
||||||
local c1 = colors.toBlit(args.c1)
|
|
||||||
local c2 = colors.toBlit(args.c2)
|
|
||||||
local c3 = colors.toBlit(args.c3)
|
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- init value for initial check in on_update
|
|
||||||
e.value = 1
|
e.value = 1
|
||||||
|
|
||||||
|
local flash_on = true
|
||||||
|
|
||||||
|
local c1 = colors.toBlit(args.c1)
|
||||||
|
local c2 = colors.toBlit(args.c2)
|
||||||
|
local c3 = colors.toBlit(args.c3)
|
||||||
|
|
||||||
-- called by flasher when enabled
|
-- called by flasher when enabled
|
||||||
local function flash_callback()
|
local function flash_callback()
|
||||||
e.w_set_cur(1, 1)
|
e.w_set_cur(1, 1)
|
||||||
@ -102,9 +96,14 @@ local function tristate_indicator_light(args)
|
|||||||
---@param val integer indicator state
|
---@param val integer indicator state
|
||||||
function e.set_value(val) e.on_update(val) end
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
-- write label and initial indicator light
|
-- draw light and label
|
||||||
e.on_update(1)
|
function e.redraw()
|
||||||
e.w_write(args.label)
|
e.on_update(1)
|
||||||
|
e.w_write(args.label)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -20,13 +20,13 @@ local element = require("graphics.element")
|
|||||||
---@param args vbar_args
|
---@param args vbar_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function vbar(args)
|
local function vbar(args)
|
||||||
-- properties/state
|
|
||||||
local last_num_bars = -1
|
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- blit strings
|
e.value = 0.0
|
||||||
|
|
||||||
|
local last_num_bars = -1
|
||||||
|
|
||||||
local fgd = string.rep(e.fg_bg.blit_fgd, e.frame.w)
|
local fgd = string.rep(e.fg_bg.blit_fgd, e.frame.w)
|
||||||
local bkg = string.rep(e.fg_bg.blit_bkg, e.frame.w)
|
local bkg = string.rep(e.fg_bg.blit_bkg, e.frame.w)
|
||||||
local spaces = util.spaces(e.frame.w)
|
local spaces = util.spaces(e.frame.w)
|
||||||
@ -52,10 +52,7 @@ local function vbar(args)
|
|||||||
if num_bars ~= last_num_bars then
|
if num_bars ~= last_num_bars then
|
||||||
last_num_bars = num_bars
|
last_num_bars = num_bars
|
||||||
|
|
||||||
-- start bottom up
|
|
||||||
local y = e.frame.h
|
local y = e.frame.h
|
||||||
|
|
||||||
-- start at base of vertical bar
|
|
||||||
e.w_set_cur(1, y)
|
e.w_set_cur(1, y)
|
||||||
|
|
||||||
-- fill percentage
|
-- fill percentage
|
||||||
@ -83,22 +80,26 @@ local function vbar(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- set the percentage value
|
||||||
|
---@param val number 0.0 to 1.0
|
||||||
|
function e.set_value(val) e.on_update(val) end
|
||||||
|
|
||||||
|
-- element redraw
|
||||||
|
function e.redraw()
|
||||||
|
last_num_bars = -1
|
||||||
|
e.on_update(e.value)
|
||||||
|
end
|
||||||
|
|
||||||
-- change bar color
|
-- change bar color
|
||||||
---@param fg_bg cpair new bar colors
|
---@param fg_bg cpair new bar colors
|
||||||
function e.recolor(fg_bg)
|
function e.recolor(fg_bg)
|
||||||
fgd = string.rep(fg_bg.blit_fgd, e.frame.w)
|
fgd = string.rep(fg_bg.blit_fgd, e.frame.w)
|
||||||
bkg = string.rep(fg_bg.blit_bkg, e.frame.w)
|
bkg = string.rep(fg_bg.blit_bkg, e.frame.w)
|
||||||
|
e.redraw()
|
||||||
-- re-draw
|
|
||||||
last_num_bars = 0
|
|
||||||
if type(e.value) == "number" then
|
|
||||||
e.on_update(e.value)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set the percentage value
|
-- initial draw
|
||||||
---@param val number 0.0 to 1.0
|
e.redraw()
|
||||||
function e.set_value(val) e.on_update(val) end
|
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -274,8 +274,20 @@ local function listbox(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
draw_arrows(0)
|
-- element redraw
|
||||||
draw_bar()
|
function e.redraw()
|
||||||
|
draw_arrows(0)
|
||||||
|
draw_bar()
|
||||||
|
|
||||||
|
-- redraw all children
|
||||||
|
for i = 1, #list do
|
||||||
|
local item = list[i] ---@type listbox_item
|
||||||
|
item.e.redraw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -19,23 +19,30 @@ local element = require("graphics.element")
|
|||||||
---@param args multipane_args
|
---@param args multipane_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function multipane(args)
|
local function multipane(args)
|
||||||
assert(type(args.panes) == "table", "graphics.elements.multipane: panes is a required field")
|
assert(type(args.panes) == "table", "multipane: panes is a required field")
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = 1
|
||||||
|
|
||||||
|
-- show the selected pane
|
||||||
|
function e.redraw()
|
||||||
|
for i = 1, #args.panes do args.panes[i].hide() end
|
||||||
|
args.panes[e.value].show()
|
||||||
|
end
|
||||||
|
|
||||||
-- select which pane is shown
|
-- select which pane is shown
|
||||||
---@param value integer pane to show
|
---@param value integer pane to show
|
||||||
function e.set_value(value)
|
function e.set_value(value)
|
||||||
if (e.value ~= value) and (value > 0) and (value <= #args.panes) then
|
if (e.value ~= value) and (value > 0) and (value <= #args.panes) then
|
||||||
e.value = value
|
e.value = value
|
||||||
|
e.redraw()
|
||||||
for i = 1, #args.panes do args.panes[i].hide() end
|
|
||||||
args.panes[value].show()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
e.set_value(1)
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
@ -24,12 +24,11 @@ local element = require("graphics.element")
|
|||||||
---@param args pipenet_args
|
---@param args pipenet_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function pipenet(args)
|
local function pipenet(args)
|
||||||
assert(type(args.pipes) == "table", "graphics.elements.indicators.pipenet: pipes is a required field")
|
assert(type(args.pipes) == "table", "pipenet: pipes is a required field")
|
||||||
|
|
||||||
args.width = 0
|
args.width = 0
|
||||||
args.height = 0
|
args.height = 0
|
||||||
|
|
||||||
-- determine width/height
|
|
||||||
for i = 1, #args.pipes do
|
for i = 1, #args.pipes do
|
||||||
local pipe = args.pipes[i] ---@type pipe
|
local pipe = args.pipes[i] ---@type pipe
|
||||||
|
|
||||||
@ -57,8 +56,8 @@ local function pipenet(args)
|
|||||||
if any_thin then break end
|
if any_thin then break end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not any_thin then
|
-- draw all pipes by drawing out lines
|
||||||
-- draw all pipes
|
local function vector_draw()
|
||||||
for p = 1, #args.pipes do
|
for p = 1, #args.pipes do
|
||||||
local pipe = args.pipes[p] ---@type pipe
|
local pipe = args.pipes[p] ---@type pipe
|
||||||
|
|
||||||
@ -161,11 +160,109 @@ local function pipenet(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
end
|
||||||
-- build map if using thin pipes, easist way to check adjacent blocks (cannot 'cheat' like with standard width)
|
|
||||||
|
-- draw a particular map cell
|
||||||
|
---@param map table 2D cell map
|
||||||
|
---@param x integer x coord
|
||||||
|
---@param y integer y coord
|
||||||
|
local function draw_map_cell(map, x, y)
|
||||||
|
local entry = map[x][y] ---@type _pipe_map_entry already confirmed not false
|
||||||
|
local char
|
||||||
|
local invert = false
|
||||||
|
|
||||||
|
local function check(cx, cy)
|
||||||
|
return (map[cx] ~= nil) and (map[cx][cy] ~= nil) and (map[cx][cy] ~= false) and (map[cx][cy].fg == entry.fg)
|
||||||
|
end
|
||||||
|
|
||||||
|
if entry.thin then
|
||||||
|
if check(x - 1, y) then -- if left
|
||||||
|
if check(x, y - 1) then -- if above
|
||||||
|
if check(x + 1, y) then -- if right
|
||||||
|
if check(x, y + 1) then -- if below
|
||||||
|
char = util.trinary(entry.atr, "\x91", "\x9d")
|
||||||
|
invert = entry.atr
|
||||||
|
else -- not below
|
||||||
|
char = util.trinary(entry.atr, "\x8e", "\x8d")
|
||||||
|
end
|
||||||
|
else -- not right
|
||||||
|
if check(x, y + 1) then -- if below
|
||||||
|
char = util.trinary(entry.atr, "\x91", "\x95")
|
||||||
|
invert = entry.atr
|
||||||
|
else -- not below
|
||||||
|
char = util.trinary(entry.atr, "\x8e", "\x85")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif check(x, y + 1) then-- not above, if below
|
||||||
|
if check(x + 1, y) then -- if right
|
||||||
|
char = util.trinary(entry.atr, "\x93", "\x9c")
|
||||||
|
invert = entry.atr
|
||||||
|
else -- not right
|
||||||
|
char = util.trinary(entry.atr, "\x93", "\x94")
|
||||||
|
invert = entry.atr
|
||||||
|
end
|
||||||
|
else -- not above, not below
|
||||||
|
char = "\x8c"
|
||||||
|
end
|
||||||
|
elseif check(x + 1, y) then -- not left, if right
|
||||||
|
if check(x, y - 1) then -- if above
|
||||||
|
if check(x, y + 1) then -- if below
|
||||||
|
char = util.trinary(entry.atr, "\x95", "\x9d")
|
||||||
|
invert = entry.atr
|
||||||
|
else -- not below
|
||||||
|
char = util.trinary(entry.atr, "\x8a", "\x8d")
|
||||||
|
end
|
||||||
|
else -- not above
|
||||||
|
if check(x, y + 1) then -- if below
|
||||||
|
char = util.trinary(entry.atr, "\x97", "\x9c")
|
||||||
|
invert = entry.atr
|
||||||
|
else -- not below
|
||||||
|
char = "\x8c"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else -- not left, not right
|
||||||
|
char = "\x95"
|
||||||
|
invert = entry.atr
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if check(x, y - 1) then -- above
|
||||||
|
-- not below and (if left or right)
|
||||||
|
if (not check(x, y + 1)) and (check(x - 1, y) or check(x + 1, y)) then
|
||||||
|
char = util.trinary(entry.atr, "\x8f", " ")
|
||||||
|
invert = not entry.atr
|
||||||
|
else -- not below w/ sides only
|
||||||
|
char = " "
|
||||||
|
invert = true
|
||||||
|
end
|
||||||
|
elseif check(x, y + 1) then -- not above, if below
|
||||||
|
-- if left or right
|
||||||
|
if (check(x - 1, y) or check(x + 1, y)) then
|
||||||
|
char = "\x83"
|
||||||
|
invert = true
|
||||||
|
else -- not left or right
|
||||||
|
char = " "
|
||||||
|
invert = true
|
||||||
|
end
|
||||||
|
else -- not above, not below
|
||||||
|
char = util.trinary(entry.atr, "\x8f", "\x83")
|
||||||
|
invert = not entry.atr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
e.w_set_cur(x, y)
|
||||||
|
|
||||||
|
if invert then
|
||||||
|
e.w_blit(char, entry.bg, entry.fg)
|
||||||
|
else
|
||||||
|
e.w_blit(char, entry.fg, entry.bg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- draw all pipes by assembling and marking up a 2D map<br>
|
||||||
|
-- this is an easy way to check adjacent blocks, which is required to properly draw thin pipes
|
||||||
|
local function map_draw()
|
||||||
local map = {}
|
local map = {}
|
||||||
|
|
||||||
-- allocate map
|
|
||||||
for x = 1, args.width do
|
for x = 1, args.width do
|
||||||
table.insert(map, {})
|
table.insert(map, {})
|
||||||
for _ = 1, args.height do table.insert(map[x], false) end
|
for _ = 1, args.height do table.insert(map[x], false) end
|
||||||
@ -215,101 +312,19 @@ local function pipenet(args)
|
|||||||
-- render
|
-- render
|
||||||
for x = 1, args.width do
|
for x = 1, args.width do
|
||||||
for y = 1, args.height do
|
for y = 1, args.height do
|
||||||
local entry = map[x][y] ---@type _pipe_map_entry|false
|
if map[x][y] ~= false then draw_map_cell(map, x, y) end
|
||||||
local char
|
|
||||||
local invert = false
|
|
||||||
|
|
||||||
if entry ~= false then
|
|
||||||
local function check(cx, cy)
|
|
||||||
return (map[cx] ~= nil) and (map[cx][cy] ~= nil) and (map[cx][cy] ~= false) and (map[cx][cy].fg == entry.fg)
|
|
||||||
end
|
|
||||||
|
|
||||||
if entry.thin then
|
|
||||||
if check(x - 1, y) then -- if left
|
|
||||||
if check(x, y - 1) then -- if above
|
|
||||||
if check(x + 1, y) then -- if right
|
|
||||||
if check(x, y + 1) then -- if below
|
|
||||||
char = util.trinary(entry.atr, "\x91", "\x9d")
|
|
||||||
invert = entry.atr
|
|
||||||
else -- not below
|
|
||||||
char = util.trinary(entry.atr, "\x8e", "\x8d")
|
|
||||||
end
|
|
||||||
else -- not right
|
|
||||||
if check(x, y + 1) then -- if below
|
|
||||||
char = util.trinary(entry.atr, "\x91", "\x95")
|
|
||||||
invert = entry.atr
|
|
||||||
else -- not below
|
|
||||||
char = util.trinary(entry.atr, "\x8e", "\x85")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif check(x, y + 1) then-- not above, if below
|
|
||||||
if check(x + 1, y) then -- if right
|
|
||||||
char = util.trinary(entry.atr, "\x93", "\x9c")
|
|
||||||
invert = entry.atr
|
|
||||||
else -- not right
|
|
||||||
char = util.trinary(entry.atr, "\x93", "\x94")
|
|
||||||
invert = entry.atr
|
|
||||||
end
|
|
||||||
else -- not above, not below
|
|
||||||
char = "\x8c"
|
|
||||||
end
|
|
||||||
elseif check(x + 1, y) then -- not left, if right
|
|
||||||
if check(x, y - 1) then -- if above
|
|
||||||
if check(x, y + 1) then -- if below
|
|
||||||
char = util.trinary(entry.atr, "\x95", "\x9d")
|
|
||||||
invert = entry.atr
|
|
||||||
else -- not below
|
|
||||||
char = util.trinary(entry.atr, "\x8a", "\x8d")
|
|
||||||
end
|
|
||||||
else -- not above
|
|
||||||
if check(x, y + 1) then -- if below
|
|
||||||
char = util.trinary(entry.atr, "\x97", "\x9c")
|
|
||||||
invert = entry.atr
|
|
||||||
else -- not below
|
|
||||||
char = "\x8c"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else -- not left, not right
|
|
||||||
char = "\x95"
|
|
||||||
invert = entry.atr
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if check(x, y - 1) then -- above
|
|
||||||
-- not below and (if left or right)
|
|
||||||
if (not check(x, y + 1)) and (check(x - 1, y) or check(x + 1, y)) then
|
|
||||||
char = util.trinary(entry.atr, "\x8f", " ")
|
|
||||||
invert = not entry.atr
|
|
||||||
else -- not below w/ sides only
|
|
||||||
char = " "
|
|
||||||
invert = true
|
|
||||||
end
|
|
||||||
elseif check(x, y + 1) then -- not above, if below
|
|
||||||
-- if left or right
|
|
||||||
if (check(x - 1, y) or check(x + 1, y)) then
|
|
||||||
char = "\x83"
|
|
||||||
invert = true
|
|
||||||
else -- not left or right
|
|
||||||
char = " "
|
|
||||||
invert = true
|
|
||||||
end
|
|
||||||
else -- not above, not below
|
|
||||||
char = util.trinary(entry.atr, "\x8f", "\x83")
|
|
||||||
invert = not entry.atr
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
e.w_set_cur(x, y)
|
|
||||||
|
|
||||||
if invert then
|
|
||||||
e.w_blit(char, entry.bg, entry.fg)
|
|
||||||
else
|
|
||||||
e.w_blit(char, entry.fg, entry.bg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- element redraw
|
||||||
|
function e.redraw()
|
||||||
|
if any_thin then map_draw() else vector_draw() end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ local element = require("graphics.element")
|
|||||||
---@param args rectangle_args
|
---@param args rectangle_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function rectangle(args)
|
local function rectangle(args)
|
||||||
assert(args.border ~= nil or args.thin ~= true, "graphics.elements.rectangle: thin requires border to be provided")
|
assert(args.border ~= nil or args.thin ~= true, "rectangle: thin requires border to be provided")
|
||||||
|
|
||||||
-- if thin, then width will always need to be 1
|
-- if thin, then width will always need to be 1
|
||||||
if args.thin == true then
|
if args.thin == true then
|
||||||
@ -65,8 +65,8 @@ local function rectangle(args)
|
|||||||
local inner_width = e.frame.w - width_x2
|
local inner_width = e.frame.w - width_x2
|
||||||
|
|
||||||
-- check dimensions
|
-- check dimensions
|
||||||
assert(width_x2 <= e.frame.w, "graphics.elements.rectangle: border too thick for width")
|
assert(width_x2 <= e.frame.w, "rectangle: border too thick for width")
|
||||||
assert(width_x2 <= e.frame.h, "graphics.elements.rectangle: border too thick for height")
|
assert(width_x2 <= e.frame.h, "rectangle: border too thick for height")
|
||||||
|
|
||||||
-- form the basic line strings and top/bottom blit strings
|
-- form the basic line strings and top/bottom blit strings
|
||||||
local spaces = util.spaces(e.frame.w)
|
local spaces = util.spaces(e.frame.w)
|
||||||
@ -126,64 +126,69 @@ local function rectangle(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- draw rectangle with borders
|
-- draw rectangle with borders
|
||||||
for y = 1, e.frame.h do
|
function e.redraw()
|
||||||
e.w_set_cur(1, y)
|
for y = 1, e.frame.h do
|
||||||
-- top border
|
e.w_set_cur(1, y)
|
||||||
if y <= border_height then
|
-- top border
|
||||||
-- partial pixel fill
|
if y <= border_height then
|
||||||
if args.border.even and y == border_height then
|
-- partial pixel fill
|
||||||
if args.thin == true then
|
if args.border.even and y == border_height then
|
||||||
e.w_blit(p_a, p_inv_bg, p_inv_fg)
|
if args.thin == true then
|
||||||
else
|
e.w_blit(p_a, p_inv_bg, p_inv_fg)
|
||||||
local _fg = util.trinary(args.even_inner == true, string.rep(e.fg_bg.blit_bkg, e.frame.w), p_inv_bg)
|
else
|
||||||
local _bg = util.trinary(args.even_inner == true, blit_bg_top_bot, p_inv_fg)
|
local _fg = util.trinary(args.even_inner == true, string.rep(e.fg_bg.blit_bkg, e.frame.w), p_inv_bg)
|
||||||
|
local _bg = util.trinary(args.even_inner == true, blit_bg_top_bot, p_inv_fg)
|
||||||
|
|
||||||
if width_x2 % 3 == 1 then
|
if width_x2 % 3 == 1 then
|
||||||
e.w_blit(p_b, _fg, _bg)
|
e.w_blit(p_b, _fg, _bg)
|
||||||
elseif width_x2 % 3 == 2 then
|
elseif width_x2 % 3 == 2 then
|
||||||
e.w_blit(p_a, _fg, _bg)
|
e.w_blit(p_a, _fg, _bg)
|
||||||
else
|
else
|
||||||
-- skip line
|
-- skip line
|
||||||
e.w_blit(spaces, blit_fg, blit_bg_sides)
|
e.w_blit(spaces, blit_fg, blit_bg_sides)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
else
|
|
||||||
e.w_blit(spaces, blit_fg, blit_bg_top_bot)
|
|
||||||
end
|
|
||||||
-- bottom border
|
|
||||||
elseif y > (e.frame.h - border_width) then
|
|
||||||
-- partial pixel fill
|
|
||||||
if args.border.even and y == ((e.frame.h - border_width) + 1) then
|
|
||||||
if args.thin == true then
|
|
||||||
if args.even_inner == true then
|
|
||||||
e.w_blit(p_b, blit_bg_top_bot, string.rep(e.fg_bg.blit_bkg, e.frame.w))
|
|
||||||
else
|
|
||||||
e.w_blit(p_b, string.rep(e.fg_bg.blit_bkg, e.frame.w), blit_bg_top_bot)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local _fg = util.trinary(args.even_inner == true, blit_bg_top_bot, p_inv_fg)
|
e.w_blit(spaces, blit_fg, blit_bg_top_bot)
|
||||||
local _bg = util.trinary(args.even_inner == true, string.rep(e.fg_bg.blit_bkg, e.frame.w), blit_bg_top_bot)
|
end
|
||||||
|
-- bottom border
|
||||||
if width_x2 % 3 == 1 then
|
elseif y > (e.frame.h - border_width) then
|
||||||
e.w_blit(p_a, _fg, _bg)
|
-- partial pixel fill
|
||||||
elseif width_x2 % 3 == 2 then
|
if args.border.even and y == ((e.frame.h - border_width) + 1) then
|
||||||
e.w_blit(p_b, _fg, _bg)
|
if args.thin == true then
|
||||||
|
if args.even_inner == true then
|
||||||
|
e.w_blit(p_b, blit_bg_top_bot, string.rep(e.fg_bg.blit_bkg, e.frame.w))
|
||||||
|
else
|
||||||
|
e.w_blit(p_b, string.rep(e.fg_bg.blit_bkg, e.frame.w), blit_bg_top_bot)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- skip line
|
local _fg = util.trinary(args.even_inner == true, blit_bg_top_bot, p_inv_fg)
|
||||||
e.w_blit(spaces, blit_fg, blit_bg_sides)
|
local _bg = util.trinary(args.even_inner == true, string.rep(e.fg_bg.blit_bkg, e.frame.w), blit_bg_top_bot)
|
||||||
|
|
||||||
|
if width_x2 % 3 == 1 then
|
||||||
|
e.w_blit(p_a, _fg, _bg)
|
||||||
|
elseif width_x2 % 3 == 2 then
|
||||||
|
e.w_blit(p_b, _fg, _bg)
|
||||||
|
else
|
||||||
|
-- skip line
|
||||||
|
e.w_blit(spaces, blit_fg, blit_bg_sides)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
e.w_blit(spaces, blit_fg, blit_bg_top_bot)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
e.w_blit(spaces, blit_fg, blit_bg_top_bot)
|
if args.thin == true then
|
||||||
end
|
e.w_blit(p_s, blit_fg_sides, blit_bg_sides)
|
||||||
else
|
else
|
||||||
if args.thin == true then
|
e.w_blit(p_s, blit_fg, blit_bg_sides)
|
||||||
e.w_blit(p_s, blit_fg_sides, blit_bg_sides)
|
end
|
||||||
else
|
|
||||||
e.w_blit(p_s, blit_fg, blit_bg_sides)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- initial draw of border
|
||||||
|
e.redraw()
|
||||||
end
|
end
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
|
@ -24,19 +24,20 @@ local TEXT_ALIGN = core.TEXT_ALIGN
|
|||||||
---@param args textbox_args
|
---@param args textbox_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function textbox(args)
|
local function textbox(args)
|
||||||
assert(type(args.text) == "string", "graphics.elements.textbox: text is a required field")
|
assert(type(args.text) == "string", "textbox: text is a required field")
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
|
e.value = args.text
|
||||||
|
|
||||||
local alignment = args.alignment or TEXT_ALIGN.LEFT
|
local alignment = args.alignment or TEXT_ALIGN.LEFT
|
||||||
|
|
||||||
-- draw textbox
|
-- draw textbox
|
||||||
|
function e.redraw()
|
||||||
|
e.window.clear()
|
||||||
|
|
||||||
local function display_text(text)
|
local lines = util.strwrap(e.value, e.frame.w)
|
||||||
e.value = text
|
|
||||||
|
|
||||||
local lines = util.strwrap(text, e.frame.w)
|
|
||||||
|
|
||||||
for i = 1, #lines do
|
for i = 1, #lines do
|
||||||
if i > e.frame.h then break end
|
if i > e.frame.h then break end
|
||||||
@ -56,15 +57,16 @@ local function textbox(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
display_text(args.text)
|
|
||||||
|
|
||||||
-- set the string value and re-draw the text
|
-- set the string value and re-draw the text
|
||||||
---@param val string value
|
---@param val string value
|
||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
e.window.clear()
|
e.value = val
|
||||||
display_text(val)
|
e.redraw()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,13 +22,11 @@ local element = require("graphics.element")
|
|||||||
---@param args tiling_args
|
---@param args tiling_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function tiling(args)
|
local function tiling(args)
|
||||||
assert(type(args.fill_c) == "table", "graphics.elements.tiling: fill_c is a required field")
|
assert(type(args.fill_c) == "table", "tiling: fill_c is a required field")
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
-- draw tiling box
|
|
||||||
|
|
||||||
local fill_a = args.fill_c.blit_a
|
local fill_a = args.fill_c.blit_a
|
||||||
local fill_b = args.fill_c.blit_b
|
local fill_b = args.fill_c.blit_b
|
||||||
|
|
||||||
@ -38,13 +36,9 @@ local function tiling(args)
|
|||||||
local start_y = 1
|
local start_y = 1
|
||||||
local inner_width = math.floor(e.frame.w / util.trinary(even, 2, 1))
|
local inner_width = math.floor(e.frame.w / util.trinary(even, 2, 1))
|
||||||
local inner_height = e.frame.h
|
local inner_height = e.frame.h
|
||||||
local alternator = true
|
|
||||||
|
|
||||||
-- border
|
-- border
|
||||||
if args.border_c ~= nil then
|
if args.border_c ~= nil then
|
||||||
e.w_set_bkg(args.border_c)
|
|
||||||
e.window.clear()
|
|
||||||
|
|
||||||
start_x = 1 + util.trinary(even, 2, 1)
|
start_x = 1 + util.trinary(even, 2, 1)
|
||||||
start_y = 2
|
start_y = 2
|
||||||
|
|
||||||
@ -53,35 +47,48 @@ local function tiling(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check dimensions
|
-- check dimensions
|
||||||
assert(inner_width > 0, "graphics.elements.tiling: inner_width <= 0")
|
assert(inner_width > 0, "tiling: inner_width <= 0")
|
||||||
assert(inner_height > 0, "graphics.elements.tiling: inner_height <= 0")
|
assert(inner_height > 0, "tiling: inner_height <= 0")
|
||||||
assert(start_x <= inner_width, "graphics.elements.tiling: start_x > inner_width")
|
assert(start_x <= inner_width, "tiling: start_x > inner_width")
|
||||||
assert(start_y <= inner_height, "graphics.elements.tiling: start_y > inner_height")
|
assert(start_y <= inner_height, "tiling: start_y > inner_height")
|
||||||
|
|
||||||
-- create pattern
|
-- draw tiling box
|
||||||
for y = start_y, inner_height + (start_y - 1) do
|
function e.redraw()
|
||||||
e.w_set_cur(start_x, y)
|
local alternator = true
|
||||||
for _ = 1, inner_width do
|
|
||||||
if alternator then
|
|
||||||
if even then
|
|
||||||
e.w_blit(" ", "00", fill_a .. fill_a)
|
|
||||||
else
|
|
||||||
e.w_blit(" ", "0", fill_a)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if even then
|
|
||||||
e.w_blit(" ", "00", fill_b .. fill_b)
|
|
||||||
else
|
|
||||||
e.w_blit(" ", "0", fill_b)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
alternator = not alternator
|
if args.border_c ~= nil then
|
||||||
|
e.w_set_bkg(args.border_c)
|
||||||
|
e.window.clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
if inner_width % 2 == 0 then alternator = not alternator end
|
-- draw pattern
|
||||||
|
for y = start_y, inner_height + (start_y - 1) do
|
||||||
|
e.w_set_cur(start_x, y)
|
||||||
|
for _ = 1, inner_width do
|
||||||
|
if alternator then
|
||||||
|
if even then
|
||||||
|
e.w_blit(" ", "00", fill_a .. fill_a)
|
||||||
|
else
|
||||||
|
e.w_blit(" ", "0", fill_a)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if even then
|
||||||
|
e.w_blit(" ", "00", fill_b .. fill_b)
|
||||||
|
else
|
||||||
|
e.w_blit(" ", "0", fill_b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alternator = not alternator
|
||||||
|
end
|
||||||
|
|
||||||
|
if inner_width % 2 == 0 then alternator = not alternator end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
e.redraw()
|
||||||
|
|
||||||
return e.complete()
|
return e.complete()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user