#91 get and set values for all controls/indicators and textbox

This commit is contained in:
Mikayla Fischler 2022-09-12 12:59:28 -04:00
parent d9be5ccb47
commit 10c53ac4b3
16 changed files with 192 additions and 60 deletions

View File

@ -37,6 +37,7 @@ function element.new(args)
---@class graphics_template
local protected = {
value = nil, ---@type any
window = nil, ---@type table
fg_bg = core.graphics.cpair(colors.white, colors.black),
frame = core.graphics.gframe(1, 1, 1, 1)
@ -136,11 +137,27 @@ function element.new(args)
function protected.on_update(...)
end
-- get control value
-- get value
function protected.get_value()
return protected.value
end
-- set value
---@param value any value to set
function protected.set_value(value)
return nil
end
-- custom recolor command, varies by element if implemented
---@vararg cpair|color color(s)
function protected.recolor(...)
end
-- custom resize command, varies by element if implemented
---@vararg integer sizing
function protected.resize(...)
end
-- start animations
function protected.start_anim()
end

View File

@ -1,6 +1,7 @@
-- Button Graphics Element
local element = require("graphics.element")
local util = require("scada-common.util")
---@class button_option
@ -33,9 +34,6 @@ local function multi_button(args)
-- single line
args.height = 3
-- button state (convert nil to 1 if missing)
local state = args.default or 1
-- determine widths
local max_width = 1
for i = 1, #args.options do
@ -52,6 +50,9 @@ local function multi_button(args)
-- create new graphics element base object
local e = element.new(args)
-- button state (convert nil to 1 if missing)
e.value = args.default or 1
-- calculate required button information
local next_x = 2
for i = 1, #args.options do
@ -72,7 +73,7 @@ local function multi_button(args)
e.window.setCursorPos(opt._start_x, 2)
if state == i then
if e.value == i then
-- show as pressed
e.window.setTextColor(opt.active_fg_bg.fgd)
e.window.setBackgroundColor(opt.active_fg_bg.bkg)
@ -86,9 +87,6 @@ local function multi_button(args)
end
end
-- initial draw
draw()
-- handle touch
---@param event monitor_touch monitor touch event
function e.handle_touch(event)
@ -98,14 +96,25 @@ local function multi_button(args)
local opt = args.options[i] ---@type button_option
if event.x >= opt._start_x and event.x <= opt._end_x then
state = i
e.value = i
draw()
args.callback(state)
args.callback(e.value)
end
end
end
end
-- set the value
---@param val integer new value
function e.set_value(val)
e.value = val
draw()
args.callback(e.value)
end
-- initial draw
draw()
return e.get()
end

View File

@ -2,6 +2,7 @@
local tcd = require("scada-common.tcallbackdsp")
local core = require("graphics.core")
local element = require("graphics.element")
---@class push_button_args
@ -52,12 +53,14 @@ local function push_button(args)
function e.handle_touch(event)
if args.active_fg_bg ~= nil then
-- show as pressed
e.value = true
e.window.setTextColor(args.active_fg_bg.fgd)
e.window.setBackgroundColor(args.active_fg_bg.bkg)
draw()
-- show as unpressed in 0.25 seconds
tcd.dispatch(0.25, function ()
e.value = false
e.window.setTextColor(e.fg_bg.fgd)
e.window.setBackgroundColor(e.fg_bg.bkg)
draw()
@ -68,6 +71,12 @@ local function push_button(args)
args.callback()
end
-- set the value
---@param val boolean new value
function e.set_value(val)
if val then e.handle_touch(core.events.touch("", 1, 1)) end
end
-- initial draw
draw()

View File

@ -3,7 +3,6 @@
local tcd = require("scada-common.tcallbackdsp")
local core = require("graphics.core")
local element = require("graphics.element")
---@class scram_button_args
@ -65,6 +64,12 @@ local function scram_button(args)
args.callback()
end
-- set the value
---@param val boolean new value
function e.set_value(val)
if val then e.handle_touch(core.events.touch("", 1, 1)) end
end
return e.get()
end

View File

@ -1,6 +1,7 @@
-- Spinbox Numeric Graphics Element
local element = require("graphics.element")
local util = require("scada-common.util")
---@class spinbox_args
@ -19,7 +20,6 @@ local util = require("scada-common.util")
---@return graphics_element element, element_id id
local function spinbox(args)
-- properties
local value = args.default or 0.0
local digits = {}
local wn_prec = args.whole_num_precision
local fr_prec = args.fractional_precision
@ -33,11 +33,6 @@ local function spinbox(args)
assert(type(args.arrow_fg_bg) == "table", "graphics.element.spinbox_numeric: arrow_fg_bg is a required field")
local initial_str = util.sprintf(fmt_init, value)
---@diagnostic disable-next-line: discard-returns
initial_str:gsub("%d", function(char) table.insert(digits, char) end)
-- determine widths
args.width = wn_prec + fr_prec + util.trinary(fr_prec > 0, 1, 0)
args.height = 3
@ -45,6 +40,14 @@ local function spinbox(args)
-- create new graphics element base object
local e = element.new(args)
-- set initial value
e.value = args.default or 0.0
local initial_str = util.sprintf(fmt_init, e.value)
---@diagnostic disable-next-line: discard-returns
initial_str:gsub("%d", function (char) table.insert(digits, char) end)
-- draw the arrows
e.window.setBackgroundColor(args.arrow_fg_bg.bkg)
e.window.setTextColor(args.arrow_fg_bg.fgd)
@ -62,7 +65,7 @@ local function spinbox(args)
-- zero the value
local function zero()
for i = 1, #digits do digits[i] = 0 end
value = 0
e.value = 0
end
-- print out the current value
@ -70,7 +73,42 @@ local function spinbox(args)
e.window.setBackgroundColor(e.fg_bg.bkg)
e.window.setTextColor(e.fg_bg.fgd)
e.window.setCursorPos(1, 2)
e.window.write(util.sprintf(fmt, value))
e.window.write(util.sprintf(fmt, e.value))
end
-- update the value per digits table
local function update_value()
e.value = 0
for i = 1, #digits do
local pow = math.abs(wn_prec - i)
if i <= wn_prec then
e.value = e.value + (digits[i] * (10 ^ pow))
else
e.value = e.value + (digits[i] * (10 ^ -pow))
end
end
end
-- enforce numeric limits
local function enforce_limits()
-- min 0
if e.value < 0 then
zero()
-- max printable
elseif string.len(util.sprintf(fmt, e.value)) > args.width then
-- max out
for i = 1, #digits do digits[i] = 9 end
-- re-update value
update_value()
end
end
-- update value and show
local function parse_and_show()
update_value()
enforce_limits()
show_num()
end
-- init with the default value
@ -90,27 +128,16 @@ local function spinbox(args)
digits[idx] = digits[idx] - 1
end
-- update value
value = 0
for i = 1, #digits do
local pow = math.abs(wn_prec - i)
if i <= wn_prec then
value = value + (digits[i] * (10 ^ pow))
else
value = value + (digits[i] * (10 ^ -pow))
parse_and_show()
end
end
-- min 0
if value < 0 then zero() end
show_num()
-- set the value
---@param val number number to show
function e.set_value(val)
e.value = val
parse_and_show()
end
end
-- get current value
---@return number|integer
function e.get_value() return value end
return e.get()
end

View File

@ -3,7 +3,6 @@
local tcd = require("scada-common.tcallbackdsp")
local core = require("graphics.core")
local element = require("graphics.element")
---@class start_button_args
@ -65,6 +64,12 @@ local function start_button(args)
args.callback()
end
-- set the value
---@param val boolean new value
function e.set_value(val)
if val then e.handle_touch(core.events.touch("", 1, 1)) end
end
return e.get()
end

View File

@ -26,9 +26,6 @@ local function switch_button(args)
-- single line
args.height = 1
-- button state (convert nil to false if missing)
local state = args.default or false
-- determine widths
local text_width = string.len(args.text)
args.width = math.max(text_width + 2, args.min_width)
@ -36,12 +33,15 @@ local function switch_button(args)
-- create new graphics element base object
local e = element.new(args)
-- button state (convert nil to false if missing)
e.value = args.default or false
local h_pad = math.floor((e.frame.w - text_width) / 2)
local v_pad = math.floor(e.frame.h / 2) + 1
-- show the button state
local function draw_state()
if state then
if e.value then
-- show as pressed
e.window.setTextColor(args.active_fg_bg.fgd)
e.window.setBackgroundColor(args.active_fg_bg.bkg)
@ -64,11 +64,22 @@ local function switch_button(args)
---@diagnostic disable-next-line: unused-local
function e.handle_touch(event)
-- toggle state
state = not state
e.value = not e.value
draw_state()
-- call the touch callback with state
args.callback(state)
args.callback(e.value)
end
-- set the value
---@param val boolean new value
function e.set_value(val)
-- set state
e.value = val
draw_state()
-- call the touch callback with state
args.callback(e.value)
end
return e.get()

View File

@ -116,15 +116,18 @@ local function core_map(args)
end
end
-- initial draw at base temp
draw(300)
-- on state change
---@param temperature number temperature in Kelvin
function e.on_update(temperature)
e.value = temperature
draw(temperature)
end
function e.set_value(val) e.on_update(val) end
-- initial draw at base temp
e.on_update(300)
return e.get()
end

View File

@ -70,6 +70,8 @@ local function data(args)
-- on state change
---@param value any new value
function e.on_update(value)
e.value = value
local data_str = util.sprintf(args.format, value)
-- write data
@ -90,6 +92,8 @@ local function data(args)
end
end
function e.set_value(val) e.on_update(val) end
-- initial value draw
e.on_update(args.value)

View File

@ -42,6 +42,8 @@ local function hbar(args)
-- handle data changes
function e.on_update(fraction)
e.value = fraction
-- enforce minimum and maximum
if fraction < 0 then
fraction = 0.0
@ -96,6 +98,18 @@ local function hbar(args)
end
end
---@param bar_fg_bg cpair new bar colors
function e.recolor(bar_fg_bg)
bar_bkg = bar_fg_bg.blit_bkg
bar_fgd = bar_fg_bg.blit_fgd
-- re-draw
last_num_bars = 0
e.on_update(e.value)
end
function e.set_value(val) e.on_update(val) end
-- initialize to 0
e.on_update(0)

View File

@ -55,10 +55,13 @@ local function icon(args)
---@param new_state integer indicator state
function e.on_update(new_state)
local blit_cmd = state_blit_cmds[new_state]
e.value = new_state
e.window.setCursorPos(1, 1)
e.window.blit(blit_cmd.text, blit_cmd.fgd, blit_cmd.bkg)
end
function e.set_value(val) e.on_update(val) end
-- initial icon draw
e.on_update(args.value or 1)

View File

@ -31,6 +31,7 @@ local function indicator_light(args)
-- on state change
---@param new_state boolean indicator state
function e.on_update(new_state)
e.value = new_state
e.window.setCursorPos(1, 1)
if new_state then
e.window.blit(" \x95", "0" .. args.colors.blit_a, args.colors.blit_a .. e.fg_bg.blit_bkg)
@ -39,6 +40,8 @@ local function indicator_light(args)
end
end
function e.set_value(val) e.on_update(val) end
-- write label and initial indicator light
e.on_update(false)
e.window.write(args.label)

View File

@ -61,10 +61,13 @@ local function state_indicator(args)
---@param new_state integer indicator state
function e.on_update(new_state)
local blit_cmd = state_blit_cmds[new_state]
e.value = new_state
e.window.setCursorPos(1, 1)
e.window.blit(blit_cmd.text, blit_cmd.fgd, blit_cmd.bkg)
end
function e.set_value(val) e.on_update(val) end
-- initial draw
e.on_update(args.value or 1)

View File

@ -40,6 +40,7 @@ local function tristate_indicator_light(args)
-- on state change
---@param new_state integer indicator state
function e.on_update(new_state)
e.value = new_state
e.window.setCursorPos(1, 1)
if new_state == 2 then
e.window.blit(" \x95", "0" .. c2, c2 .. e.fg_bg.blit_bkg)
@ -50,6 +51,8 @@ local function tristate_indicator_light(args)
end
end
function e.set_value(val) e.on_update(val) end
-- write label and initial indicator light
e.on_update(0)
e.window.write(args.label)

View File

@ -33,6 +33,8 @@ local function vbar(args)
-- handle data changes
function e.on_update(fraction)
e.value = fraction
-- enforce minimum and maximum
if fraction < 0 then
fraction = 0.0
@ -78,6 +80,8 @@ local function vbar(args)
end
end
function e.set_value(val) e.on_update(val) end
return e.get()
end

View File

@ -32,7 +32,9 @@ local function textbox(args)
-- draw textbox
local text = args.text
local function display_text(text)
e.value = text
local lines = util.strwrap(text, e.frame.w)
for i = 1, #lines do
@ -51,6 +53,16 @@ local function textbox(args)
e.window.write(lines[i])
end
end
display_text(args.text)
-- set the string value and re-draw the text
---@param val string value
function e.set_value(val)
e.window.clear()
display_text(val)
end
return e.get()
end