2023-02-23 04:09:47 +00:00
|
|
|
--
|
|
|
|
-- Graphics Rendering Control
|
|
|
|
--
|
|
|
|
|
2023-04-21 18:53:28 +00:00
|
|
|
local log = require("scada-common.log")
|
|
|
|
local util = require("scada-common.util")
|
2022-09-03 14:50:14 +00:00
|
|
|
|
2023-04-21 18:53:28 +00:00
|
|
|
local style = require("coordinator.ui.style")
|
2022-09-10 14:42:56 +00:00
|
|
|
|
2023-04-21 18:53:28 +00:00
|
|
|
local main_view = require("coordinator.ui.layout.main_view")
|
|
|
|
local unit_view = require("coordinator.ui.layout.unit_view")
|
2022-06-06 19:42:39 +00:00
|
|
|
|
2023-04-21 18:53:28 +00:00
|
|
|
local flasher = require("graphics.flasher")
|
|
|
|
|
|
|
|
local DisplayBox = require("graphics.elements.displaybox")
|
2023-02-03 04:07:09 +00:00
|
|
|
|
2022-05-29 18:34:09 +00:00
|
|
|
local renderer = {}
|
|
|
|
|
2022-06-06 19:42:39 +00:00
|
|
|
-- render engine
|
2022-05-29 18:34:09 +00:00
|
|
|
local engine = {
|
2023-04-21 18:53:28 +00:00
|
|
|
monitors = nil, ---@type monitors_struct|nil
|
|
|
|
dmesg_window = nil, ---@type table|nil
|
|
|
|
ui_ready = false,
|
|
|
|
ui = {
|
|
|
|
main_display = nil, ---@type graphics_element|nil
|
|
|
|
unit_displays = {}
|
|
|
|
}
|
2022-06-06 19:42:39 +00:00
|
|
|
}
|
|
|
|
|
2023-02-28 04:59:46 +00:00
|
|
|
-- init a display to the "default", but set text scale to 0.5
|
2022-07-05 16:46:31 +00:00
|
|
|
---@param monitor table monitor
|
2023-02-28 04:59:46 +00:00
|
|
|
local function _init_display(monitor)
|
2022-06-06 19:42:39 +00:00
|
|
|
monitor.setTextScale(0.5)
|
|
|
|
monitor.setTextColor(colors.white)
|
|
|
|
monitor.setBackgroundColor(colors.black)
|
|
|
|
monitor.clear()
|
|
|
|
monitor.setCursorPos(1, 1)
|
2022-07-05 16:46:31 +00:00
|
|
|
|
2023-02-28 04:59:46 +00:00
|
|
|
-- set overridden colors
|
|
|
|
for i = 1, #style.colors do
|
|
|
|
monitor.setPaletteColor(style.colors[i].c, style.colors[i].hex)
|
2022-07-05 16:46:31 +00:00
|
|
|
end
|
2022-06-06 19:42:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- link to the monitor peripherals
|
2022-05-29 18:34:09 +00:00
|
|
|
---@param monitors monitors_struct
|
|
|
|
function renderer.set_displays(monitors)
|
|
|
|
engine.monitors = monitors
|
|
|
|
end
|
|
|
|
|
2022-09-13 20:07:21 +00:00
|
|
|
-- check if the renderer is configured to use a given monitor peripheral
|
2023-02-23 04:09:47 +00:00
|
|
|
---@nodiscard
|
2022-09-13 20:07:21 +00:00
|
|
|
---@param periph table peripheral
|
|
|
|
---@return boolean is_used
|
|
|
|
function renderer.is_monitor_used(periph)
|
|
|
|
if engine.monitors ~= nil then
|
|
|
|
if engine.monitors.primary == periph then
|
|
|
|
return true
|
|
|
|
else
|
2023-04-22 03:43:28 +00:00
|
|
|
for _, monitor in ipairs(engine.monitors.unit_displays) do
|
2023-04-21 18:53:28 +00:00
|
|
|
if monitor == periph then return true end
|
2022-09-13 20:07:21 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2023-02-28 04:59:46 +00:00
|
|
|
-- init all displays in use by the renderer
|
|
|
|
function renderer.init_displays()
|
|
|
|
-- init primary monitor
|
|
|
|
_init_display(engine.monitors.primary)
|
2022-05-29 18:34:09 +00:00
|
|
|
|
2023-02-28 04:59:46 +00:00
|
|
|
-- init unit displays
|
2023-04-22 03:43:28 +00:00
|
|
|
for _, monitor in ipairs(engine.monitors.unit_displays) do
|
2023-02-28 04:59:46 +00:00
|
|
|
_init_display(monitor)
|
2022-05-29 18:34:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-02-03 20:19:00 +00:00
|
|
|
-- check main display width
|
2023-02-23 04:09:47 +00:00
|
|
|
---@nodiscard
|
2023-02-03 20:19:00 +00:00
|
|
|
---@return boolean width_okay
|
|
|
|
function renderer.validate_main_display_width()
|
|
|
|
local w, _ = engine.monitors.primary.getSize()
|
|
|
|
return w == 164
|
|
|
|
end
|
|
|
|
|
|
|
|
-- check display sizes
|
2023-02-23 04:09:47 +00:00
|
|
|
---@nodiscard
|
2023-02-03 20:19:00 +00:00
|
|
|
---@return boolean valid all unit display dimensions OK
|
|
|
|
function renderer.validate_unit_display_sizes()
|
|
|
|
local valid = true
|
|
|
|
|
2023-04-22 03:43:28 +00:00
|
|
|
for id, monitor in ipairs(engine.monitors.unit_displays) do
|
2023-02-03 20:19:00 +00:00
|
|
|
local w, h = monitor.getSize()
|
|
|
|
if w ~= 79 or h ~= 52 then
|
2023-02-23 04:09:47 +00:00
|
|
|
log.warning(util.c("RENDERER: unit ", id, " display resolution not 79 wide by 52 tall: ", w, ", ", h))
|
2023-02-03 20:19:00 +00:00
|
|
|
valid = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return valid
|
|
|
|
end
|
|
|
|
|
2022-06-06 19:42:39 +00:00
|
|
|
-- initialize the dmesg output window
|
2022-05-29 18:34:09 +00:00
|
|
|
function renderer.init_dmesg()
|
|
|
|
local disp_x, disp_y = engine.monitors.primary.getSize()
|
|
|
|
engine.dmesg_window = window.create(engine.monitors.primary, 1, 1, disp_x, disp_y)
|
|
|
|
log.direct_dmesg(engine.dmesg_window)
|
|
|
|
end
|
|
|
|
|
2022-06-06 19:42:39 +00:00
|
|
|
-- start the coordinator GUI
|
|
|
|
function renderer.start_ui()
|
2022-09-13 20:07:21 +00:00
|
|
|
if not engine.ui_ready then
|
|
|
|
-- hide dmesg
|
|
|
|
engine.dmesg_window.setVisible(false)
|
2022-06-06 19:42:39 +00:00
|
|
|
|
2022-09-13 20:07:21 +00:00
|
|
|
-- show main view on main monitor
|
2023-04-21 18:53:28 +00:00
|
|
|
engine.ui.main_display = DisplayBox{window=engine.monitors.primary,fg_bg=style.root}
|
|
|
|
main_view(engine.ui.main_display)
|
2022-06-16 15:24:35 +00:00
|
|
|
|
2022-09-13 20:07:21 +00:00
|
|
|
-- show unit views on unit displays
|
2023-04-22 03:43:28 +00:00
|
|
|
for i = 1, #engine.monitors.unit_displays do
|
|
|
|
engine.ui.unit_displays[i] = DisplayBox{window=engine.monitors.unit_displays[i],fg_bg=style.root}
|
2023-04-21 18:53:28 +00:00
|
|
|
unit_view(engine.ui.unit_displays[i], i)
|
2022-09-13 20:07:21 +00:00
|
|
|
end
|
2022-09-03 14:50:14 +00:00
|
|
|
|
2022-10-12 20:37:11 +00:00
|
|
|
-- start flasher callback task
|
2022-10-23 05:41:02 +00:00
|
|
|
flasher.run()
|
2022-10-12 20:37:11 +00:00
|
|
|
|
2022-09-13 20:07:21 +00:00
|
|
|
-- report ui as ready
|
|
|
|
engine.ui_ready = true
|
|
|
|
end
|
2022-06-06 19:42:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- close out the UI
|
2022-09-11 02:08:29 +00:00
|
|
|
function renderer.close_ui()
|
2022-10-12 20:37:11 +00:00
|
|
|
-- stop blinking indicators
|
|
|
|
flasher.clear()
|
2022-09-13 20:07:21 +00:00
|
|
|
|
2023-05-14 23:13:12 +00:00
|
|
|
-- delete element trees
|
|
|
|
if engine.ui.main_display ~= nil then engine.ui.main_display.delete() end
|
|
|
|
for _, display in ipairs(engine.ui.unit_displays) do display.delete() end
|
2023-04-21 18:53:28 +00:00
|
|
|
|
|
|
|
-- report ui as not ready
|
|
|
|
engine.ui_ready = false
|
2022-09-11 02:08:29 +00:00
|
|
|
|
2022-10-12 20:37:11 +00:00
|
|
|
-- clear root UI elements
|
2023-04-21 18:53:28 +00:00
|
|
|
engine.ui.main_display = nil
|
|
|
|
engine.ui.unit_displays = {}
|
|
|
|
|
|
|
|
-- clear unit monitors
|
2023-04-22 03:43:28 +00:00
|
|
|
for _, monitor in ipairs(engine.monitors.unit_displays) do monitor.clear() end
|
2022-06-11 21:58:29 +00:00
|
|
|
|
2022-10-12 20:37:11 +00:00
|
|
|
-- re-draw dmesg
|
|
|
|
engine.dmesg_window.setVisible(true)
|
|
|
|
engine.dmesg_window.redraw()
|
2022-06-06 19:42:39 +00:00
|
|
|
end
|
|
|
|
|
2022-09-03 14:50:14 +00:00
|
|
|
-- is the UI ready?
|
2023-02-23 04:09:47 +00:00
|
|
|
---@nodiscard
|
2022-09-03 14:50:14 +00:00
|
|
|
---@return boolean ready
|
|
|
|
function renderer.ui_ready() return engine.ui_ready end
|
|
|
|
|
2022-07-20 17:28:58 +00:00
|
|
|
-- handle a touch event
|
2023-05-11 00:01:06 +00:00
|
|
|
---@param event mouse_interaction|nil
|
2023-04-09 01:33:54 +00:00
|
|
|
function renderer.handle_mouse(event)
|
2023-05-11 00:01:06 +00:00
|
|
|
if engine.ui_ready and event ~= nil then
|
2023-04-21 18:53:28 +00:00
|
|
|
if event.monitor == engine.monitors.primary_name then
|
|
|
|
engine.ui.main_display.handle_mouse(event)
|
|
|
|
else
|
|
|
|
for id, monitor in ipairs(engine.monitors.unit_name_map) do
|
|
|
|
if event.monitor == monitor then
|
|
|
|
local layout = engine.ui.unit_displays[id] ---@type graphics_element
|
|
|
|
layout.handle_mouse(event)
|
|
|
|
end
|
2022-07-20 17:28:58 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-05-29 18:34:09 +00:00
|
|
|
return renderer
|