mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
Merge pull request #230 from MikaylaFischler/graphics-rearchitect
Graphics Rearchitect Part 1: Mouse Events
This commit is contained in:
commit
b430a22f08
@ -163,9 +163,9 @@ end
|
|||||||
function renderer.ui_ready() return engine.ui_ready end
|
function renderer.ui_ready() return engine.ui_ready end
|
||||||
|
|
||||||
-- handle a touch event
|
-- handle a touch event
|
||||||
---@param event mouse_interaction
|
---@param event mouse_interaction|nil
|
||||||
function renderer.handle_mouse(event)
|
function renderer.handle_mouse(event)
|
||||||
if engine.ui_ready then
|
if engine.ui_ready and event ~= nil then
|
||||||
if event.monitor == engine.monitors.primary_name then
|
if event.monitor == engine.monitors.primary_name then
|
||||||
engine.ui.main_display.handle_mouse(event)
|
engine.ui.main_display.handle_mouse(event)
|
||||||
else
|
else
|
||||||
|
@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder")
|
|||||||
|
|
||||||
local apisessions = require("coordinator.session.apisessions")
|
local apisessions = require("coordinator.session.apisessions")
|
||||||
|
|
||||||
local COORDINATOR_VERSION = "v0.13.8"
|
local COORDINATOR_VERSION = "v0.14.0"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
@ -359,7 +359,7 @@ local function main()
|
|||||||
end
|
end
|
||||||
elseif event == "monitor_touch" then
|
elseif event == "monitor_touch" then
|
||||||
-- handle a monitor touch event
|
-- handle a monitor touch event
|
||||||
renderer.handle_mouse(core.events.touch(param1, param2, param3))
|
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||||
elseif event == "speaker_audio_empty" then
|
elseif event == "speaker_audio_empty" then
|
||||||
-- handle speaker buffer emptied
|
-- handle speaker buffer emptied
|
||||||
sounder.continue()
|
sounder.continue()
|
||||||
|
@ -9,8 +9,8 @@ local DataIndicator = require("graphics.elements.indicators.data")
|
|||||||
local StateIndicator = require("graphics.elements.indicators.state")
|
local StateIndicator = require("graphics.elements.indicators.state")
|
||||||
local VerticalBar = require("graphics.elements.indicators.vbar")
|
local VerticalBar = require("graphics.elements.indicators.vbar")
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
local border = core.graphics.border
|
local border = core.border
|
||||||
|
|
||||||
-- new boiler view
|
-- new boiler view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -13,10 +13,10 @@ local PowerIndicator = require("graphics.elements.indicators.power")
|
|||||||
local StateIndicator = require("graphics.elements.indicators.state")
|
local StateIndicator = require("graphics.elements.indicators.state")
|
||||||
local VerticalBar = require("graphics.elements.indicators.vbar")
|
local VerticalBar = require("graphics.elements.indicators.vbar")
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
local border = core.graphics.border
|
local border = core.border
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
-- new induction matrix view
|
-- new induction matrix view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -21,10 +21,10 @@ local HazardButton = require("graphics.elements.controls.hazard_button")
|
|||||||
local RadioButton = require("graphics.elements.controls.radio_button")
|
local RadioButton = require("graphics.elements.controls.radio_button")
|
||||||
local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric")
|
local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
local border = core.graphics.border
|
local border = core.border
|
||||||
|
|
||||||
local period = core.flasher.PERIOD
|
local period = core.flasher.PERIOD
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ local DataIndicator = require("graphics.elements.indicators.data")
|
|||||||
local HorizontalBar = require("graphics.elements.indicators.hbar")
|
local HorizontalBar = require("graphics.elements.indicators.hbar")
|
||||||
local StateIndicator = require("graphics.elements.indicators.state")
|
local StateIndicator = require("graphics.elements.indicators.state")
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
local border = core.graphics.border
|
local border = core.border
|
||||||
|
|
||||||
-- create new reactor view
|
-- create new reactor view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -12,8 +12,8 @@ local PowerIndicator = require("graphics.elements.indicators.power")
|
|||||||
local StateIndicator = require("graphics.elements.indicators.state")
|
local StateIndicator = require("graphics.elements.indicators.state")
|
||||||
local VerticalBar = require("graphics.elements.indicators.vbar")
|
local VerticalBar = require("graphics.elements.indicators.vbar")
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
local border = core.graphics.border
|
local border = core.border
|
||||||
|
|
||||||
-- new turbine view
|
-- new turbine view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -26,10 +26,10 @@ local PushButton = require("graphics.elements.controls.push_button")
|
|||||||
local RadioButton = require("graphics.elements.controls.radio_button")
|
local RadioButton = require("graphics.elements.controls.radio_button")
|
||||||
local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric")
|
local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
local border = core.graphics.border
|
local border = core.border
|
||||||
|
|
||||||
local period = core.flasher.PERIOD
|
local period = core.flasher.PERIOD
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ local Div = require("graphics.elements.div")
|
|||||||
local PipeNetwork = require("graphics.elements.pipenet")
|
local PipeNetwork = require("graphics.elements.pipenet")
|
||||||
local TextBox = require("graphics.elements.textbox")
|
local TextBox = require("graphics.elements.textbox")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local pipe = core.graphics.pipe
|
local pipe = core.pipe
|
||||||
|
|
||||||
-- make a new unit overview window
|
-- make a new unit overview window
|
||||||
---@param parent graphics_element parent
|
---@param parent graphics_element parent
|
||||||
|
@ -18,9 +18,9 @@ local TextBox = require("graphics.elements.textbox")
|
|||||||
|
|
||||||
local DataIndicator = require("graphics.elements.indicators.data")
|
local DataIndicator = require("graphics.elements.indicators.data")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- create new main view
|
-- create new main view
|
||||||
---@param main graphics_element main displaybox
|
---@param main graphics_element main displaybox
|
||||||
|
@ -6,7 +6,7 @@ local core = require("graphics.core")
|
|||||||
|
|
||||||
local style = {}
|
local style = {}
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- GLOBAL --
|
-- GLOBAL --
|
||||||
|
|
||||||
|
@ -1,96 +1,19 @@
|
|||||||
--
|
--
|
||||||
-- Graphics Core Functions and Objects
|
-- Graphics Core Types, Checks, and Constructors
|
||||||
--
|
--
|
||||||
|
|
||||||
|
local events = require("graphics.events")
|
||||||
|
local flasher = require("graphics.flasher")
|
||||||
|
|
||||||
local core = {}
|
local core = {}
|
||||||
|
|
||||||
local flasher = require("graphics.flasher")
|
|
||||||
|
|
||||||
core.flasher = flasher
|
core.flasher = flasher
|
||||||
|
|
||||||
local events = {}
|
|
||||||
|
|
||||||
---@enum click_type
|
|
||||||
events.click_type = {
|
|
||||||
VIRTUAL = 0,
|
|
||||||
LEFT_BUTTON = 1,
|
|
||||||
RIGHT_BUTTON = 2,
|
|
||||||
MID_BUTTON = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
---@class mouse_interaction
|
|
||||||
---@field monitor string
|
|
||||||
---@field button integer
|
|
||||||
---@field x integer
|
|
||||||
---@field y integer
|
|
||||||
|
|
||||||
-- create a new monitor touch mouse interaction event
|
|
||||||
---@nodiscard
|
|
||||||
---@param monitor string
|
|
||||||
---@param x integer
|
|
||||||
---@param y integer
|
|
||||||
---@return mouse_interaction
|
|
||||||
function events.touch(monitor, x, y)
|
|
||||||
return {
|
|
||||||
monitor = monitor,
|
|
||||||
button = events.click_type.LEFT_BUTTON,
|
|
||||||
x = x,
|
|
||||||
y = y
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- create a new mouse click mouse interaction event
|
|
||||||
---@nodiscard
|
|
||||||
---@param button click_type
|
|
||||||
---@param x integer
|
|
||||||
---@param y integer
|
|
||||||
---@return mouse_interaction
|
|
||||||
function events.click(button, x, y)
|
|
||||||
return {
|
|
||||||
monitor = "terminal",
|
|
||||||
button = button,
|
|
||||||
x = x,
|
|
||||||
y = y
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- create a new transposed mouse interaction event using the event's monitor/button fields
|
|
||||||
---@nodiscard
|
|
||||||
---@param event mouse_interaction
|
|
||||||
---@param new_x integer
|
|
||||||
---@param new_y integer
|
|
||||||
---@return mouse_interaction
|
|
||||||
function events.mouse_transposed(event, new_x, new_y)
|
|
||||||
return {
|
|
||||||
monitor = event.monitor,
|
|
||||||
button = event.button,
|
|
||||||
x = new_x,
|
|
||||||
y = new_y
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- create a new generic mouse interaction event
|
|
||||||
---@nodiscard
|
|
||||||
---@param monitor string
|
|
||||||
---@param button click_type
|
|
||||||
---@param x integer
|
|
||||||
---@param y integer
|
|
||||||
---@return mouse_interaction
|
|
||||||
function events.mouse_generic(monitor, button, x, y)
|
|
||||||
return {
|
|
||||||
monitor = monitor,
|
|
||||||
button = button,
|
|
||||||
x = x,
|
|
||||||
y = y
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
core.events = events
|
core.events = events
|
||||||
|
|
||||||
local graphics = {}
|
-- Core Types
|
||||||
|
|
||||||
---@enum TEXT_ALIGN
|
---@enum TEXT_ALIGN
|
||||||
graphics.TEXT_ALIGN = {
|
core.TEXT_ALIGN = {
|
||||||
LEFT = 1,
|
LEFT = 1,
|
||||||
CENTER = 2,
|
CENTER = 2,
|
||||||
RIGHT = 3
|
RIGHT = 3
|
||||||
@ -109,7 +32,7 @@ graphics.TEXT_ALIGN = {
|
|||||||
---@param color color border color
|
---@param color color border color
|
||||||
---@param even? boolean whether to pad width extra to account for rectangular pixels, defaults to false
|
---@param even? boolean whether to pad width extra to account for rectangular pixels, defaults to false
|
||||||
---@return graphics_border
|
---@return graphics_border
|
||||||
function graphics.border(width, color, even)
|
function core.border(width, color, even)
|
||||||
return {
|
return {
|
||||||
width = width,
|
width = width,
|
||||||
color = color,
|
color = color,
|
||||||
@ -130,7 +53,7 @@ end
|
|||||||
---@param w integer
|
---@param w integer
|
||||||
---@param h integer
|
---@param h integer
|
||||||
---@return graphics_frame
|
---@return graphics_frame
|
||||||
function graphics.gframe(x, y, w, h)
|
function core.gframe(x, y, w, h)
|
||||||
return {
|
return {
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
@ -154,7 +77,7 @@ end
|
|||||||
---@param a color
|
---@param a color
|
||||||
---@param b color
|
---@param b color
|
||||||
---@return cpair
|
---@return cpair
|
||||||
function graphics.cpair(a, b)
|
function core.cpair(a, b)
|
||||||
return {
|
return {
|
||||||
-- color pairs
|
-- color pairs
|
||||||
color_a = a,
|
color_a = a,
|
||||||
@ -191,7 +114,7 @@ end
|
|||||||
---@param thin? boolean true for 1 subpixel, false (default) for 2
|
---@param thin? boolean true for 1 subpixel, false (default) for 2
|
||||||
---@param align_tr? boolean false to align bottom left (default), true to align top right
|
---@param align_tr? boolean false to align bottom left (default), true to align top right
|
||||||
---@return pipe
|
---@return pipe
|
||||||
function graphics.pipe(x1, y1, x2, y2, color, thin, align_tr)
|
function core.pipe(x1, y1, x2, y2, color, thin, align_tr)
|
||||||
return {
|
return {
|
||||||
x1 = x1,
|
x1 = x1,
|
||||||
y1 = y1,
|
y1 = y1,
|
||||||
@ -205,6 +128,4 @@ function graphics.pipe(x1, y1, x2, y2, color, thin, align_tr)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
core.graphics = graphics
|
|
||||||
|
|
||||||
return core
|
return core
|
||||||
|
@ -28,6 +28,7 @@ local element = {}
|
|||||||
---|sidebar_args
|
---|sidebar_args
|
||||||
---|spinbox_args
|
---|spinbox_args
|
||||||
---|switch_button_args
|
---|switch_button_args
|
||||||
|
---|tabbar_args
|
||||||
---|alarm_indicator_light
|
---|alarm_indicator_light
|
||||||
---|core_map_args
|
---|core_map_args
|
||||||
---|data_indicator_args
|
---|data_indicator_args
|
||||||
@ -60,9 +61,9 @@ function element.new(args)
|
|||||||
elem_type = debug.getinfo(2).name,
|
elem_type = debug.getinfo(2).name,
|
||||||
define_completed = false,
|
define_completed = false,
|
||||||
p_window = nil, ---@type table
|
p_window = nil, ---@type table
|
||||||
position = { x = 1, y = 1 },
|
position = { x = 1, y = 1 }, ---@type coordinate_2d
|
||||||
child_offset = { x = 0, y = 0 },
|
child_offset = { x = 0, y = 0 },
|
||||||
bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1},
|
bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1 }, ---@class element_bounds
|
||||||
next_y = 1,
|
next_y = 1,
|
||||||
children = {},
|
children = {},
|
||||||
mt = {}
|
mt = {}
|
||||||
@ -73,15 +74,26 @@ function element.new(args)
|
|||||||
enabled = true,
|
enabled = true,
|
||||||
value = nil, ---@type any
|
value = nil, ---@type any
|
||||||
window = nil, ---@type table
|
window = nil, ---@type table
|
||||||
fg_bg = core.graphics.cpair(colors.white, colors.black),
|
fg_bg = core.cpair(colors.white, colors.black),
|
||||||
frame = core.graphics.gframe(1, 1, 1, 1)
|
frame = core.gframe(1, 1, 1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local name_brief = "graphics.element{" .. self.elem_type .. "}: "
|
||||||
|
|
||||||
-- element as string
|
-- element as string
|
||||||
function self.mt.__tostring()
|
function self.mt.__tostring()
|
||||||
return "graphics.element{" .. self.elem_type .. "} @ " .. tostring(self)
|
return "graphics.element{" .. self.elem_type .. "} @ " .. tostring(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- check if a coordinate is within the bounds of this element
|
||||||
|
---@param x integer
|
||||||
|
---@param y integer
|
||||||
|
local function _in_bounds(x, y)
|
||||||
|
local in_x = x >= self.bounds.x1 and x <= self.bounds.x2
|
||||||
|
local in_y = y >= self.bounds.y1 and y <= self.bounds.y2
|
||||||
|
return in_x and in_y
|
||||||
|
end
|
||||||
|
|
||||||
---@class graphics_element
|
---@class graphics_element
|
||||||
local public = {}
|
local public = {}
|
||||||
|
|
||||||
@ -138,10 +150,10 @@ function element.new(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check frame
|
-- check frame
|
||||||
assert(f.x >= 1, "graphics.element{" .. self.elem_type .. "}: frame x not >= 1")
|
assert(f.x >= 1, name_brief .. "frame x not >= 1")
|
||||||
assert(f.y >= 1, "graphics.element{" .. self.elem_type .. "}: frame y not >= 1")
|
assert(f.y >= 1, name_brief .. "frame y not >= 1")
|
||||||
assert(f.w >= 1, "graphics.element{" .. self.elem_type .. "}: frame width not >= 1")
|
assert(f.w >= 1, name_brief .. "frame width not >= 1")
|
||||||
assert(f.h >= 1, "graphics.element{" .. self.elem_type .. "}: frame height not >= 1")
|
assert(f.h >= 1, name_brief .. "frame height not >= 1")
|
||||||
|
|
||||||
-- create window
|
-- create window
|
||||||
protected.window = window.create(self.p_window, f.x, f.y, f.w, f.h, true)
|
protected.window = window.create(self.p_window, f.x, f.y, f.w, f.h, true)
|
||||||
@ -252,7 +264,7 @@ function element.new(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check window
|
-- check window
|
||||||
assert(self.p_window, "graphics.element{" .. self.elem_type .. "}: no parent window provided")
|
assert(self.p_window, name_brief .. "no parent window provided")
|
||||||
|
|
||||||
-- prepare the template
|
-- prepare the template
|
||||||
if args.parent == nil then
|
if args.parent == nil then
|
||||||
@ -421,17 +433,18 @@ function element.new(args)
|
|||||||
-- handle a monitor touch or mouse click
|
-- handle a monitor touch or mouse click
|
||||||
---@param event mouse_interaction mouse interaction event
|
---@param event mouse_interaction mouse interaction event
|
||||||
function public.handle_mouse(event)
|
function public.handle_mouse(event)
|
||||||
local in_x = event.x >= self.bounds.x1 and event.x <= self.bounds.x2
|
local x_ini, y_ini, x_cur, y_cur = event.initial.x, event.initial.y, event.current.x, event.current.y
|
||||||
local in_y = event.y >= self.bounds.y1 and event.y <= self.bounds.y2
|
|
||||||
|
|
||||||
if in_x and in_y then
|
local ini_in = _in_bounds(x_ini, y_ini)
|
||||||
local event_T = core.events.mouse_transposed(event, (event.x - self.position.x) + 1, (event.y - self.position.y) + 1)
|
local cur_in = _in_bounds(x_cur, y_cur)
|
||||||
|
|
||||||
-- handle the touch event, transformed into the window frame
|
if ini_in then
|
||||||
|
local event_T = core.events.mouse_transposed(event, self.position.x, self.position.y)
|
||||||
|
if not cur_in then event_T.type = core.events.CLICK_TYPE.EXITED end
|
||||||
|
|
||||||
|
-- handle the mouse event then pass to children
|
||||||
protected.handle_mouse(event_T)
|
protected.handle_mouse(event_T)
|
||||||
|
for _, child in pairs(self.children) do child.handle_mouse(event_T) end
|
||||||
-- pass on touch event to children
|
|
||||||
for _, val in pairs(self.children) do val.handle_mouse(event_T) end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -141,8 +141,10 @@ local function hazard_button(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- handle mouse interaction
|
||||||
function e.handle_mouse(_)
|
---@param event mouse_interaction mouse event
|
||||||
|
function e.handle_mouse(event)
|
||||||
if e.enabled then
|
if e.enabled then
|
||||||
|
if core.events.was_clicked(event.type) then
|
||||||
-- change text color to indicate clicked
|
-- change text color to indicate clicked
|
||||||
e.window.setTextColor(args.accent)
|
e.window.setTextColor(args.accent)
|
||||||
e.window.setCursorPos(3, 2)
|
e.window.setCursorPos(3, 2)
|
||||||
@ -160,23 +162,19 @@ local function hazard_button(args)
|
|||||||
args.callback()
|
args.callback()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- callback on request response
|
-- callback on request response
|
||||||
---@param result boolean true for success, false for failure
|
---@param result boolean true for success, false for failure
|
||||||
function e.response_callback(result)
|
function e.response_callback(result)
|
||||||
tcd.abort(on_timeout)
|
tcd.abort(on_timeout)
|
||||||
|
if result then on_success() else on_failure(0) end
|
||||||
if result then
|
|
||||||
on_success()
|
|
||||||
else
|
|
||||||
on_failure(0)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set the value (true simulates pressing the button)
|
-- set the value (true simulates pressing the button)
|
||||||
---@param val boolean new value
|
---@param val boolean new value
|
||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_type.VIRTUAL, 1, 1)) end
|
if val then e.handle_mouse(core.events.mouse_generic(core.events.CLICK_TYPE.UP, 1, 1)) end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- show the button as disabled
|
-- show the button as disabled
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local core = require("graphics.core")
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
|
|
||||||
---@class button_option
|
---@class button_option
|
||||||
---@field text string
|
---@field text string
|
||||||
---@field fg_bg cpair
|
---@field fg_bg cpair
|
||||||
---@field active_fg_bg cpair
|
---@field active_fg_bg cpair
|
||||||
---@field _lpad integer automatically calculated left pad
|
|
||||||
---@field _start_x integer starting touch x range (inclusive)
|
---@field _start_x integer starting touch x range (inclusive)
|
||||||
---@field _end_x integer ending touch x range (inclusive)
|
---@field _end_x integer ending touch x range (inclusive)
|
||||||
|
|
||||||
@ -62,9 +62,7 @@ local function multi_button(args)
|
|||||||
local next_x = 2
|
local next_x = 2
|
||||||
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
|
||||||
local w = string.len(opt.text)
|
|
||||||
|
|
||||||
opt._lpad = math.floor((e.frame.w - w) / 2)
|
|
||||||
opt._start_x = next_x
|
opt._start_x = next_x
|
||||||
opt._end_x = next_x + button_width - 1
|
opt._end_x = next_x + button_width - 1
|
||||||
|
|
||||||
@ -92,23 +90,35 @@ local function multi_button(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- check which button a given x is within
|
||||||
---@param event mouse_interaction mouse event
|
---@return integer|nil button index or nil if not within a button
|
||||||
---@diagnostic disable-next-line: unused-local
|
local function which_button(x)
|
||||||
function e.handle_mouse(event)
|
|
||||||
-- determine what was pressed
|
|
||||||
if e.enabled and event.y == 1 then
|
|
||||||
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
|
||||||
|
if x >= opt._start_x and x <= opt._end_x then return i end
|
||||||
|
end
|
||||||
|
|
||||||
if event.x >= opt._start_x and event.x <= opt._end_x then
|
return nil
|
||||||
e.value = i
|
end
|
||||||
|
|
||||||
|
-- handle mouse interaction
|
||||||
|
---@param event mouse_interaction mouse event
|
||||||
|
function e.handle_mouse(event)
|
||||||
|
-- if enabled and the button row was pressed...
|
||||||
|
if e.enabled and core.events.was_clicked(event.type) then
|
||||||
|
-- a button may have been pressed, which one was it?
|
||||||
|
local button_ini = which_button(event.initial.x)
|
||||||
|
local button_cur = which_button(event.current.x)
|
||||||
|
|
||||||
|
-- mouse up must always have started with a mouse down on the same button to count as a click
|
||||||
|
-- tap always has identical coordinates, so this always passes for taps
|
||||||
|
if button_ini == button_cur and button_cur ~= nil then
|
||||||
|
e.value = button_cur
|
||||||
draw()
|
draw()
|
||||||
args.callback(e.value)
|
args.callback(e.value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
-- set the value
|
-- set the value
|
||||||
---@param val integer new value
|
---@param val integer new value
|
||||||
|
@ -5,6 +5,8 @@ local tcd = require("scada-common.tcallbackdsp")
|
|||||||
local core = require("graphics.core")
|
local core = require("graphics.core")
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
|
|
||||||
|
local CLICK_TYPE = core.events.CLICK_TYPE
|
||||||
|
|
||||||
---@class push_button_args
|
---@class push_button_args
|
||||||
---@field text string button text
|
---@field text string button text
|
||||||
---@field callback function function to call on touch
|
---@field callback function function to call on touch
|
||||||
@ -24,6 +26,8 @@ local element = require("graphics.element")
|
|||||||
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", "graphics.elements.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", "graphics.elements.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),
|
||||||
|
"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)
|
||||||
|
|
||||||
@ -47,36 +51,50 @@ local function push_button(args)
|
|||||||
e.window.write(args.text)
|
e.window.write(args.text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- draw the button as pressed (if active_fg_bg set)
|
||||||
function e.handle_mouse(_)
|
local function show_pressed()
|
||||||
if e.enabled then
|
if e.enabled and args.active_fg_bg ~= nil then
|
||||||
if args.active_fg_bg ~= nil then
|
|
||||||
-- show as pressed
|
|
||||||
e.value = true
|
e.value = true
|
||||||
e.window.setTextColor(args.active_fg_bg.fgd)
|
e.window.setTextColor(args.active_fg_bg.fgd)
|
||||||
e.window.setBackgroundColor(args.active_fg_bg.bkg)
|
e.window.setBackgroundColor(args.active_fg_bg.bkg)
|
||||||
draw()
|
draw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- show as unpressed in 0.25 seconds
|
-- draw the button as unpressed (if active_fg_bg set)
|
||||||
tcd.dispatch(0.25, function ()
|
local function show_unpressed()
|
||||||
|
if e.enabled and args.active_fg_bg ~= nil then
|
||||||
e.value = false
|
e.value = false
|
||||||
if e.enabled then
|
|
||||||
e.window.setTextColor(e.fg_bg.fgd)
|
e.window.setTextColor(e.fg_bg.fgd)
|
||||||
e.window.setBackgroundColor(e.fg_bg.bkg)
|
e.window.setBackgroundColor(e.fg_bg.bkg)
|
||||||
end
|
|
||||||
draw()
|
draw()
|
||||||
end)
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- call the touch callback
|
-- handle mouse interaction
|
||||||
|
---@param event mouse_interaction mouse event
|
||||||
|
function e.handle_mouse(event)
|
||||||
|
if e.enabled then
|
||||||
|
if event.type == CLICK_TYPE.TAP then
|
||||||
|
show_pressed()
|
||||||
|
-- show as unpressed in 0.25 seconds
|
||||||
|
if args.active_fg_bg ~= nil then tcd.dispatch(0.25, show_unpressed) end
|
||||||
args.callback()
|
args.callback()
|
||||||
|
elseif event.type == CLICK_TYPE.DOWN then
|
||||||
|
show_pressed()
|
||||||
|
elseif event.type == CLICK_TYPE.UP then
|
||||||
|
show_unpressed()
|
||||||
|
args.callback()
|
||||||
|
elseif event.type == CLICK_TYPE.EXITED then
|
||||||
|
show_unpressed()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set the value (true simulates pressing the button)
|
-- set the value (true simulates pressing the button)
|
||||||
---@param val boolean new value
|
---@param val boolean new value
|
||||||
function e.set_value(val)
|
function e.set_value(val)
|
||||||
if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_type.VIRTUAL, 1, 1)) end
|
if val then e.handle_mouse(core.events.mouse_generic(core.events.CLICK_TYPE.UP, 1, 1)) end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- show butten as enabled
|
-- show butten as enabled
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
-- Radio Button Graphics Element
|
-- Radio Button Graphics Element
|
||||||
|
|
||||||
|
local core = require("graphics.core")
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
|
|
||||||
---@class radio_button_args
|
---@class radio_button_args
|
||||||
@ -82,10 +83,10 @@ local function radio_button(args)
|
|||||||
-- 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) and (event.initial.y == event.current.y) then
|
||||||
-- determine what was pressed
|
-- determine what was pressed
|
||||||
if e.enabled then
|
if args.options[event.current.y] ~= nil then
|
||||||
if args.options[event.y] ~= nil then
|
e.value = event.current.y
|
||||||
e.value = event.y
|
|
||||||
draw()
|
draw()
|
||||||
args.callback(e.value)
|
args.callback(e.value)
|
||||||
end
|
end
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
local tcd = require("scada-common.tcallbackdsp")
|
local tcd = require("scada-common.tcallbackdsp")
|
||||||
|
|
||||||
|
local core = require("graphics.core")
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
|
|
||||||
|
local CLICK_TYPE = core.events.CLICK_TYPE
|
||||||
|
|
||||||
---@class sidebar_tab
|
---@class sidebar_tab
|
||||||
---@field char string character identifier
|
---@field char string character identifier
|
||||||
---@field color cpair tab colors (fg/bg)
|
---@field color cpair tab colors (fg/bg)
|
||||||
@ -39,7 +42,10 @@ local function sidebar(args)
|
|||||||
|
|
||||||
-- 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
|
||||||
local function draw(pressed)
|
---@param pressed_idx? integer optional index to show as held (that is not yet selected)
|
||||||
|
local function draw(pressed, pressed_idx)
|
||||||
|
pressed_idx = pressed_idx or e.value
|
||||||
|
|
||||||
for i = 1, #args.tabs do
|
for i = 1, #args.tabs do
|
||||||
local tab = args.tabs[i] ---@type sidebar_tab
|
local tab = args.tabs[i] ---@type sidebar_tab
|
||||||
|
|
||||||
@ -47,7 +53,7 @@ local function sidebar(args)
|
|||||||
|
|
||||||
e.window.setCursorPos(1, y)
|
e.window.setCursorPos(1, y)
|
||||||
|
|
||||||
if pressed and e.value == i then
|
if pressed and i == pressed_idx then
|
||||||
e.window.setTextColor(e.fg_bg.fgd)
|
e.window.setTextColor(e.fg_bg.fgd)
|
||||||
e.window.setBackgroundColor(e.fg_bg.bkg)
|
e.window.setBackgroundColor(e.fg_bg.bkg)
|
||||||
else
|
else
|
||||||
@ -74,16 +80,27 @@ local function sidebar(args)
|
|||||||
function e.handle_mouse(event)
|
function e.handle_mouse(event)
|
||||||
-- determine what was pressed
|
-- determine what was pressed
|
||||||
if e.enabled then
|
if e.enabled then
|
||||||
local idx = math.ceil(event.y / 3)
|
local cur_idx = math.ceil(event.current.y / 3)
|
||||||
|
local ini_idx = math.ceil(event.initial.y / 3)
|
||||||
|
|
||||||
if args.tabs[idx] ~= nil then
|
if args.tabs[cur_idx] ~= nil then
|
||||||
e.value = idx
|
if event.type == CLICK_TYPE.TAP then
|
||||||
|
e.value = cur_idx
|
||||||
draw(true)
|
draw(true)
|
||||||
|
|
||||||
-- show as unpressed in 0.25 seconds
|
-- show as unpressed in 0.25 seconds
|
||||||
tcd.dispatch(0.25, function () draw(false) end)
|
tcd.dispatch(0.25, function () draw(false) end)
|
||||||
|
|
||||||
args.callback(e.value)
|
args.callback(e.value)
|
||||||
|
elseif event.type == CLICK_TYPE.DOWN then
|
||||||
|
draw(true, cur_idx)
|
||||||
|
elseif event.type == CLICK_TYPE.UP then
|
||||||
|
if cur_idx == ini_idx then
|
||||||
|
e.value = cur_idx
|
||||||
|
draw(false)
|
||||||
|
args.callback(e.value)
|
||||||
|
else draw(false) end
|
||||||
|
elseif event.type == CLICK_TYPE.EXITED then
|
||||||
|
draw(false)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local core = require("graphics.core")
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
|
|
||||||
---@class spinbox_args
|
---@class spinbox_args
|
||||||
@ -130,13 +131,15 @@ local function spinbox(args)
|
|||||||
---@param event mouse_interaction mouse event
|
---@param event mouse_interaction mouse event
|
||||||
function e.handle_mouse(event)
|
function e.handle_mouse(event)
|
||||||
-- only handle if on an increment or decrement arrow
|
-- only handle if on an increment or decrement arrow
|
||||||
if e.enabled and event.x ~= dec_point_x then
|
if e.enabled and core.events.was_clicked(event.type) and
|
||||||
local idx = util.trinary(event.x > dec_point_x, event.x - 1, event.x)
|
(event.current.x ~= dec_point_x) and (event.current.y ~= 2) then
|
||||||
|
if event.current.x == event.initial.x and event.current.y == event.initial.y then
|
||||||
|
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.y == 1 then
|
if event.current.y == 1 then
|
||||||
-- increment
|
-- increment
|
||||||
digits[idx] = digits[idx] + 1
|
digits[idx] = digits[idx] + 1
|
||||||
elseif event.y == 3 then
|
elseif event.current.y == 3 then
|
||||||
-- decrement
|
-- decrement
|
||||||
digits[idx] = digits[idx] - 1
|
digits[idx] = digits[idx] - 1
|
||||||
end
|
end
|
||||||
@ -146,6 +149,7 @@ local function spinbox(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- set the value
|
-- set the value
|
||||||
---@param val number number to show
|
---@param val number number to show
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
-- Button Graphics Element
|
-- Button Graphics Element
|
||||||
|
|
||||||
|
local core = require("graphics.core")
|
||||||
local element = require("graphics.element")
|
local element = require("graphics.element")
|
||||||
|
|
||||||
---@class switch_button_args
|
---@class switch_button_args
|
||||||
@ -22,13 +23,15 @@ 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", "graphics.elements.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", "graphics.elements.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", "graphics.elements.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),
|
||||||
|
"graphics.elements.controls.switch_button: min_width must be nil or a number > 0")
|
||||||
|
|
||||||
-- single line
|
|
||||||
args.height = 1
|
|
||||||
|
|
||||||
-- determine widths
|
|
||||||
local text_width = string.len(args.text)
|
local text_width = string.len(args.text)
|
||||||
args.width = math.max(text_width + 2, args.min_width)
|
|
||||||
|
-- single line height, calculate width
|
||||||
|
args.height = 1
|
||||||
|
args.min_width = args.min_width or 0
|
||||||
|
args.width = math.max(text_width, args.min_width)
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
@ -63,8 +66,9 @@ local function switch_button(args)
|
|||||||
draw_state()
|
draw_state()
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- handle mouse interaction
|
||||||
function e.handle_mouse(_)
|
---@param event mouse_interaction mouse event
|
||||||
if e.enabled then
|
function e.handle_mouse(event)
|
||||||
|
if e.enabled and core.events.was_clicked(event.type) then
|
||||||
-- toggle state
|
-- toggle state
|
||||||
e.value = not e.value
|
e.value = not e.value
|
||||||
draw_state()
|
draw_state()
|
||||||
|
130
graphics/elements/controls/tabbar.lua
Normal file
130
graphics/elements/controls/tabbar.lua
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
-- Tab Bar Graphics Element
|
||||||
|
|
||||||
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local core = require("graphics.core")
|
||||||
|
local element = require("graphics.element")
|
||||||
|
|
||||||
|
---@class tabbar_tab
|
||||||
|
---@field name string tab name
|
||||||
|
---@field color cpair tab colors (fg/bg)
|
||||||
|
---@field _start_x integer starting touch x range (inclusive)
|
||||||
|
---@field _end_x integer ending touch x range (inclusive)
|
||||||
|
|
||||||
|
---@class tabbar_args
|
||||||
|
---@field tabs table tab options
|
||||||
|
---@field callback function function to call on tab change
|
||||||
|
---@field min_width? integer text length + 2 if omitted
|
||||||
|
---@field parent graphics_element
|
||||||
|
---@field id? string element id
|
||||||
|
---@field x? integer 1 if omitted
|
||||||
|
---@field y? integer 1 if omitted
|
||||||
|
---@field width? integer parent width if omitted
|
||||||
|
---@field fg_bg? cpair foreground/background colors
|
||||||
|
|
||||||
|
-- new tab selector
|
||||||
|
---@param args tabbar_args
|
||||||
|
---@return graphics_element element, element_id id
|
||||||
|
local function tabbar(args)
|
||||||
|
assert(type(args.tabs) == "table", "graphics.elements.controls.tabbar: tabs is a required field")
|
||||||
|
assert(#args.tabs > 0, "graphics.elements.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.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
||||||
|
"graphics.elements.controls.tabbar: min_width must be nil or a number > 0")
|
||||||
|
|
||||||
|
-- always 1 tall
|
||||||
|
args.height = 1
|
||||||
|
|
||||||
|
-- determine widths
|
||||||
|
local max_width = 1
|
||||||
|
for i = 1, #args.tabs do
|
||||||
|
local opt = args.tabs[i] ---@type tabbar_tab
|
||||||
|
if string.len(opt.name) > max_width then
|
||||||
|
max_width = string.len(opt.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local button_width = math.max(max_width, args.min_width or 0)
|
||||||
|
|
||||||
|
-- create new graphics element base object
|
||||||
|
local e = element.new(args)
|
||||||
|
|
||||||
|
assert(e.frame.w >= (button_width * #args.tabs), "graphics.elements.controls.tabbar: width insufficent to display all tabs")
|
||||||
|
|
||||||
|
-- default to 1st tab
|
||||||
|
e.value = 1
|
||||||
|
|
||||||
|
-- calculate required tab dimension information
|
||||||
|
local next_x = 1
|
||||||
|
for i = 1, #args.tabs do
|
||||||
|
local tab = args.tabs[i] ---@type tabbar_tab
|
||||||
|
|
||||||
|
tab._start_x = next_x
|
||||||
|
tab._end_x = next_x + button_width - 1
|
||||||
|
|
||||||
|
next_x = next_x + button_width
|
||||||
|
end
|
||||||
|
|
||||||
|
-- show the tab state
|
||||||
|
local function draw()
|
||||||
|
for i = 1, #args.tabs do
|
||||||
|
local tab = args.tabs[i] ---@type tabbar_tab
|
||||||
|
|
||||||
|
e.window.setCursorPos(tab._start_x, 1)
|
||||||
|
|
||||||
|
if e.value == i then
|
||||||
|
e.window.setTextColor(tab.color.fgd)
|
||||||
|
e.window.setBackgroundColor(tab.color.bkg)
|
||||||
|
else
|
||||||
|
e.window.setTextColor(e.fg_bg.fgd)
|
||||||
|
e.window.setBackgroundColor(e.fg_bg.bkg)
|
||||||
|
end
|
||||||
|
|
||||||
|
e.window.write(util.pad(tab.name, button_width))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check which tab a given x is within
|
||||||
|
---@return integer|nil button index or nil if not within a tab
|
||||||
|
local function which_tab(x)
|
||||||
|
for i = 1, #args.tabs do
|
||||||
|
local tab = args.tabs[i] ---@type tabbar_tab
|
||||||
|
if x >= tab._start_x and x <= tab._end_x then return i end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- handle mouse interaction
|
||||||
|
---@param event mouse_interaction mouse event
|
||||||
|
function e.handle_mouse(event)
|
||||||
|
-- determine what was pressed
|
||||||
|
if e.enabled and core.events.was_clicked(event.type) then
|
||||||
|
-- a button may have been pressed, which one was it?
|
||||||
|
local tab_ini = which_tab(event.initial.x)
|
||||||
|
local tab_cur = which_tab(event.current.x)
|
||||||
|
|
||||||
|
-- mouse up must always have started with a mouse down on the same tab to count as a click
|
||||||
|
-- tap always has identical coordinates, so this always passes for taps
|
||||||
|
if tab_ini == tab_cur and tab_cur ~= nil then
|
||||||
|
e.value = tab_cur
|
||||||
|
draw()
|
||||||
|
args.callback(e.value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set the value
|
||||||
|
---@param val integer new value
|
||||||
|
function e.set_value(val)
|
||||||
|
e.value = val
|
||||||
|
draw()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initial draw
|
||||||
|
draw()
|
||||||
|
|
||||||
|
return e.get()
|
||||||
|
end
|
||||||
|
|
||||||
|
return tabbar
|
@ -26,7 +26,7 @@ local function core_map(args)
|
|||||||
args.height = 18
|
args.height = 18
|
||||||
|
|
||||||
-- inherit only foreground color
|
-- inherit only foreground color
|
||||||
args.fg_bg = core.graphics.cpair(args.parent.get_fg_bg().fgd, colors.gray)
|
args.fg_bg = core.cpair(args.parent.get_fg_bg().fgd, colors.gray)
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
@ -37,7 +37,7 @@ local function pipenet(args)
|
|||||||
args.y = args.y or 1
|
args.y = args.y or 1
|
||||||
|
|
||||||
if args.bg ~= nil then
|
if args.bg ~= nil then
|
||||||
args.fg_bg = core.graphics.cpair(args.bg, args.bg)
|
args.fg_bg = core.cpair(args.bg, args.bg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
@ -55,7 +55,7 @@ local function pipenet(args)
|
|||||||
|
|
||||||
e.window.setCursorPos(x, y)
|
e.window.setCursorPos(x, y)
|
||||||
|
|
||||||
local c = core.graphics.cpair(pipe.color, e.fg_bg.bkg)
|
local c = core.cpair(pipe.color, e.fg_bg.bkg)
|
||||||
|
|
||||||
if pipe.align_tr then
|
if pipe.align_tr then
|
||||||
-- cross width then height
|
-- cross width then height
|
||||||
|
@ -5,7 +5,7 @@ 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")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
---@class textbox_args
|
---@class textbox_args
|
||||||
---@field text string text to show
|
---@field text string text to show
|
||||||
|
162
graphics/events.lua
Normal file
162
graphics/events.lua
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
--
|
||||||
|
-- Graphics Events and Event Handlers
|
||||||
|
--
|
||||||
|
|
||||||
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local events = {}
|
||||||
|
|
||||||
|
---@enum CLICK_BUTTON
|
||||||
|
events.CLICK_BUTTON = {
|
||||||
|
GENERIC = 0,
|
||||||
|
LEFT_BUTTON = 1,
|
||||||
|
RIGHT_BUTTON = 2,
|
||||||
|
MID_BUTTON = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
---@enum CLICK_TYPE
|
||||||
|
events.CLICK_TYPE = {
|
||||||
|
TAP = 1, -- screen tap (complete click)
|
||||||
|
DOWN = 2, -- button down
|
||||||
|
UP = 3, -- button up (completed a click)
|
||||||
|
DRAG = 4, -- mouse dragged
|
||||||
|
SCROLL_DOWN = 5, -- scroll down
|
||||||
|
SCROLL_UP = 6, -- scroll up
|
||||||
|
EXITED = 7 -- cursor exited bounds of element
|
||||||
|
}
|
||||||
|
|
||||||
|
-- create a new 2D coordinate
|
||||||
|
---@param x integer
|
||||||
|
---@param y integer
|
||||||
|
---@return coordinate_2d
|
||||||
|
local function _coord2d(x, y) return { x = x, y = y } end
|
||||||
|
|
||||||
|
---@class mouse_interaction
|
||||||
|
---@field monitor string
|
||||||
|
---@field button CLICK_BUTTON
|
||||||
|
---@field type CLICK_TYPE
|
||||||
|
---@field initial coordinate_2d
|
||||||
|
---@field current coordinate_2d
|
||||||
|
|
||||||
|
local handler = {
|
||||||
|
-- left, right, middle button down tracking
|
||||||
|
button_down = {
|
||||||
|
_coord2d(0, 0),
|
||||||
|
_coord2d(0, 0),
|
||||||
|
_coord2d(0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- create a new monitor touch mouse interaction event
|
||||||
|
---@nodiscard
|
||||||
|
---@param monitor string
|
||||||
|
---@param x integer
|
||||||
|
---@param y integer
|
||||||
|
---@return mouse_interaction
|
||||||
|
local function _monitor_touch(monitor, x, y)
|
||||||
|
return {
|
||||||
|
monitor = monitor,
|
||||||
|
button = events.CLICK_BUTTON.GENERIC,
|
||||||
|
type = events.CLICK_TYPE.TAP,
|
||||||
|
initial = _coord2d(x, y),
|
||||||
|
current = _coord2d(x, y)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create a new mouse button mouse interaction event
|
||||||
|
---@nodiscard
|
||||||
|
---@param button CLICK_BUTTON mouse button
|
||||||
|
---@param type CLICK_TYPE click type
|
||||||
|
---@param x1 integer initial x
|
||||||
|
---@param y1 integer initial y
|
||||||
|
---@param x2 integer current x
|
||||||
|
---@param y2 integer current y
|
||||||
|
---@return mouse_interaction
|
||||||
|
local function _mouse_event(button, type, x1, y1, x2, y2)
|
||||||
|
return {
|
||||||
|
monitor = "terminal",
|
||||||
|
button = button,
|
||||||
|
type = type,
|
||||||
|
initial = _coord2d(x1, y1),
|
||||||
|
current = _coord2d(x2, y2)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create a new generic mouse interaction event
|
||||||
|
---@nodiscard
|
||||||
|
---@param type CLICK_TYPE
|
||||||
|
---@param x integer
|
||||||
|
---@param y integer
|
||||||
|
---@return mouse_interaction
|
||||||
|
function events.mouse_generic(type, x, y)
|
||||||
|
return {
|
||||||
|
monitor = "",
|
||||||
|
button = events.CLICK_BUTTON.GENERIC,
|
||||||
|
type = type,
|
||||||
|
initial = _coord2d(x, y),
|
||||||
|
current = _coord2d(x, y)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create a new transposed mouse interaction event using the event's monitor/button fields
|
||||||
|
---@nodiscard
|
||||||
|
---@param event mouse_interaction
|
||||||
|
---@param elem_pos_x integer element's x position: new x = (event x - element x) + 1
|
||||||
|
---@param elem_pos_y integer element's y position: new y = (event y - element y) + 1
|
||||||
|
---@return mouse_interaction
|
||||||
|
function events.mouse_transposed(event, elem_pos_x, elem_pos_y)
|
||||||
|
return {
|
||||||
|
monitor = event.monitor,
|
||||||
|
button = event.button,
|
||||||
|
type = event.type,
|
||||||
|
initial = _coord2d((event.initial.x - elem_pos_x) + 1, (event.initial.y - elem_pos_y) + 1),
|
||||||
|
current = _coord2d((event.current.x - elem_pos_x) + 1, (event.current.y - elem_pos_y) + 1)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check if an event qualifies as a click (tap or up)
|
||||||
|
---@nodiscard
|
||||||
|
---@param t CLICK_TYPE
|
||||||
|
function events.was_clicked(t) return t == events.CLICK_TYPE.TAP or t == events.CLICK_TYPE.UP end
|
||||||
|
|
||||||
|
-- create a new mouse event to pass onto graphics renderer<br>
|
||||||
|
-- supports: mouse_click, mouse_up, mouse_drag, mouse_scroll, and monitor_touch
|
||||||
|
---@param event_type os_event OS event to handle
|
||||||
|
---@param opt integer|string button, scroll direction, or monitor for monitor touch
|
||||||
|
---@param x integer x coordinate
|
||||||
|
---@param y integer y coordinate
|
||||||
|
---@return mouse_interaction|nil
|
||||||
|
function events.new_mouse_event(event_type, opt, x, y)
|
||||||
|
if event_type == "mouse_click" then
|
||||||
|
---@cast opt 1|2|3
|
||||||
|
handler.button_down[opt] = _coord2d(x, y)
|
||||||
|
return _mouse_event(opt, events.CLICK_TYPE.DOWN, x, y, x, y)
|
||||||
|
elseif event_type == "mouse_up" then
|
||||||
|
---@cast opt 1|2|3
|
||||||
|
local initial = handler.button_down[opt] ---@type coordinate_2d
|
||||||
|
return _mouse_event(opt, events.CLICK_TYPE.UP, initial.x, initial.y, x, y)
|
||||||
|
elseif event_type == "monitor_touch" then
|
||||||
|
---@cast opt string
|
||||||
|
return _monitor_touch(opt, x, y)
|
||||||
|
elseif event_type == "mouse_drag" then
|
||||||
|
---@cast opt 1|2|3
|
||||||
|
local initial = handler.button_down[opt] ---@type coordinate_2d
|
||||||
|
return _mouse_event(opt, events.CLICK_TYPE.DRAG, initial.x, initial.y, x, y)
|
||||||
|
elseif event_type == "mouse_scroll" then
|
||||||
|
---@cast opt 1|-1
|
||||||
|
local scroll_direction = util.trinary(opt == 1, events.CLICK_TYPE.SCROLL_DOWN, events.CLICK_TYPE.SCROLL_UP)
|
||||||
|
return _mouse_event(events.CLICK_BUTTON.GENERIC, scroll_direction, x, y, x, y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create a new key event to pass onto graphics renderer<br>
|
||||||
|
-- supports: char, key, and key_up
|
||||||
|
---@param event_type os_event
|
||||||
|
function events.new_key_event(event_type)
|
||||||
|
if event_type == "char" then
|
||||||
|
elseif event_type == "key" then
|
||||||
|
elseif event_type == "key_up" then
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return events
|
File diff suppressed because one or more lines are too long
@ -70,9 +70,9 @@ end
|
|||||||
function renderer.ui_ready() return ui.display ~= nil end
|
function renderer.ui_ready() return ui.display ~= nil end
|
||||||
|
|
||||||
-- handle a mouse event
|
-- handle a mouse event
|
||||||
---@param event mouse_interaction
|
---@param event mouse_interaction|nil
|
||||||
function renderer.handle_mouse(event)
|
function renderer.handle_mouse(event)
|
||||||
if ui.display ~= nil then
|
if ui.display ~= nil and event ~= nil then
|
||||||
ui.display.handle_mouse(event)
|
ui.display.handle_mouse(event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -153,9 +153,9 @@ local function main()
|
|||||||
-- got a packet
|
-- got a packet
|
||||||
local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5)
|
local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||||
pocket_comms.handle_packet(packet)
|
pocket_comms.handle_packet(packet)
|
||||||
elseif event == "mouse_click" then
|
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then
|
||||||
-- handle a monitor touch event
|
-- handle a monitor touch event
|
||||||
renderer.handle_mouse(core.events.touch(param1, param2, param3))
|
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check for termination request
|
-- check for termination request
|
||||||
|
@ -5,9 +5,9 @@ local core = require("graphics.core")
|
|||||||
local Div = require("graphics.elements.div")
|
local Div = require("graphics.elements.div")
|
||||||
local TextBox = require("graphics.elements.textbox")
|
local TextBox = require("graphics.elements.textbox")
|
||||||
|
|
||||||
-- local cpair = core.graphics.cpair
|
-- local cpair = core.cpair
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
-- new boiler page view
|
-- new boiler page view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -11,9 +11,9 @@ local TextBox = require("graphics.elements.textbox")
|
|||||||
|
|
||||||
local WaitingAnim = require("graphics.elements.animations.waiting")
|
local WaitingAnim = require("graphics.elements.animations.waiting")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- create a waiting view
|
-- create a waiting view
|
||||||
---@param parent graphics_element parent
|
---@param parent graphics_element parent
|
||||||
|
@ -5,9 +5,9 @@ local core = require("graphics.core")
|
|||||||
local Div = require("graphics.elements.div")
|
local Div = require("graphics.elements.div")
|
||||||
local TextBox = require("graphics.elements.textbox")
|
local TextBox = require("graphics.elements.textbox")
|
||||||
|
|
||||||
-- local cpair = core.graphics.cpair
|
-- local cpair = core.cpair
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
-- new home page view
|
-- new home page view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -5,9 +5,9 @@ local core = require("graphics.core")
|
|||||||
local Div = require("graphics.elements.div")
|
local Div = require("graphics.elements.div")
|
||||||
local TextBox = require("graphics.elements.textbox")
|
local TextBox = require("graphics.elements.textbox")
|
||||||
|
|
||||||
-- local cpair = core.graphics.cpair
|
-- local cpair = core.cpair
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
-- new reactor page view
|
-- new reactor page view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -5,9 +5,9 @@ local core = require("graphics.core")
|
|||||||
local Div = require("graphics.elements.div")
|
local Div = require("graphics.elements.div")
|
||||||
local TextBox = require("graphics.elements.textbox")
|
local TextBox = require("graphics.elements.textbox")
|
||||||
|
|
||||||
-- local cpair = core.graphics.cpair
|
-- local cpair = core.cpair
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
-- new turbine page view
|
-- new turbine page view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -5,9 +5,9 @@ local core = require("graphics.core")
|
|||||||
local Div = require("graphics.elements.div")
|
local Div = require("graphics.elements.div")
|
||||||
local TextBox = require("graphics.elements.textbox")
|
local TextBox = require("graphics.elements.textbox")
|
||||||
|
|
||||||
-- local cpair = core.graphics.cpair
|
-- local cpair = core.cpair
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
-- new unit page view
|
-- new unit page view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
|
@ -22,9 +22,9 @@ local TextBox = require("graphics.elements.textbox")
|
|||||||
|
|
||||||
local Sidebar = require("graphics.elements.controls.sidebar")
|
local Sidebar = require("graphics.elements.controls.sidebar")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- create new main view
|
-- create new main view
|
||||||
---@param main graphics_element main displaybox
|
---@param main graphics_element main displaybox
|
||||||
|
@ -6,7 +6,7 @@ local core = require("graphics.core")
|
|||||||
|
|
||||||
local style = {}
|
local style = {}
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- GLOBAL --
|
-- GLOBAL --
|
||||||
|
|
||||||
|
@ -22,10 +22,10 @@ local LED = require("graphics.elements.indicators.led")
|
|||||||
local LEDPair = require("graphics.elements.indicators.ledpair")
|
local LEDPair = require("graphics.elements.indicators.ledpair")
|
||||||
local RGBLED = require("graphics.elements.indicators.ledrgb")
|
local RGBLED = require("graphics.elements.indicators.ledrgb")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
local border = core.graphics.border
|
local border = core.border
|
||||||
|
|
||||||
-- create new main view
|
-- create new main view
|
||||||
---@param panel graphics_element main displaybox
|
---@param panel graphics_element main displaybox
|
||||||
|
@ -6,7 +6,7 @@ local core = require("graphics.core")
|
|||||||
|
|
||||||
local style = {}
|
local style = {}
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- GLOBAL --
|
-- GLOBAL --
|
||||||
|
|
||||||
|
@ -70,9 +70,9 @@ end
|
|||||||
function renderer.ui_ready() return ui.display ~= nil end
|
function renderer.ui_ready() return ui.display ~= nil end
|
||||||
|
|
||||||
-- handle a mouse event
|
-- handle a mouse event
|
||||||
---@param event mouse_interaction
|
---@param event mouse_interaction|nil
|
||||||
function renderer.handle_mouse(event)
|
function renderer.handle_mouse(event)
|
||||||
if ui.display ~= nil then
|
if ui.display ~= nil and event ~= nil then
|
||||||
ui.display.handle_mouse(event)
|
ui.display.handle_mouse(event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc")
|
|||||||
local renderer = require("reactor-plc.renderer")
|
local renderer = require("reactor-plc.renderer")
|
||||||
local threads = require("reactor-plc.threads")
|
local threads = require("reactor-plc.threads")
|
||||||
|
|
||||||
local R_PLC_VERSION = "v1.1.17"
|
local R_PLC_VERSION = "v1.2.0"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
@ -257,9 +257,9 @@ function threads.thread__main(smem, init)
|
|||||||
|
|
||||||
-- update indicators
|
-- update indicators
|
||||||
databus.tx_hw_status(plc_state)
|
databus.tx_hw_status(plc_state)
|
||||||
elseif event == "mouse_click" then
|
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then
|
||||||
-- handle a monitor touch event
|
-- handle a mouse event
|
||||||
renderer.handle_mouse(core.events.click(param1, param2, param3))
|
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||||
elseif event == "clock_start" then
|
elseif event == "clock_start" then
|
||||||
-- start loop clock
|
-- start loop clock
|
||||||
loop_clock.start()
|
loop_clock.start()
|
||||||
|
@ -16,9 +16,9 @@ local TextBox = require("graphics.elements.textbox")
|
|||||||
local LED = require("graphics.elements.indicators.led")
|
local LED = require("graphics.elements.indicators.led")
|
||||||
local RGBLED = require("graphics.elements.indicators.ledrgb")
|
local RGBLED = require("graphics.elements.indicators.ledrgb")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
local TEXT_ALIGN = core.TEXT_ALIGN
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
local UNIT_TYPE_LABELS = {
|
local UNIT_TYPE_LABELS = {
|
||||||
"UNKNOWN",
|
"UNKNOWN",
|
||||||
|
@ -6,7 +6,7 @@ local core = require("graphics.core")
|
|||||||
|
|
||||||
local style = {}
|
local style = {}
|
||||||
|
|
||||||
local cpair = core.graphics.cpair
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- GLOBAL --
|
-- GLOBAL --
|
||||||
|
|
||||||
|
@ -71,9 +71,9 @@ end
|
|||||||
function renderer.ui_ready() return ui.display ~= nil end
|
function renderer.ui_ready() return ui.display ~= nil end
|
||||||
|
|
||||||
-- handle a mouse event
|
-- handle a mouse event
|
||||||
---@param event mouse_interaction
|
---@param event mouse_interaction|nil
|
||||||
function renderer.handle_mouse(event)
|
function renderer.handle_mouse(event)
|
||||||
if ui.display ~= nil then
|
if ui.display ~= nil and event ~= nil then
|
||||||
ui.display.handle_mouse(event)
|
ui.display.handle_mouse(event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -28,7 +28,7 @@ local sna_rtu = require("rtu.dev.sna_rtu")
|
|||||||
local sps_rtu = require("rtu.dev.sps_rtu")
|
local sps_rtu = require("rtu.dev.sps_rtu")
|
||||||
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
||||||
|
|
||||||
local RTU_VERSION = "v1.0.5"
|
local RTU_VERSION = "v1.1.0"
|
||||||
|
|
||||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||||
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE
|
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE
|
||||||
|
@ -229,9 +229,9 @@ function threads.thread__main(smem)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif event == "mouse_click" then
|
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then
|
||||||
-- handle a monitor touch event
|
-- handle a mouse event
|
||||||
renderer.handle_mouse(core.events.click(param1, param2, param3))
|
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check for termination request
|
-- check for termination request
|
||||||
|
@ -39,6 +39,10 @@ function types.new_radiation_reading(r, u) return { radiation = r, unit = u } en
|
|||||||
---@return radiation_reading
|
---@return radiation_reading
|
||||||
function types.new_zero_radiation_reading() return { radiation = 0, unit = "nSv" } end
|
function types.new_zero_radiation_reading() return { radiation = 0, unit = "nSv" } end
|
||||||
|
|
||||||
|
---@class coordinate_2d
|
||||||
|
---@field x integer
|
||||||
|
---@field y integer
|
||||||
|
|
||||||
---@class coordinate
|
---@class coordinate
|
||||||
---@field x integer
|
---@field x integer
|
||||||
---@field y integer
|
---@field y integer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user