diff --git a/README.md b/README.md index 2f727be..e8f901f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ Configurable ComputerCraft SCADA system for multi-reactor control of Mekanism fi ![GitHub](https://img.shields.io/github/license/MikaylaFischler/cc-mek-scada) ![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/MikaylaFischler/cc-mek-scada?include_prereleases) ![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=main&label=main) -![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=latest&label=latest) ![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=devel&label=devel) ### [Join](https://discord.gg/R9NSCkhcwt) the Discord! @@ -17,6 +16,7 @@ Configurable ComputerCraft SCADA system for multi-reactor control of Mekanism fi ![Bootloader](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fbootloader.json) +![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fcommon.json) ![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fcomms.json) ![Graphics](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fgraphics.json) ![Lockbox](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Flockbox.json) diff --git a/coordinator/configure.lua b/coordinator/configure.lua index 7c3fe58..b2576c5 100644 --- a/coordinator/configure.lua +++ b/coordinator/configure.lua @@ -8,6 +8,7 @@ local network = require("scada-common.network") local ppm = require("scada-common.ppm") local tcd = require("scada-common.tcd") local util = require("scada-common.util") +local themes = require("graphics.themes") local core = require("graphics.core") @@ -24,6 +25,8 @@ local RadioButton = require("graphics.elements.controls.radio_button") local NumberField = require("graphics.elements.form.number_field") local TextField = require("graphics.elements.form.text_field") +local IndLight = require("graphics.elements.indicators.light") + local println = util.println local tri = util.trinary @@ -40,7 +43,8 @@ local RIGHT = core.ALIGN.RIGHT -- changes to the config data/format to let the user know local changes = { - {"v1.2.4", { "Added temperature scale options" } } + { "v1.2.4", { "Added temperature scale options" } }, + { "v1.2.12", { "Added main UI theme", "Added front panel UI theme", "Added color accessibility modes" } } } ---@class crd_configurator @@ -73,6 +77,7 @@ local nav_fg_bg = bw_fg_bg local btn_act_fg_bg = cpair(colors.white, colors.gray) local dis_fg_bg = cpair(colors.lightGray,colors.white) +---@class _crd_cfg_tool_ctl local tool_ctl = { nic = nil, ---@type nic net_listen = false, @@ -86,8 +91,12 @@ local tool_ctl = { has_config = false, viewing_config = false, importing_legacy = false, + jumped_to_color = false, view_cfg = nil, ---@type graphics_element + color_cfg = nil, ---@type graphics_element + color_next = nil, ---@type graphics_element + color_apply = nil, ---@type graphics_element settings_apply = nil, ---@type graphics_element gen_summary = nil, ---@type function @@ -136,6 +145,9 @@ local tmp_cfg = { LogMode = 0, LogPath = "", LogDebug = false, + MainTheme = 1, + FrontPanelTheme = 1, + ColorMode = 1 } ---@class crd_config @@ -162,7 +174,10 @@ local fields = { { "AuthKey", "Facility Auth Key" , ""}, { "LogMode", "Log Mode", log.MODE.APPEND }, { "LogPath", "Log Path", "/log.txt" }, - { "LogDebug","Log Debug Messages", false } + { "LogDebug", "Log Debug Messages", false }, + { "MainTheme", "Main UI Theme", themes.UI_THEME.SMOOTH_STONE }, + { "FrontPanelTheme", "Front Panel Theme", themes.FP_THEME.SANDSTONE }, + { "ColorMode", "Color Mode", themes.COLOR_MODE.STANDARD } } -- check if a value is an integer within a range (inclusive) @@ -313,10 +328,11 @@ local function config_view(display) local spkr_cfg = Div{parent=root_pane_div,x=1,y=1} local crd_cfg = Div{parent=root_pane_div,x=1,y=1} local log_cfg = Div{parent=root_pane_div,x=1,y=1} + local clr_cfg = Div{parent=root_pane_div,x=1,y=1} local summary = Div{parent=root_pane_div,x=1,y=1} local changelog = Div{parent=root_pane_div,x=1,y=1} - local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,net_cfg,fac_cfg,mon_cfg,spkr_cfg,crd_cfg,log_cfg,summary,changelog}} + local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,net_cfg,fac_cfg,mon_cfg,spkr_cfg,crd_cfg,log_cfg,clr_cfg,summary,changelog}} -- Main Page @@ -337,7 +353,7 @@ local function config_view(display) tool_ctl.viewing_config = true tool_ctl.gen_summary(settings_cfg) tool_ctl.settings_apply.hide(true) - main_pane.set_value(8) + main_pane.set_value(9) end if fs.exists("/coordinator/config.lua") then @@ -348,10 +364,21 @@ local function config_view(display) PushButton{parent=main_page,x=2,y=y_start,min_width=18,text="Configure System",callback=function()main_pane.set_value(2)end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg} tool_ctl.view_cfg = PushButton{parent=main_page,x=2,y=y_start+2,min_width=20,text="View Configuration",callback=view_config,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=dis_fg_bg} - if not tool_ctl.has_config then tool_ctl.view_cfg.disable() end + local function jump_color() + tool_ctl.jumped_to_color = true + tool_ctl.color_next.hide(true) + tool_ctl.color_apply.show() + main_pane.set_value(8) + end PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg} - PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(9)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(10)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + if not tool_ctl.has_config then + tool_ctl.view_cfg.disable() + tool_ctl.color_cfg.disable() + end --#region Network @@ -697,7 +724,7 @@ local function config_view(display) mon_pane.set_value(1) end - PushButton{parent=mon_c_4,x=1,y=14,text="\x1b Back",callback=back_from_legacy,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=mon_c_4,x=44,y=14,min_width=6,text="Done",callback=back_from_legacy,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} --#endregion @@ -734,8 +761,6 @@ local function config_view(display) local crd_c_1 = Div{parent=crd_cfg,x=2,y=4,width=49} - local crd_pane = MultiPane{parent=crd_cfg,x=1,y=4,panes={crd_c_1}} - TextBox{parent=crd_cfg,x=1,y=2,height=1,text=" Coordinator UI Configuration",fg_bg=cpair(colors.black,colors.lime)} TextBox{parent=crd_c_1,x=1,y=1,height=3,text="Configure the UI interface options below if you wish to customize formats."} @@ -782,10 +807,8 @@ local function config_view(display) tmp_cfg.LogMode = mode.get_value() - 1 tmp_cfg.LogPath = path.get_value() tmp_cfg.LogDebug = en_dbg.get_value() - tool_ctl.gen_summary(tmp_cfg) - tool_ctl.viewing_config = false - tool_ctl.importing_legacy = false - tool_ctl.settings_apply.show() + tool_ctl.color_apply.hide(true) + tool_ctl.color_next.show() main_pane.set_value(8) else path_err.show() end end @@ -795,6 +818,115 @@ local function config_view(display) --#endregion + --#region Color Options + + local clr_c_1 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_2 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49} + + local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}} + + TextBox{parent=clr_cfg,x=1,y=2,height=1,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)} + + TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color themes for the different UI displays."} + TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg} + + TextBox{parent=clr_c_1,x=1,y=7,height=1,text="Main UI Theme"} + local main_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.MainTheme,options=themes.UI_THEME_NAMES,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + TextBox{parent=clr_c_1,x=18,y=7,height=1,text="Front Panel Theme"} + local fp_theme = RadioButton{parent=clr_c_1,x=18,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."} + + local function recolor(value) + if value == 1 then + for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end + elseif value == 2 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf5e633) + term.setPaletteColor(colors.red, 0xff521a) + elseif value == 3 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf7c311) + term.setPaletteColor(colors.red, 0xfb5615) + elseif value == 4 then + term.setPaletteColor(colors.green, 0x00ecff) + term.setPaletteColor(colors.yellow, 0xffbc00) + term.setPaletteColor(colors.red, 0xff0000) + end + end + + local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + local _ = IndLight{parent=clr_c_2,x=20,y=8,label="Good",colors=cpair(colors.black,colors.green),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=9,label="Warning",colors=cpair(colors.black,colors.yellow),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=10,label="Bad",colors=cpair(colors.black,colors.red),value=true} + + TextBox{parent=clr_c_2,x=20,y=12,height=6,text="Exact color varies by theme.",fg_bg=g_lg_fg_bg} + + PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + local function back_from_colors() + main_pane.set_value(util.trinary(tool_ctl.jumped_to_color, 1, 7)) + tool_ctl.jumped_to_color = false + recolor(1) + end + + local function show_access() + clr_pane.set_value(2) + recolor(c_mode.get_value()) + end + + local function submit_colors() + tmp_cfg.MainTheme = main_theme.get_value() + tmp_cfg.FrontPanelTheme = fp_theme.get_value() + tmp_cfg.ColorMode = c_mode.get_value() + + if tool_ctl.jumped_to_color then + settings.set("MainTheme", tmp_cfg.MainTheme) + settings.set("FrontPanelTheme", tmp_cfg.FrontPanelTheme) + settings.set("ColorMode", tmp_cfg.ColorMode) + + if settings.save("/coordinator.settings") then + load_settings(settings_cfg, true) + load_settings(ini_cfg) + clr_pane.set_value(3) + else + clr_pane.set_value(4) + end + else + tool_ctl.gen_summary(tmp_cfg) + tool_ctl.viewing_config = false + tool_ctl.importing_legacy = false + tool_ctl.settings_apply.show() + main_pane.set_value(9) + end + end + + PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg} + + tool_ctl.color_apply.hide(true) + + local function c_go_home() + main_pane.set_value(1) + clr_pane.set_value(1) + end + + TextBox{parent=clr_c_3,x=1,y=1,height=1,text="Settings saved!"} + PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."} + PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + --#endregion + --#region Summary and Saving local sum_c_1 = Div{parent=summary,x=2,y=4,width=49} @@ -815,7 +947,7 @@ local function config_view(display) tool_ctl.importing_legacy = false tool_ctl.settings_apply.show() else - main_pane.set_value(7) + main_pane.set_value(8) end end @@ -846,12 +978,16 @@ local function config_view(display) try_set(mode, ini_cfg.LogMode) try_set(path, ini_cfg.LogPath) try_set(en_dbg, ini_cfg.LogDebug) + try_set(main_theme, ini_cfg.MainTheme) + try_set(fp_theme, ini_cfg.FrontPanelTheme) + try_set(c_mode, ini_cfg.ColorMode) preset_monitor_fields() tool_ctl.gen_mon_list() tool_ctl.view_cfg.enable() + tool_ctl.color_cfg.enable() if tool_ctl.importing_legacy then tool_ctl.importing_legacy = false @@ -875,7 +1011,7 @@ local function config_view(display) net_pane.set_value(1) fac_pane.set_value(1) mon_pane.set_value(1) - crd_pane.set_value(1) + clr_pane.set_value(1) sum_pane.set_value(1) end @@ -972,7 +1108,7 @@ local function config_view(display) tool_ctl.gen_summary(tmp_cfg) sum_pane.set_value(1) - main_pane.set_value(8) + main_pane.set_value(9) tool_ctl.importing_legacy = true end @@ -1195,7 +1331,13 @@ local function config_view(display) if f[1] == "AuthKey" then val = string.rep("*", string.len(val)) elseif f[1] == "LogMode" then val = util.trinary(raw == log.MODE.APPEND, "append", "replace") elseif f[1] == "TempScale" then - if raw == 1 then val = "Kelvin" elseif raw == 2 then val = "Celsius" elseif raw == 3 then val = "Fahrenheit" else val = "Rankine" end + if raw == 1 then val = "Kelvin" elseif raw == 2 then val = "Celsius" elseif raw == 3 then val = "Fahrenheit" elseif raw == 4 then val = "Rankine" end + elseif f[1] == "MainTheme" then + val = util.strval(themes.ui_theme_name(raw)) + elseif f[1] == "FrontPanelTheme" then + val = util.strval(themes.fp_theme_name(raw)) + elseif f[1] == "ColorMode" then + val = util.strval(themes.color_mode_name(raw)) elseif f[1] == "UnitDisplays" and type(cfg.UnitDisplays) == "table" then val = "" for idx = 1, #cfg.UnitDisplays do diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index bc97c99..85387b4 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -54,6 +54,10 @@ function coordinator.load_config() config.LogPath = settings.get("LogPath") config.LogDebug = settings.get("LogDebug") + config.MainTheme = settings.get("MainTheme") + config.FrontPanelTheme = settings.get("FrontPanelTheme") + config.ColorMode = settings.get("ColorMode") + local cfv = util.new_validator() cfv.assert_type_int(config.UnitCount) @@ -91,6 +95,13 @@ function coordinator.load_config() cfv.assert_type_str(config.LogPath) cfv.assert_type_bool(config.LogDebug) + cfv.assert_type_int(config.MainTheme) + cfv.assert_range(config.MainTheme, 1, 2) + cfv.assert_type_int(config.FrontPanelTheme) + cfv.assert_range(config.FrontPanelTheme, 1, 2) + cfv.assert_type_int(config.ColorMode) + cfv.assert_range(config.ColorMode, 1, 4) + -- Monitor Setup ---@class monitors_struct diff --git a/coordinator/renderer.lua b/coordinator/renderer.lua index 541b1a7..c05afee 100644 --- a/coordinator/renderer.lua +++ b/coordinator/renderer.lua @@ -47,8 +47,8 @@ local function _init_display(monitor) monitor.setCursorPos(1, 1) -- set overridden colors - for i = 1, #style.colors do - monitor.setPaletteColor(style.colors[i].c, style.colors[i].hex) + for i = 1, #style.theme.colors do + monitor.setPaletteColor(style.theme.colors[i].c, style.theme.colors[i].hex) end end @@ -97,8 +97,8 @@ function renderer.init_displays() term.setCursorPos(1, 1) -- set overridden colors - for i = 1, #style.fp.colors do - term.setPaletteColor(style.fp.colors[i].c, style.fp.colors[i].hex) + for i = 1, #style.fp_theme.colors do + term.setPaletteColor(style.fp_theme.colors[i].c, style.fp_theme.colors[i].hex) end end @@ -152,9 +152,9 @@ function renderer.close_fp() engine.fp_ready = false -- restore colors - for i = 1, #style.colors do - local r, g, b = term.nativePaletteColor(style.colors[i].c) - term.setPaletteColor(style.colors[i].c, r, g, b) + for i = 1, #style.fp_theme.colors do + local r, g, b = term.nativePaletteColor(style.fp_theme.colors[i].c) + term.setPaletteColor(style.fp_theme.colors[i].c, r, g, b) end -- reset terminal diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 10294f8..feeafd0 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -22,7 +22,9 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v1.2.11" +local style = require("coordinator.ui.style") + +local COORDINATOR_VERSION = "v1.2.12" local CHUNK_LOAD_DELAY_S = 30.0 @@ -120,6 +122,7 @@ local function main() iocontrol.init_fp(COORDINATOR_VERSION, comms.version) -- init renderer + style.set_themes(config.MainTheme, config.FrontPanelTheme) renderer.legacy_disable_flow_view(config.DisableFlowView) renderer.set_displays(monitors) renderer.init_displays() diff --git a/coordinator/ui/components/boiler.lua b/coordinator/ui/components/boiler.lua index ce2f1bc..0b7843f 100644 --- a/coordinator/ui/components/boiler.lua +++ b/coordinator/ui/components/boiler.lua @@ -14,31 +14,31 @@ local VerticalBar = require("graphics.elements.indicators.vbar") local cpair = core.cpair local border = core.border -local text_fg_bg = style.text_colors -local lu_col = style.lu_colors - -- new boiler view ---@param root graphics_element parent ---@param x integer top left x ---@param y integer top left y ---@param ps psil ps interface local function new_view(root, x, y, ps) + local text_fg = style.theme.text_fg + local lu_col = style.lu_colors + local db = iocontrol.get_db() local boiler = Rectangle{parent=root,border=border(1,colors.gray,true),width=31,height=7,x=x,y=y} local status = StateIndicator{parent=boiler,x=9,y=1,states=style.boiler.states,value=1,min_width=12} - local temp = DataIndicator{parent=boiler,x=5,y=3,lu_colors=lu_col,label="Temp:",unit=db.temp_label,format="%10.2f",value=0,commas=true,width=22,fg_bg=text_fg_bg} - local boil_r = DataIndicator{parent=boiler,x=5,y=4,lu_colors=lu_col,label="Boil:",unit="mB/t",format="%10.0f",value=0,commas=true,width=22,fg_bg=text_fg_bg} + local temp = DataIndicator{parent=boiler,x=5,y=3,lu_colors=lu_col,label="Temp:",unit=db.temp_label,format="%10.2f",value=0,commas=true,width=22,fg_bg=text_fg} + local boil_r = DataIndicator{parent=boiler,x=5,y=4,lu_colors=lu_col,label="Boil:",unit="mB/t",format="%10.0f",value=0,commas=true,width=22,fg_bg=text_fg} status.register(ps, "computed_status", status.update) temp.register(ps, "temperature", function (t) temp.update(db.temp_convert(t)) end) boil_r.register(ps, "boil_rate", boil_r.update) - TextBox{parent=boiler,text="H",x=2,y=5,height=1,width=1,fg_bg=text_fg_bg} - TextBox{parent=boiler,text="W",x=3,y=5,height=1,width=1,fg_bg=text_fg_bg} - TextBox{parent=boiler,text="S",x=27,y=5,height=1,width=1,fg_bg=text_fg_bg} - TextBox{parent=boiler,text="C",x=28,y=5,height=1,width=1,fg_bg=text_fg_bg} + TextBox{parent=boiler,text="H",x=2,y=5,height=1,width=1,fg_bg=text_fg} + TextBox{parent=boiler,text="W",x=3,y=5,height=1,width=1,fg_bg=text_fg} + TextBox{parent=boiler,text="S",x=27,y=5,height=1,width=1,fg_bg=text_fg} + TextBox{parent=boiler,text="C",x=28,y=5,height=1,width=1,fg_bg=text_fg} local hcool = VerticalBar{parent=boiler,x=2,y=1,fg_bg=cpair(colors.orange,colors.gray),height=4,width=1} local water = VerticalBar{parent=boiler,x=3,y=1,fg_bg=cpair(colors.blue,colors.gray),height=4,width=1} diff --git a/coordinator/ui/components/imatrix.lua b/coordinator/ui/components/imatrix.lua index fc2e038..078661a 100644 --- a/coordinator/ui/components/imatrix.lua +++ b/coordinator/ui/components/imatrix.lua @@ -18,9 +18,6 @@ local border = core.border local ALIGN = core.ALIGN -local text_fg_bg = style.text_colors -local lu_col = style.lu_colors - -- new induction matrix view ---@param root graphics_element parent ---@param x integer top left x @@ -29,27 +26,30 @@ local lu_col = style.lu_colors ---@param ps psil ps interface ---@param id number? matrix ID local function new_view(root, x, y, data, ps, id) + local text_fg = style.theme.text_fg + local lu_col = style.lu_colors + local title = "INDUCTION MATRIX" if type(id) == "number" then title = title .. id end local matrix = Div{parent=root,fg_bg=style.root,width=33,height=24,x=x,y=y} - TextBox{parent=matrix,text=" ",width=33,height=1,x=1,y=1,fg_bg=style.lg_gray} - TextBox{parent=matrix,text=title,alignment=ALIGN.CENTER,width=33,height=1,x=1,y=2,fg_bg=style.lg_gray} + local cutout_fg_bg = cpair(style.theme.bg, colors.gray) + + TextBox{parent=matrix,text=" ",width=33,height=1,x=1,y=1,fg_bg=cutout_fg_bg} + TextBox{parent=matrix,text=title,alignment=ALIGN.CENTER,width=33,height=1,x=1,y=2,fg_bg=cutout_fg_bg} local rect = Rectangle{parent=matrix,border=border(1,colors.gray,true),width=33,height=22,x=1,y=3} - local label_fg_bg = cpair(colors.gray, colors.lightGray) - local status = StateIndicator{parent=rect,x=10,y=1,states=style.imatrix.states,value=1,min_width=14} - local energy = PowerIndicator{parent=rect,x=7,y=3,lu_colors=lu_col,label="Energy: ",format="%8.2f",value=0,width=26,fg_bg=text_fg_bg} - local capacity = PowerIndicator{parent=rect,x=7,y=4,lu_colors=lu_col,label="Capacity:",format="%8.2f",value=0,width=26,fg_bg=text_fg_bg} - local input = PowerIndicator{parent=rect,x=7,y=5,lu_colors=lu_col,label="Input: ",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg_bg} - local output = PowerIndicator{parent=rect,x=7,y=6,lu_colors=lu_col,label="Output: ",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg_bg} + local energy = PowerIndicator{parent=rect,x=7,y=3,lu_colors=lu_col,label="Energy: ",format="%8.2f",value=0,width=26,fg_bg=text_fg} + local capacity = PowerIndicator{parent=rect,x=7,y=4,lu_colors=lu_col,label="Capacity:",format="%8.2f",value=0,width=26,fg_bg=text_fg} + local input = PowerIndicator{parent=rect,x=7,y=5,lu_colors=lu_col,label="Input: ",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg} + local output = PowerIndicator{parent=rect,x=7,y=6,lu_colors=lu_col,label="Output: ",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg} - local avg_chg = PowerIndicator{parent=rect,x=7,y=8,lu_colors=lu_col,label="Avg. Chg:",format="%8.2f",value=0,width=26,fg_bg=text_fg_bg} - local avg_in = PowerIndicator{parent=rect,x=7,y=9,lu_colors=lu_col,label="Avg. In: ",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg_bg} - local avg_out = PowerIndicator{parent=rect,x=7,y=10,lu_colors=lu_col,label="Avg. Out:",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg_bg} + local avg_chg = PowerIndicator{parent=rect,x=7,y=8,lu_colors=lu_col,label="Avg. Chg:",format="%8.2f",value=0,width=26,fg_bg=text_fg} + local avg_in = PowerIndicator{parent=rect,x=7,y=9,lu_colors=lu_col,label="Avg. In: ",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg} + local avg_out = PowerIndicator{parent=rect,x=7,y=10,lu_colors=lu_col,label="Avg. Out:",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg} status.register(ps, "computed_status", status.update) energy.register(ps, "energy", function (val) energy.update(util.joules_to_fe(val)) end) @@ -61,13 +61,13 @@ local function new_view(root, x, y, data, ps, id) avg_in.register(ps, "avg_inflow", avg_in.update) avg_out.register(ps, "avg_outflow", avg_out.update) - local fill = DataIndicator{parent=rect,x=11,y=12,lu_colors=lu_col,label="Fill:",unit="%",format="%8.2f",value=0,width=18,fg_bg=text_fg_bg} + local fill = DataIndicator{parent=rect,x=11,y=12,lu_colors=lu_col,label="Fill:",unit="%",format="%8.2f",value=0,width=18,fg_bg=text_fg} - local cells = DataIndicator{parent=rect,x=11,y=14,lu_colors=lu_col,label="Cells: ",format="%7d",value=0,width=18,fg_bg=text_fg_bg} - local providers = DataIndicator{parent=rect,x=11,y=15,lu_colors=lu_col,label="Providers:",format="%7d",value=0,width=18,fg_bg=text_fg_bg} + local cells = DataIndicator{parent=rect,x=11,y=14,lu_colors=lu_col,label="Cells: ",format="%7d",value=0,width=18,fg_bg=text_fg} + local providers = DataIndicator{parent=rect,x=11,y=15,lu_colors=lu_col,label="Providers:",format="%7d",value=0,width=18,fg_bg=text_fg} - TextBox{parent=rect,text="Transfer Capacity",x=11,y=17,height=1,width=17,fg_bg=label_fg_bg} - local trans_cap = PowerIndicator{parent=rect,x=19,y=18,lu_colors=lu_col,label="",format="%5.2f",rate=true,value=0,width=12,fg_bg=text_fg_bg} + TextBox{parent=rect,text="Transfer Capacity",x=11,y=17,height=1,width=17,fg_bg=style.theme.label_fg} + local trans_cap = PowerIndicator{parent=rect,x=19,y=18,lu_colors=lu_col,label="",format="%5.2f",rate=true,value=0,width=12,fg_bg=text_fg} cells.register(ps, "cells", cells.update) providers.register(ps, "providers", providers.update) @@ -78,8 +78,8 @@ local function new_view(root, x, y, data, ps, id) local in_cap = VerticalBar{parent=rect,x=7,y=12,fg_bg=cpair(colors.red,colors.gray),height=7,width=1} local out_cap = VerticalBar{parent=rect,x=9,y=12,fg_bg=cpair(colors.blue,colors.gray),height=7,width=1} - TextBox{parent=rect,text="FILL",x=2,y=20,height=1,width=4,fg_bg=text_fg_bg} - TextBox{parent=rect,text="I/O",x=7,y=20,height=1,width=3,fg_bg=text_fg_bg} + TextBox{parent=rect,text="FILL",x=2,y=20,height=1,width=4,fg_bg=text_fg} + TextBox{parent=rect,text="I/O",x=7,y=20,height=1,width=3,fg_bg=text_fg} local function calc_saturation(val) if (type(data.build) == "table") and (type(data.build.transfer_cap) == "number") and (data.build.transfer_cap > 0) then diff --git a/coordinator/ui/components/pkt_entry.lua b/coordinator/ui/components/pkt_entry.lua index d6ba4be..760f406 100644 --- a/coordinator/ui/components/pkt_entry.lua +++ b/coordinator/ui/components/pkt_entry.lua @@ -17,33 +17,35 @@ local ALIGN = core.ALIGN local cpair = core.cpair -local text_fg_bg = style.text_colors -local lg_wh = style.lg_white - -- create a pocket list entry ---@param parent graphics_element parent ---@param id integer PKT session ID local function init(parent, id) + local s_hi_box = style.fp_theme.highlight_box + local s_hi_bright = style.fp_theme.highlight_box_bright + + local label_fg = style.fp.label_fg + local ps = iocontrol.get_db().fp.ps -- root div local root = Div{parent=parent,x=2,y=2,height=4,width=parent.get_width()-2,hidden=true} - local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=style.bw_fg_bg} + local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=s_hi_bright} local ps_prefix = "pkt_" .. id .. "_" - TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=text_fg_bg} - local pkt_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,height=1,fg_bg=text_fg_bg,nav_active=cpair(colors.gray,colors.black)} - TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=text_fg_bg} + TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=s_hi_box} + local pkt_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,height=1,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)} + TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=s_hi_box} pkt_addr.register(ps, ps_prefix .. "addr", pkt_addr.set_value) TextBox{parent=entry,x=10,y=2,text="FW:",width=3,height=1} - local pkt_fw_v = TextBox{parent=entry,x=14,y=2,text=" ------- ",width=20,height=1,fg_bg=lg_wh} + local pkt_fw_v = TextBox{parent=entry,x=14,y=2,text=" ------- ",width=20,height=1,fg_bg=label_fg} pkt_fw_v.register(ps, ps_prefix .. "fw", pkt_fw_v.set_value) TextBox{parent=entry,x=35,y=2,text="RTT:",width=4,height=1} - local pkt_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=lg_wh} - TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=lg_wh} + local pkt_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=label_fg} + TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=label_fg} pkt_rtt.register(ps, ps_prefix .. "rtt", pkt_rtt.update) pkt_rtt.register(ps, ps_prefix .. "rtt_color", pkt_rtt.recolor) diff --git a/coordinator/ui/components/process_ctl.lua b/coordinator/ui/components/process_ctl.lua index efc6eb1..e1c3252 100644 --- a/coordinator/ui/components/process_ctl.lua +++ b/coordinator/ui/components/process_ctl.lua @@ -29,11 +29,6 @@ local cpair = core.cpair local border = core.border local bw_fg_bg = style.bw_fg_bg -local lu_cpair = style.lu_colors -local hzd_fg_bg = style.hzd_fg_bg -local dis_colors = style.dis_colors - -local gry_wht = style.gray_white local ind_grn = style.ind_grn local ind_yel = style.ind_yel @@ -47,6 +42,14 @@ local period = core.flasher.PERIOD ---@param x integer top left x ---@param y integer top left y local function new_view(root, x, y) + local s_hi_box = style.theme.highlight_box + local s_field = style.theme.field_box + + local lu_cpair = style.lu_colors + local hzd_fg_bg = style.hzd_fg_bg + local dis_colors = style.dis_colors + local arrow_fg_bg = cpair(style.theme.label, s_hi_box.bkg) + assert(root.get_height() >= (y + 24), "main display not of sufficient vertical resolution (add an additional row of monitors)") local black = cpair(colors.black, colors.black) @@ -103,11 +106,11 @@ local function new_view(root, x, y) gen_fault.register(facility.ps, "as_gen_fault", gen_fault.update) TextBox{parent=main,y=23,text="Radiation",height=1,width=13,fg_bg=style.label} - local radiation = RadIndicator{parent=main,label="",format="%9.3f",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} + local radiation = RadIndicator{parent=main,label="",format="%9.3f",lu_colors=lu_cpair,width=13,fg_bg=s_field} radiation.register(facility.ps, "radiation", radiation.update) TextBox{parent=main,x=15,y=23,text="Linked RTUs",height=1,width=11,fg_bg=style.label} - local rtu_count = DataIndicator{parent=main,x=15,y=24,label="",format="%11d",value=0,lu_colors=lu_cpair,width=11,fg_bg=bw_fg_bg} + local rtu_count = DataIndicator{parent=main,x=15,y=24,label="",format="%11d",value=0,lu_colors=lu_cpair,width=11,fg_bg=s_field} rtu_count.register(facility.ps, "rtu_count", rtu_count.update) --------------------- @@ -125,9 +128,9 @@ local function new_view(root, x, y) local burn_tag = Div{parent=targets,x=1,y=1,width=8,height=4,fg_bg=blk_pur} TextBox{parent=burn_tag,x=2,y=2,text="Burn Target",width=7,height=2} - local burn_target = Div{parent=targets,x=9,y=1,width=23,height=3,fg_bg=gry_wht} - local b_target = SpinboxNumeric{parent=burn_target,x=11,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=gry_wht,fg_bg=bw_fg_bg} - TextBox{parent=burn_target,x=18,y=2,text="mB/t"} + local burn_target = Div{parent=targets,x=9,y=1,width=23,height=3,fg_bg=s_hi_box} + local b_target = SpinboxNumeric{parent=burn_target,x=11,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} + TextBox{parent=burn_target,x=18,y=2,text="mB/t",fg_bg=style.theme.label_fg} local burn_sum = DataIndicator{parent=targets,x=9,y=4,label="",format="%18.1f",value=0,unit="mB/t",commas=true,lu_colors=black,width=23,fg_bg=blk_brn} b_target.register(facility.ps, "process_burn_target", b_target.set_value) @@ -136,9 +139,9 @@ local function new_view(root, x, y) local chg_tag = Div{parent=targets,x=1,y=6,width=8,height=4,fg_bg=blk_pur} TextBox{parent=chg_tag,x=2,y=2,text="Charge Target",width=7,height=2} - local chg_target = Div{parent=targets,x=9,y=6,width=23,height=3,fg_bg=gry_wht} - local c_target = SpinboxNumeric{parent=chg_target,x=2,y=1,whole_num_precision=15,fractional_precision=0,min=0,arrow_fg_bg=gry_wht,fg_bg=bw_fg_bg} - TextBox{parent=chg_target,x=18,y=2,text="MFE"} + local chg_target = Div{parent=targets,x=9,y=6,width=23,height=3,fg_bg=s_hi_box} + local c_target = SpinboxNumeric{parent=chg_target,x=2,y=1,whole_num_precision=15,fractional_precision=0,min=0,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} + TextBox{parent=chg_target,x=18,y=2,text="MFE",fg_bg=style.theme.label_fg} local cur_charge = DataIndicator{parent=targets,x=9,y=9,label="",format="%19d",value=0,unit="MFE",commas=true,lu_colors=black,width=23,fg_bg=blk_brn} c_target.register(facility.ps, "process_charge_target", c_target.set_value) @@ -147,9 +150,9 @@ local function new_view(root, x, y) local gen_tag = Div{parent=targets,x=1,y=11,width=8,height=4,fg_bg=blk_pur} TextBox{parent=gen_tag,x=2,y=2,text="Gen. Target",width=7,height=2} - local gen_target = Div{parent=targets,x=9,y=11,width=23,height=3,fg_bg=gry_wht} - local g_target = SpinboxNumeric{parent=gen_target,x=8,y=1,whole_num_precision=9,fractional_precision=0,min=0,arrow_fg_bg=gry_wht,fg_bg=bw_fg_bg} - TextBox{parent=gen_target,x=18,y=2,text="kFE/t"} + local gen_target = Div{parent=targets,x=9,y=11,width=23,height=3,fg_bg=s_hi_box} + local g_target = SpinboxNumeric{parent=gen_target,x=8,y=1,whole_num_precision=9,fractional_precision=0,min=0,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} + TextBox{parent=gen_target,x=18,y=2,text="kFE/t",fg_bg=style.theme.label_fg} local cur_gen = DataIndicator{parent=targets,x=9,y=14,label="",format="%17d",value=0,unit="kFE/t",commas=true,lu_colors=black,width=23,fg_bg=blk_brn} g_target.register(facility.ps, "process_gen_target", g_target.set_value) @@ -165,17 +168,17 @@ local function new_view(root, x, y) for i = 1, 4 do local unit - local tag_fg_bg = gry_wht - local lim_fg_bg = style.lg_white - local ctl_fg = colors.lightGray - local cur_fg_bg = style.lg_white - local cur_lu = colors.lightGray + local tag_fg_bg = cpair(style.theme.disabled, s_hi_box.bkg) + local lim_fg_bg = cpair(style.theme.disabled, s_hi_box.bkg) + local label_fg = style.theme.disabled_fg + local cur_fg_bg = cpair(style.theme.disabled, s_hi_box.bkg) + local cur_lu = style.theme.disabled if i <= facility.num_units then unit = units[i] ---@type ioctl_unit - tag_fg_bg = cpair(colors.black,colors.lightBlue) - lim_fg_bg = bw_fg_bg - ctl_fg = colors.gray + tag_fg_bg = cpair(colors.black, colors.lightBlue) + lim_fg_bg = s_hi_box + label_fg = style.theme.label_fg cur_fg_bg = blk_brn cur_lu = colors.black end @@ -185,9 +188,9 @@ local function new_view(root, x, y) local unit_tag = Div{parent=limit_div,x=1,y=_y,width=8,height=4,fg_bg=tag_fg_bg} TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Limit",width=7,height=2} - local lim_ctl = Div{parent=limit_div,x=9,y=_y,width=14,height=3,fg_bg=cpair(ctl_fg,colors.white)} - local lim = SpinboxNumeric{parent=lim_ctl,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=gry_wht,fg_bg=lim_fg_bg} - TextBox{parent=lim_ctl,x=9,y=2,text="mB/t",width=4,height=1} + local lim_ctl = Div{parent=limit_div,x=9,y=_y,width=14,height=3,fg_bg=s_hi_box} + local lim = SpinboxNumeric{parent=lim_ctl,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled,fg_bg=lim_fg_bg} + TextBox{parent=lim_ctl,x=9,y=2,text="mB/t",width=4,height=1,fg_bg=label_fg} local cur_burn = DataIndicator{parent=limit_div,x=9,y=_y+3,label="",format="%7.1f",value=0,unit="mB/t",commas=false,lu_colors=cpair(cur_lu,cur_lu),width=14,fg_bg=cur_fg_bg} @@ -209,14 +212,14 @@ local function new_view(root, x, y) local stat_div = Div{parent=proc,width=22,height=24,x=57,y=6} for i = 1, 4 do - local tag_fg_bg = gry_wht - local ind_fg_bg = style.lg_white - local ind_off = colors.lightGray + local tag_fg_bg = cpair(style.theme.disabled, s_hi_box.bkg) + local ind_fg_bg = cpair(style.theme.disabled, s_hi_box.bkg) + local ind_off = style.theme.disabled if i <= facility.num_units then tag_fg_bg = cpair(colors.black, colors.cyan) - ind_fg_bg = bw_fg_bg - ind_off = colors.gray + ind_fg_bg = cpair(style.theme.text, s_hi_box.bkg) + ind_off = style.theme.label end local _y = ((i - 1) * 5) + 1 @@ -241,18 +244,18 @@ local function new_view(root, x, y) ------------------------- local ctl_opts = { "Monitored Max Burn", "Combined Burn Rate", "Charge Level", "Generation Rate" } - local mode = RadioButton{parent=proc,x=34,y=1,options=ctl_opts,callback=function()end,radio_colors=cpair(colors.gray,colors.white),select_color=colors.purple} + local mode = RadioButton{parent=proc,x=34,y=1,options=ctl_opts,callback=function()end,radio_colors=cpair(style.theme.accent_dark,style.theme.accent_light),select_color=colors.purple} mode.register(facility.ps, "process_mode", mode.set_value) local u_stat = Rectangle{parent=proc,border=border(1,colors.gray,true),thin=true,width=31,height=4,x=1,y=16,fg_bg=bw_fg_bg} local stat_line_1 = TextBox{parent=u_stat,x=1,y=1,text="UNKNOWN",width=31,height=1,alignment=ALIGN.CENTER,fg_bg=bw_fg_bg} - local stat_line_2 = TextBox{parent=u_stat,x=1,y=2,text="awaiting data...",width=31,height=1,alignment=ALIGN.CENTER,fg_bg=gry_wht} + local stat_line_2 = TextBox{parent=u_stat,x=1,y=2,text="awaiting data...",width=31,height=1,alignment=ALIGN.CENTER,fg_bg=cpair(colors.gray,colors.white)} stat_line_1.register(facility.ps, "status_line_1", stat_line_1.set_value) stat_line_2.register(facility.ps, "status_line_2", stat_line_2.set_value) - local auto_controls = Div{parent=proc,x=1,y=20,width=31,height=5,fg_bg=gry_wht} + local auto_controls = Div{parent=proc,x=1,y=20,width=31,height=5,fg_bg=s_hi_box} -- save the automatic process control configuration without starting local function _save_cfg() @@ -327,16 +330,18 @@ local function new_view(root, x, y) local waste_sel = Div{parent=proc,width=21,height=24,x=81,y=1} - TextBox{parent=waste_sel,text=" ",width=21,height=1,x=1,y=1,fg_bg=blk_brn} - TextBox{parent=waste_sel,text="WASTE PRODUCTION",alignment=ALIGN.CENTER,width=21,height=1,x=1,y=2,fg_bg=cpair(colors.lightGray,colors.brown)} + local cutout_fg_bg = cpair(style.theme.bg, colors.brown) + + TextBox{parent=waste_sel,text=" ",width=21,height=1,x=1,y=1,fg_bg=cutout_fg_bg} + TextBox{parent=waste_sel,text="WASTE PRODUCTION",alignment=ALIGN.CENTER,width=21,height=1,x=1,y=2,fg_bg=cutout_fg_bg} local rect = Rectangle{parent=waste_sel,border=border(1,colors.brown,true),width=21,height=22,x=1,y=3} local status = StateIndicator{parent=rect,x=2,y=1,states=style.waste.states,value=1,min_width=17} status.register(facility.ps, "current_waste_product", status.update) - local waste_prod = RadioButton{parent=rect,x=2,y=3,options=style.waste.options,callback=process.set_process_waste,radio_colors=cpair(colors.gray,colors.white),select_color=colors.brown} - local pu_fallback = Checkbox{parent=rect,x=2,y=7,label="Pu Fallback",callback=process.set_pu_fallback,box_fg_bg=cpair(colors.green,colors.black)} + local waste_prod = RadioButton{parent=rect,x=2,y=3,options=style.waste.options,callback=process.set_process_waste,radio_colors=cpair(style.theme.accent_dark,style.theme.accent_light),select_color=colors.brown} + local pu_fallback = Checkbox{parent=rect,x=2,y=7,label="Pu Fallback",callback=process.set_pu_fallback,box_fg_bg=cpair(colors.green,style.theme.accent_light)} waste_prod.register(facility.ps, "process_waste_product", waste_prod.set_value) pu_fallback.register(facility.ps, "process_pu_fallback", pu_fallback.set_value) @@ -346,13 +351,13 @@ local function new_view(root, x, y) fb_active.register(facility.ps, "pu_fallback_active", fb_active.update) TextBox{parent=rect,x=2,y=11,text="Plutonium Rate",height=1,width=17,fg_bg=style.label} - local pu_rate = DataIndicator{parent=rect,x=2,label="",unit="mB/t",format="%12.2f",value=0,lu_colors=lu_cpair,fg_bg=bw_fg_bg,width=17} + local pu_rate = DataIndicator{parent=rect,x=2,label="",unit="mB/t",format="%12.2f",value=0,lu_colors=lu_cpair,fg_bg=s_field,width=17} TextBox{parent=rect,x=2,y=14,text="Polonium Rate",height=1,width=17,fg_bg=style.label} - local po_rate = DataIndicator{parent=rect,x=2,label="",unit="mB/t",format="%12.2f",value=0,lu_colors=lu_cpair,fg_bg=bw_fg_bg,width=17} + local po_rate = DataIndicator{parent=rect,x=2,label="",unit="mB/t",format="%12.2f",value=0,lu_colors=lu_cpair,fg_bg=s_field,width=17} TextBox{parent=rect,x=2,y=17,text="Antimatter Rate",height=1,width=17,fg_bg=style.label} - local am_rate = DataIndicator{parent=rect,x=2,label="",unit="\xb5B/t",format="%12d",value=0,lu_colors=lu_cpair,fg_bg=bw_fg_bg,width=17} + local am_rate = DataIndicator{parent=rect,x=2,label="",unit="\xb5B/t",format="%12d",value=0,lu_colors=lu_cpair,fg_bg=s_field,width=17} pu_rate.register(facility.ps, "pu_rate", pu_rate.update) po_rate.register(facility.ps, "po_rate", po_rate.update) diff --git a/coordinator/ui/components/reactor.lua b/coordinator/ui/components/reactor.lua index 27b033e..8e6005d 100644 --- a/coordinator/ui/components/reactor.lua +++ b/coordinator/ui/components/reactor.lua @@ -16,23 +16,23 @@ local StateIndicator = require("graphics.elements.indicators.state") local cpair = core.cpair local border = core.border -local text_fg_bg = style.text_colors -local lu_col = style.lu_colors - -- create new reactor view ---@param root graphics_element parent ---@param x integer top left x ---@param y integer top left y ---@param ps psil ps interface local function new_view(root, x, y, ps) + local text_fg = style.theme.text_fg + local lu_col = style.lu_colors + local db = iocontrol.get_db() - local reactor = Rectangle{parent=root,border=border(1, colors.gray, true),width=30,height=7,x=x,y=y} + local reactor = Rectangle{parent=root,border=border(1,colors.gray,true),width=30,height=7,x=x,y=y} local status = StateIndicator{parent=reactor,x=6,y=1,states=style.reactor.states,value=1,min_width=16} - local core_temp = DataIndicator{parent=reactor,x=2,y=3,lu_colors=lu_col,label="Core Temp:",unit=db.temp_label,format="%10.2f",value=0,commas=true,width=26,fg_bg=text_fg_bg} - local burn_r = DataIndicator{parent=reactor,x=2,y=4,lu_colors=lu_col,label="Burn Rate:",unit="mB/t",format="%10.2f",value=0,width=26,fg_bg=text_fg_bg} - local heating_r = DataIndicator{parent=reactor,x=2,y=5,lu_colors=lu_col,label="Heating:",unit="mB/t",format="%12.0f",value=0,commas=true,width=26,fg_bg=text_fg_bg} + local core_temp = DataIndicator{parent=reactor,x=2,y=3,lu_colors=lu_col,label="Core Temp:",unit=db.temp_label,format="%10.2f",value=0,commas=true,width=26,fg_bg=text_fg} + local burn_r = DataIndicator{parent=reactor,x=2,y=4,lu_colors=lu_col,label="Burn Rate:",unit="mB/t",format="%10.2f",value=0,width=26,fg_bg=text_fg} + local heating_r = DataIndicator{parent=reactor,x=2,y=5,lu_colors=lu_col,label="Heating:",unit="mB/t",format="%12.0f",value=0,commas=true,width=26,fg_bg=text_fg} status.register(ps, "computed_status", status.update) core_temp.register(ps, "temp", function (t) core_temp.update(db.temp_convert(t)) end) @@ -41,12 +41,12 @@ local function new_view(root, x, y, ps) local reactor_fills = Rectangle{parent=root,border=border(1, colors.gray, true),width=24,height=7,x=(x + 29),y=y} - TextBox{parent=reactor_fills,text="FUEL",x=2,y=1,height=1,fg_bg=text_fg_bg} - TextBox{parent=reactor_fills,text="COOL",x=2,y=2,height=1,fg_bg=text_fg_bg} - TextBox{parent=reactor_fills,text="HCOOL",x=2,y=4,height=1,fg_bg=text_fg_bg} - TextBox{parent=reactor_fills,text="WASTE",x=2,y=5,height=1,fg_bg=text_fg_bg} + TextBox{parent=reactor_fills,text="FUEL",x=2,y=1,height=1,fg_bg=text_fg} + TextBox{parent=reactor_fills,text="COOL",x=2,y=2,height=1,fg_bg=text_fg} + TextBox{parent=reactor_fills,text="HCOOL",x=2,y=4,height=1,fg_bg=text_fg} + TextBox{parent=reactor_fills,text="WASTE",x=2,y=5,height=1,fg_bg=text_fg} - local fuel = HorizontalBar{parent=reactor_fills,x=8,y=1,show_percent=true,bar_fg_bg=cpair(colors.black,colors.gray),height=1,width=14} + local fuel = HorizontalBar{parent=reactor_fills,x=8,y=1,show_percent=true,bar_fg_bg=cpair(style.theme.fuel_color,colors.gray),height=1,width=14} local ccool = HorizontalBar{parent=reactor_fills,x=8,y=2,show_percent=true,bar_fg_bg=cpair(colors.blue,colors.gray),height=1,width=14} local hcool = HorizontalBar{parent=reactor_fills,x=8,y=4,show_percent=true,bar_fg_bg=cpair(colors.white,colors.gray),height=1,width=14} local waste = HorizontalBar{parent=reactor_fills,x=8,y=5,show_percent=true,bar_fg_bg=cpair(colors.brown,colors.gray),height=1,width=14} diff --git a/coordinator/ui/components/turbine.lua b/coordinator/ui/components/turbine.lua index d8b2e17..75cbabd 100644 --- a/coordinator/ui/components/turbine.lua +++ b/coordinator/ui/components/turbine.lua @@ -15,20 +15,20 @@ local VerticalBar = require("graphics.elements.indicators.vbar") local cpair = core.cpair local border = core.border -local text_fg_bg = style.text_colors -local lu_col = style.lu_colors - -- new turbine view ---@param root graphics_element parent ---@param x integer top left x ---@param y integer top left y ---@param ps psil ps interface local function new_view(root, x, y, ps) + local text_fg = style.theme.text_fg + local lu_col = style.lu_colors + local turbine = Rectangle{parent=root,border=border(1,colors.gray,true),width=23,height=7,x=x,y=y} local status = StateIndicator{parent=turbine,x=7,y=1,states=style.turbine.states,value=1,min_width=12} - local prod_rate = PowerIndicator{parent=turbine,x=5,y=3,lu_colors=lu_col,label="",format="%10.2f",value=0,rate=true,width=16,fg_bg=text_fg_bg} - local flow_rate = DataIndicator{parent=turbine,x=5,y=4,lu_colors=lu_col,label="",unit="mB/t",format="%10.0f",value=0,commas=true,width=16,fg_bg=text_fg_bg} + local prod_rate = PowerIndicator{parent=turbine,x=5,y=3,lu_colors=lu_col,label="",format="%10.2f",value=0,rate=true,width=16,fg_bg=text_fg} + local flow_rate = DataIndicator{parent=turbine,x=5,y=4,lu_colors=lu_col,label="",unit="mB/t",format="%10.0f",value=0,commas=true,width=16,fg_bg=text_fg} status.register(ps, "computed_status", status.update) prod_rate.register(ps, "prod_rate", function (val) prod_rate.update(util.joules_to_fe(val)) end) @@ -37,8 +37,8 @@ local function new_view(root, x, y, ps) local steam = VerticalBar{parent=turbine,x=2,y=1,fg_bg=cpair(colors.white,colors.gray),height=4,width=1} local energy = VerticalBar{parent=turbine,x=3,y=1,fg_bg=cpair(colors.green,colors.gray),height=4,width=1} - TextBox{parent=turbine,text="S",x=2,y=5,height=1,width=1,fg_bg=text_fg_bg} - TextBox{parent=turbine,text="E",x=3,y=5,height=1,width=1,fg_bg=text_fg_bg} + TextBox{parent=turbine,text="S",x=2,y=5,height=1,width=1,fg_bg=text_fg} + TextBox{parent=turbine,text="E",x=3,y=5,height=1,width=1,fg_bg=text_fg} steam.register(ps, "steam_fill", steam.update) energy.register(ps, "energy_fill", energy.update) diff --git a/coordinator/ui/components/unit_detail.lua b/coordinator/ui/components/unit_detail.lua index 64fc1e0..d76c9d8 100644 --- a/coordinator/ui/components/unit_detail.lua +++ b/coordinator/ui/components/unit_detail.lua @@ -35,10 +35,6 @@ local cpair = core.cpair local border = core.border local bw_fg_bg = style.bw_fg_bg -local lu_cpair = style.lu_colors -local hzd_fg_bg = style.hzd_fg_bg -local dis_colors = style.dis_colors - local gry_wht = style.gray_white local ind_grn = style.ind_grn @@ -52,6 +48,16 @@ local period = core.flasher.PERIOD ---@param parent graphics_element parent ---@param id integer local function init(parent, id) + local s_hi_box = style.theme.highlight_box + local s_hi_bright = style.theme.highlight_box_bright + local s_field = style.theme.field_box + + local hc_text = style.hc_text + local lu_cpair = style.lu_colors + local hzd_fg_bg = style.hzd_fg_bg + local dis_colors = style.dis_colors + local arrow_fg_bg = cpair(style.theme.label, s_hi_box.bkg) + local db = iocontrol.get_db() local unit = db.units[id] ---@type ioctl_unit local f_ps = db.facility.ps @@ -64,7 +70,7 @@ local function init(parent, id) local b_ps = unit.boiler_ps_tbl local t_ps = unit.turbine_ps_tbl - TextBox{parent=main,text="Reactor Unit #" .. id,alignment=ALIGN.CENTER,height=1,fg_bg=style.header} + TextBox{parent=main,text="Reactor Unit #" .. id,alignment=ALIGN.CENTER,height=1,fg_bg=style.theme.header} ----------------------------- -- main stats and core map -- @@ -75,11 +81,11 @@ local function init(parent, id) core_map.register(u_ps, "size", function (s) core_map.resize(s[1], s[2]) end) TextBox{parent=main,x=12,y=22,text="Heating Rate",height=1,width=12,fg_bg=style.label} - local heating_r = DataIndicator{parent=main,x=12,label="",format="%14.0f",value=0,unit="mB/t",commas=true,lu_colors=lu_cpair,width=19,fg_bg=bw_fg_bg} + local heating_r = DataIndicator{parent=main,x=12,label="",format="%14.0f",value=0,unit="mB/t",commas=true,lu_colors=lu_cpair,width=19,fg_bg=s_field} heating_r.register(u_ps, "heating_rate", heating_r.update) TextBox{parent=main,x=12,y=25,text="Commanded Burn Rate",height=1,width=19,fg_bg=style.label} - local burn_r = DataIndicator{parent=main,x=12,label="",format="%14.2f",value=0,unit="mB/t",lu_colors=lu_cpair,width=19,fg_bg=bw_fg_bg} + local burn_r = DataIndicator{parent=main,x=12,label="",format="%14.2f",value=0,unit="mB/t",lu_colors=lu_cpair,width=19,fg_bg=s_field} burn_r.register(u_ps, "burn_rate", burn_r.update) TextBox{parent=main,text="F",x=2,y=22,width=1,height=1,fg_bg=style.label} @@ -89,7 +95,7 @@ local function init(parent, id) TextBox{parent=main,text="H",x=8,y=22,width=1,height=1,fg_bg=style.label} TextBox{parent=main,text="W",x=10,y=22,width=1,height=1,fg_bg=style.label} - local fuel = VerticalBar{parent=main,x=2,y=23,fg_bg=cpair(colors.black,colors.gray),height=4,width=1} + local fuel = VerticalBar{parent=main,x=2,y=23,fg_bg=cpair(style.theme.fuel_color,colors.gray),height=4,width=1} local ccool = VerticalBar{parent=main,x=4,y=23,fg_bg=cpair(colors.blue,colors.gray),height=4,width=1} local hcool = VerticalBar{parent=main,x=8,y=23,fg_bg=cpair(colors.white,colors.gray),height=4,width=1} local waste = VerticalBar{parent=main,x=10,y=23,fg_bg=cpair(colors.brown,colors.gray),height=4,width=1} @@ -117,19 +123,19 @@ local function init(parent, id) TextBox{parent=main,x=32,y=22,text="Core Temp",height=1,width=9,fg_bg=style.label} local fmt = util.trinary(string.len(db.temp_label) == 2, "%10.2f", "%11.2f") - local core_temp = DataIndicator{parent=main,x=32,label="",format=fmt,value=0,commas=true,unit=db.temp_label,lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} + local core_temp = DataIndicator{parent=main,x=32,label="",format=fmt,value=0,commas=true,unit=db.temp_label,lu_colors=lu_cpair,width=13,fg_bg=s_field} core_temp.register(u_ps, "temp", function (t) core_temp.update(db.temp_convert(t)) end) TextBox{parent=main,x=32,y=25,text="Burn Rate",height=1,width=9,fg_bg=style.label} - local act_burn_r = DataIndicator{parent=main,x=32,label="",format="%8.2f",value=0,unit="mB/t",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} + local act_burn_r = DataIndicator{parent=main,x=32,label="",format="%8.2f",value=0,unit="mB/t",lu_colors=lu_cpair,width=13,fg_bg=s_field} act_burn_r.register(u_ps, "act_burn_rate", act_burn_r.update) TextBox{parent=main,x=32,y=28,text="Damage",height=1,width=6,fg_bg=style.label} - local damage_p = DataIndicator{parent=main,x=32,label="",format="%11.0f",value=0,unit="%",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} + local damage_p = DataIndicator{parent=main,x=32,label="",format="%11.0f",value=0,unit="%",lu_colors=lu_cpair,width=13,fg_bg=s_field} damage_p.register(u_ps, "damage", damage_p.update) TextBox{parent=main,x=32,y=31,text="Radiation",height=1,width=21,fg_bg=style.label} - local radiation = RadIndicator{parent=main,x=32,label="",format="%9.3f",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} + local radiation = RadIndicator{parent=main,x=32,label="",format="%9.3f",lu_colors=lu_cpair,width=13,fg_bg=s_field} radiation.register(u_ps, "radiation", radiation.update) ------------------- @@ -255,14 +261,14 @@ local function init(parent, id) -- boiler annunciator panel(s) - if available_space > 0 then _add_space() end - if unit.num_boilers > 0 then - TextBox{parent=rcs_tags,x=1,text="B1",width=2,height=1,fg_bg=bw_fg_bg} + if available_space > 0 then _add_space() end + + TextBox{parent=rcs_tags,x=1,text="B1",width=2,height=1,fg_bg=hc_text} local b1_wll = IndicatorLight{parent=rcs_annunc,label="Water Level Low",colors=ind_red} b1_wll.register(b_ps[1], "WaterLevelLow", b1_wll.update) - TextBox{parent=rcs_tags,text="B1",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="B1",width=2,height=1,fg_bg=hc_text} local b1_hr = IndicatorLight{parent=rcs_annunc,label="Heating Rate Low",colors=ind_yel} b1_hr.register(b_ps[1], "HeatingRateLow", b1_hr.update) end @@ -274,11 +280,11 @@ local function init(parent, id) _add_space() end - TextBox{parent=rcs_tags,text="B2",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="B2",width=2,height=1,fg_bg=hc_text} local b2_wll = IndicatorLight{parent=rcs_annunc,label="Water Level Low",colors=ind_red} b2_wll.register(b_ps[2], "WaterLevelLow", b2_wll.update) - TextBox{parent=rcs_tags,text="B2",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="B2",width=2,height=1,fg_bg=hc_text} local b2_hr = IndicatorLight{parent=rcs_annunc,label="Heating Rate Low",colors=ind_yel} b2_hr.register(b_ps[2], "HeatingRateLow", b2_hr.update) end @@ -287,19 +293,19 @@ local function init(parent, id) if available_space > 1 then _add_space() end - TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=hc_text} local t1_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=colors.gray,c2=colors.yellow,c3=colors.red} t1_sdo.register(t_ps[1], "SteamDumpOpen", t1_sdo.update) - TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=hc_text} local t1_tos = IndicatorLight{parent=rcs_annunc,label="Turbine Over Speed",colors=ind_red} t1_tos.register(t_ps[1], "TurbineOverSpeed", t1_tos.update) - TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=hc_text} local t1_gtrp = IndicatorLight{parent=rcs_annunc,label="Generator Trip",colors=ind_yel,flash=true,period=period.BLINK_250_MS} t1_gtrp.register(t_ps[1], "GeneratorTrip", t1_gtrp.update) - TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=hc_text} local t1_trp = IndicatorLight{parent=rcs_annunc,label="Turbine Trip",colors=ind_red,flash=true,period=period.BLINK_250_MS} t1_trp.register(t_ps[1], "TurbineTrip", t1_trp.update) @@ -308,19 +314,19 @@ local function init(parent, id) _add_space() end - TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=hc_text} local t2_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=colors.gray,c2=colors.yellow,c3=colors.red} t2_sdo.register(t_ps[2], "SteamDumpOpen", t2_sdo.update) - TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=hc_text} local t2_tos = IndicatorLight{parent=rcs_annunc,label="Turbine Over Speed",colors=ind_red} t2_tos.register(t_ps[2], "TurbineOverSpeed", t2_tos.update) - TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=hc_text} local t2_gtrp = IndicatorLight{parent=rcs_annunc,label="Generator Trip",colors=ind_yel,flash=true,period=period.BLINK_250_MS} t2_gtrp.register(t_ps[2], "GeneratorTrip", t2_gtrp.update) - TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=hc_text} local t2_trp = IndicatorLight{parent=rcs_annunc,label="Turbine Trip",colors=ind_red,flash=true,period=period.BLINK_250_MS} t2_trp.register(t_ps[2], "TurbineTrip", t2_trp.update) end @@ -328,19 +334,19 @@ local function init(parent, id) if unit.num_turbines > 2 then if available_space > 3 then _add_space() end - TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=hc_text} local t3_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=colors.gray,c2=colors.yellow,c3=colors.red} t3_sdo.register(t_ps[3], "SteamDumpOpen", t3_sdo.update) - TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=hc_text} local t3_tos = IndicatorLight{parent=rcs_annunc,label="Turbine Over Speed",colors=ind_red} t3_tos.register(t_ps[3], "TurbineOverSpeed", t3_tos.update) - TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=hc_text} local t3_gtrp = IndicatorLight{parent=rcs_annunc,label="Generator Trip",colors=ind_yel,flash=true,period=period.BLINK_250_MS} t3_gtrp.register(t_ps[3], "GeneratorTrip", t3_gtrp.update) - TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} + TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=hc_text} local t3_trp = IndicatorLight{parent=rcs_annunc,label="Turbine Trip",colors=ind_red,flash=true,period=period.BLINK_250_MS} t3_trp.register(t_ps[3], "TurbineTrip", t3_trp.update) end @@ -349,9 +355,9 @@ local function init(parent, id) -- reactor controls -- ---------------------- - local burn_control = Div{parent=main,x=12,y=28,width=19,height=3,fg_bg=gry_wht} - local burn_rate = SpinboxNumeric{parent=burn_control,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=gry_wht,fg_bg=bw_fg_bg} - TextBox{parent=burn_control,x=9,y=2,text="mB/t"} + local burn_control = Div{parent=main,x=12,y=28,width=19,height=3,fg_bg=s_hi_box} + local burn_rate = SpinboxNumeric{parent=burn_control,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} + TextBox{parent=burn_control,x=9,y=2,text="mB/t",fg_bg=style.theme.label_fg} local set_burn = function () unit.set_burn(burn_rate.get_value()) end local set_burn_btn = PushButton{parent=burn_control,x=14,y=2,text="SET",min_width=5,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=style.wh_gray,dis_fg_bg=dis_colors,callback=set_burn} @@ -397,7 +403,7 @@ local function init(parent, id) -- alarm management -- ---------------------- - local alarm_panel = Div{parent=main,x=2,y=36,width=29,height=16,fg_bg=bw_fg_bg} + local alarm_panel = Div{parent=main,x=2,y=36,width=29,height=16,fg_bg=s_hi_bright} local a_brc = AlarmLight{parent=alarm_panel,x=6,y=2,label="Containment Breach",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} local a_rad = AlarmLight{parent=alarm_panel,x=6,label="Containment Radiation",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} @@ -465,9 +471,9 @@ local function init(parent, id) -- color tags - TextBox{parent=alarm_panel,x=5,y=13,text="\x95",width=1,height=1,fg_bg=cpair(colors.white,colors.cyan)} - TextBox{parent=alarm_panel,x=5,text="\x95",width=1,height=1,fg_bg=cpair(colors.white,colors.blue)} - TextBox{parent=alarm_panel,x=5,text="\x95",width=1,height=1,fg_bg=cpair(colors.white,colors.blue)} + TextBox{parent=alarm_panel,x=5,y=13,text="\x95",width=1,height=1,fg_bg=cpair(s_hi_bright.bkg,colors.cyan)} + TextBox{parent=alarm_panel,x=5,text="\x95",width=1,height=1,fg_bg=cpair(s_hi_bright.bkg,colors.blue)} + TextBox{parent=alarm_panel,x=5,text="\x95",width=1,height=1,fg_bg=cpair(s_hi_bright.bkg,colors.blue)} -------------------------------- -- automatic control settings -- @@ -479,7 +485,7 @@ local function init(parent, id) local ctl_opts = { "Manual", "Primary", "Secondary", "Tertiary", "Backup" } - local group = RadioButton{parent=auto_div,options=ctl_opts,callback=function()end,radio_colors=cpair(colors.gray,colors.white),select_color=colors.purple} + local group = RadioButton{parent=auto_div,options=ctl_opts,callback=function()end,radio_colors=cpair(style.theme.accent_dark,style.theme.accent_light),select_color=colors.purple} group.register(u_ps, "auto_group_id", function (gid) group.set_value(gid + 1) end) @@ -491,7 +497,7 @@ local function init(parent, id) auto_div.line_break() TextBox{parent=auto_div,text="Prio. Group",height=1,width=11,fg_bg=style.label} - local auto_grp = TextBox{parent=auto_div,text="Manual",height=1,width=11,fg_bg=bw_fg_bg} + local auto_grp = TextBox{parent=auto_div,text="Manual",height=1,width=11,fg_bg=s_field} auto_grp.register(u_ps, "auto_group", auto_grp.set_value) diff --git a/coordinator/ui/components/unit_flow.lua b/coordinator/ui/components/unit_flow.lua index 0cb64c2..115450b 100644 --- a/coordinator/ui/components/unit_flow.lua +++ b/coordinator/ui/components/unit_flow.lua @@ -24,12 +24,10 @@ local ALIGN = core.ALIGN local sprintf = util.sprintf local border = core.border +local cpair = core.cpair local pipe = core.pipe local wh_gray = style.wh_gray -local bw_fg_bg = style.bw_fg_bg -local text_c = style.text_colors -local lu_c = style.lu_colors local lg_gray = style.lg_gray local ind_grn = style.ind_grn @@ -42,6 +40,12 @@ local ind_wht = style.ind_wht ---@param wide boolean whether to render wide version ---@param unit ioctl_unit unit database entry local function make(parent, x, y, wide, unit) + local s_field = style.theme.field_box + + local text_c = style.text_colors + local lu_c = style.lu_colors + local lu_c_d = style.lu_colors_dark + local height = 16 local v_start = 1 + ((unit.unit_id - 1) * 5) @@ -99,11 +103,11 @@ local function make(parent, x, y, wide, unit) table.insert(rc_pipes, pipe(_wide(92, 78), py, _wide(104, 83), py, colors.white, true)) end - PipeNetwork{parent=root,x=20,y=1,pipes=rc_pipes,bg=colors.lightGray} + PipeNetwork{parent=root,x=20,y=1,pipes=rc_pipes,bg=style.theme.bg} if unit.num_boilers > 0 then - local cc_rate = DataIndicator{parent=root,x=_wide(25,22),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=bw_fg_bg} - local hc_rate = DataIndicator{parent=root,x=_wide(25,22),y=5,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=bw_fg_bg} + local cc_rate = DataIndicator{parent=root,x=_wide(25,22),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=s_field} + local hc_rate = DataIndicator{parent=root,x=_wide(25,22),y=5,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=s_field} cc_rate.register(unit.unit_ps, "boiler_boil_sum", function (sum) cc_rate.update(sum * 10) end) hc_rate.register(unit.unit_ps, "heating_rate", hc_rate.update) @@ -114,14 +118,14 @@ local function make(parent, x, y, wide, unit) TextBox{parent=root,x=_wide(47,40),y=2,text="\x1b \x80 \x1a",width=1,height=3,fg_bg=lg_gray} TextBox{parent=root,x=_wide(65,58),y=2,text="\x1b \x80 \x1a",width=1,height=3,fg_bg=lg_gray} - local wt_rate = DataIndicator{parent=root,x=_wide(71,61),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=bw_fg_bg} - local st_rate = DataIndicator{parent=root,x=_wide(71,61),y=5,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=bw_fg_bg} + local wt_rate = DataIndicator{parent=root,x=_wide(71,61),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=s_field} + local st_rate = DataIndicator{parent=root,x=_wide(71,61),y=5,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=s_field} wt_rate.register(unit.unit_ps, "turbine_flow_sum", wt_rate.update) st_rate.register(unit.unit_ps, "boiler_boil_sum", st_rate.update) else - local wt_rate = DataIndicator{parent=root,x=28,y=3,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=bw_fg_bg} - local st_rate = DataIndicator{parent=root,x=28,y=5,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=bw_fg_bg} + local wt_rate = DataIndicator{parent=root,x=28,y=3,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=s_field} + local st_rate = DataIndicator{parent=root,x=28,y=5,lu_colors=lu_c,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=s_field} wt_rate.register(unit.unit_ps, "turbine_flow_sum", wt_rate.update) st_rate.register(unit.unit_ps, "heating_rate", st_rate.update) @@ -145,6 +149,8 @@ local function make(parent, x, y, wide, unit) local waste = Div{parent=root,x=3,y=6} + local waste_c = style.theme.fuel_color + local waste_pipes = { pipe(0, 0, _wide(19, 16), 1, colors.brown, true), pipe(_wide(14, 13), 1, _wide(19, 17), 5, colors.brown, true), @@ -158,12 +164,12 @@ local function make(parent, x, y, wide, unit) pipe(_wide(74, 63), 4, _wide(95, 81), 4, colors.cyan, true), pipe(_wide(74, 63), 8, _wide(133, 111), 8, colors.cyan, true), - pipe(_wide(108, 94), 1, _wide(132, 110), 6, colors.black, true, true), - pipe(_wide(108, 94), 4, _wide(111, 95), 1, colors.black, true, true), - pipe(_wide(132, 110), 6, _wide(130, 108), 6, colors.black, true, true) + pipe(_wide(108, 94), 1, _wide(132, 110), 6, waste_c, true, true), + pipe(_wide(108, 94), 4, _wide(111, 95), 1, waste_c, true, true), + pipe(_wide(132, 110), 6, _wide(130, 108), 6, waste_c, true, true) } - PipeNetwork{parent=waste,x=1,y=1,pipes=waste_pipes,bg=colors.lightGray} + PipeNetwork{parent=waste,x=1,y=1,pipes=waste_pipes,bg=style.theme.bg} local function _valve(vx, vy, n) TextBox{parent=waste,x=vx,y=vy,text="\x10\x11",fg_bg=text_c,width=2,height=1} @@ -175,16 +181,16 @@ local function make(parent, x, y, wide, unit) local function _machine(mx, my, name) local l = string.len(name) + 2 - TextBox{parent=waste,x=mx,y=my,text=string.rep("\x8f",l),alignment=ALIGN.CENTER,fg_bg=lg_gray,width=l,height=1} - TextBox{parent=waste,x=mx,y=my+1,text=name,alignment=ALIGN.CENTER,fg_bg=wh_gray,width=l,height=1} + TextBox{parent=waste,x=mx,y=my,text=string.rep("\x8f",l),alignment=ALIGN.CENTER,fg_bg=cpair(style.theme.bg,style.theme.header.bkg),width=l,height=1} + TextBox{parent=waste,x=mx,y=my+1,text=name,alignment=ALIGN.CENTER,fg_bg=style.theme.header,width=l,height=1} end - local waste_rate = DataIndicator{parent=waste,x=1,y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=bw_fg_bg} - local pu_rate = DataIndicator{parent=waste,x=_wide(82,70),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=bw_fg_bg} - local po_rate = DataIndicator{parent=waste,x=_wide(52,45),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=bw_fg_bg} - local popl_rate = DataIndicator{parent=waste,x=_wide(82,70),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=bw_fg_bg} - local poam_rate = DataIndicator{parent=waste,x=_wide(82,70),y=10,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=bw_fg_bg} - local spent_rate = DataIndicator{parent=waste,x=_wide(117,98),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%8.3f",value=0,width=13,fg_bg=bw_fg_bg} + local waste_rate = DataIndicator{parent=waste,x=1,y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field} + local pu_rate = DataIndicator{parent=waste,x=_wide(82,70),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=s_field} + local po_rate = DataIndicator{parent=waste,x=_wide(52,45),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field} + local popl_rate = DataIndicator{parent=waste,x=_wide(82,70),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field} + local poam_rate = DataIndicator{parent=waste,x=_wide(82,70),y=10,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field} + local spent_rate = DataIndicator{parent=waste,x=_wide(117,98),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%8.3f",value=0,width=13,fg_bg=s_field} waste_rate.register(unit.unit_ps, "act_burn_rate", waste_rate.update) pu_rate.register(unit.unit_ps, "pu_rate", pu_rate.update) @@ -204,12 +210,12 @@ local function make(parent, x, y, wide, unit) _machine(_wide(116, 94), 6, "SPENT WASTE \x1b") TextBox{parent=waste,x=_wide(30,25),y=3,text="SNAs [Po]",alignment=ALIGN.CENTER,width=19,height=1,fg_bg=wh_gray} - local sna_po = Rectangle{parent=waste,x=_wide(30,25),y=4,border=border(1,colors.gray,true),width=19,height=7,thin=true,fg_bg=bw_fg_bg} + local sna_po = Rectangle{parent=waste,x=_wide(30,25),y=4,border=border(1,colors.gray,true),width=19,height=7,thin=true,fg_bg=style.theme.highlight_box_bright} local sna_act = IndicatorLight{parent=sna_po,label="ACTIVE",colors=ind_grn} - local sna_cnt = DataIndicator{parent=sna_po,x=12,y=1,lu_colors=lu_c,label="CNT",unit="",format="%2d",value=0,width=7} - local sna_pk = DataIndicator{parent=sna_po,y=3,lu_colors=lu_c,label="PEAK",unit="mB/t",format="%7.2f",value=0,width=17} - local sna_max = DataIndicator{parent=sna_po,lu_colors=lu_c,label="MAX",unit="mB/t",format="%8.2f",value=0,width=17} - local sna_in = DataIndicator{parent=sna_po,lu_colors=lu_c,label="IN",unit="mB/t",format="%9.2f",value=0,width=17} + local sna_cnt = DataIndicator{parent=sna_po,x=12,y=1,lu_colors=lu_c_d,label="CNT",unit="",format="%2d",value=0,width=7} + local sna_pk = DataIndicator{parent=sna_po,y=3,lu_colors=lu_c_d,label="PEAK",unit="mB/t",format="%7.2f",value=0,width=17} + local sna_max = DataIndicator{parent=sna_po,lu_colors=lu_c_d,label="MAX",unit="mB/t",format="%8.2f",value=0,width=17} + local sna_in = DataIndicator{parent=sna_po,lu_colors=lu_c_d,label="IN",unit="mB/t",format="%9.2f",value=0,width=17} sna_act.register(unit.unit_ps, "po_rate", function (r) sna_act.update(r > 0) end) sna_cnt.register(unit.unit_ps, "sna_count", sna_cnt.update) diff --git a/coordinator/ui/components/unit_overview.lua b/coordinator/ui/components/unit_overview.lua index 17702e5..80e99e9 100644 --- a/coordinator/ui/components/unit_overview.lua +++ b/coordinator/ui/components/unit_overview.lua @@ -44,7 +44,7 @@ local function make(parent, x, y, unit) local root = Div{parent=parent,x=x,y=y,width=80,height=height} -- unit header message - TextBox{parent=root,text="Unit #"..unit.unit_id,alignment=ALIGN.CENTER,height=1,fg_bg=style.header} + TextBox{parent=root,text="Unit #"..unit.unit_id,alignment=ALIGN.CENTER,height=1,fg_bg=style.theme.header} ------------- -- REACTOR -- @@ -66,7 +66,7 @@ local function make(parent, x, y, unit) table.insert(coolant_pipes, pipe(2, 0, 11, 11, colors.orange)) end - PipeNetwork{parent=root,x=4,y=10,pipes=coolant_pipes,bg=colors.lightGray} + PipeNetwork{parent=root,x=4,y=10,pipes=coolant_pipes,bg=style.theme.bg} end ------------- @@ -164,10 +164,10 @@ local function make(parent, x, y, unit) table.insert(steam_pipes_b, pipe(0, 18, 2, 18, colors.blue, false, true)) -- water boiler 2 to turbine 2 junction end - PipeNetwork{parent=root,x=47,y=11,pipes=steam_pipes_a,bg=colors.lightGray} + PipeNetwork{parent=root,x=47,y=11,pipes=steam_pipes_a,bg=style.theme.bg} end - PipeNetwork{parent=root,x=54,y=3,pipes=steam_pipes_b,bg=colors.lightGray} + PipeNetwork{parent=root,x=54,y=3,pipes=steam_pipes_b,bg=style.theme.bg} return root end diff --git a/coordinator/ui/layout/flow_view.lua b/coordinator/ui/layout/flow_view.lua index 1040a8c..98d16e9 100644 --- a/coordinator/ui/layout/flow_view.lua +++ b/coordinator/ui/layout/flow_view.lua @@ -32,13 +32,16 @@ local border = core.border local pipe = core.pipe local wh_gray = style.wh_gray -local bw_fg_bg = style.bw_fg_bg -local text_col = style.text_colors -local lu_col = style.lu_colors -- create new flow view ---@param main graphics_element main displaybox local function init(main) + local s_hi_bright = style.theme.highlight_box_bright + local s_field = style.theme.field_box + local text_col = style.text_colors + local lu_col = style.lu_colors + local lu_c_d = style.lu_colors_dark + local facility = iocontrol.get_db().facility local units = iocontrol.get_db().units @@ -46,9 +49,9 @@ local function init(main) local tank_list = facility.tank_list -- window header message - local header = TextBox{parent=main,y=1,text="Facility Coolant and Waste Flow Monitor",alignment=ALIGN.CENTER,height=1,fg_bg=style.header} + local header = TextBox{parent=main,y=1,text="Facility Coolant and Waste Flow Monitor",alignment=ALIGN.CENTER,height=1,fg_bg=style.theme.header} -- max length example: "01:23:45 AM - Wednesday, September 28 2022" - local datetime = TextBox{parent=main,x=(header.get_width()-42),y=1,text="",alignment=ALIGN.RIGHT,width=42,height=1,fg_bg=style.header} + local datetime = TextBox{parent=main,x=(header.get_width()-42),y=1,text="",alignment=ALIGN.RIGHT,width=42,height=1,fg_bg=style.theme.header} datetime.register(facility.ps, "date_time", datetime.set_value) @@ -240,7 +243,7 @@ local function init(main) local flow_x = 3 if #water_pipes > 0 then flow_x = 25 - PipeNetwork{parent=main,x=2,y=3,pipes=water_pipes,bg=colors.lightGray} + PipeNetwork{parent=main,x=2,y=3,pipes=water_pipes,bg=style.theme.bg} end for i = 1, facility.num_units do @@ -249,7 +252,7 @@ local function init(main) table.insert(po_pipes, pipe(0, 3 + y_offset, 4, 0, colors.cyan, true, true)) end - PipeNetwork{parent=main,x=139,y=15,pipes=po_pipes,bg=colors.lightGray} + PipeNetwork{parent=main,x=139,y=15,pipes=po_pipes,bg=style.theme.bg} ----------------- -- tank valves -- @@ -297,7 +300,7 @@ local function init(main) TextBox{parent=tank_box,x=2,y=3,text="Fill",height=1,width=10,fg_bg=style.label} local tank_pcnt = DataIndicator{parent=tank_box,x=10,y=3,label="",format="%5.2f",value=100,unit="%",lu_colors=lu_col,width=8,fg_bg=text_col} - local tank_amnt = DataIndicator{parent=tank_box,x=2,label="",format="%13d",value=0,commas=true,unit="mB",lu_colors=lu_col,width=16,fg_bg=bw_fg_bg} + local tank_amnt = DataIndicator{parent=tank_box,x=2,label="",format="%13d",value=0,commas=true,unit="mB",lu_colors=lu_col,width=16,fg_bg=s_field} TextBox{parent=tank_box,x=2,y=6,text="Water Level",height=1,width=11,fg_bg=style.label} local level = HorizontalBar{parent=tank_box,x=2,y=7,bar_fg_bg=cpair(colors.blue,colors.gray),height=1,width=16} @@ -348,12 +351,12 @@ local function init(main) status.register(facility.sps_ps_tbl[1], "computed_status", status.update) TextBox{parent=sps_box,x=2,y=3,text="Input Rate",height=1,width=10,fg_bg=style.label} - local sps_in = DataIndicator{parent=sps_box,x=2,label="",format="%15.2f",value=0,unit="mB/t",lu_colors=lu_col,width=20,fg_bg=bw_fg_bg} + local sps_in = DataIndicator{parent=sps_box,x=2,label="",format="%15.2f",value=0,unit="mB/t",lu_colors=lu_col,width=20,fg_bg=s_field} sps_in.register(facility.ps, "po_am_rate", sps_in.update) TextBox{parent=sps_box,x=2,y=6,text="Production Rate",height=1,width=15,fg_bg=style.label} - local sps_rate = DataIndicator{parent=sps_box,x=2,label="",format="%15d",value=0,unit="\xb5B/t",lu_colors=lu_col,width=20,fg_bg=bw_fg_bg} + local sps_rate = DataIndicator{parent=sps_box,x=2,label="",format="%15d",value=0,unit="\xb5B/t",lu_colors=lu_col,width=20,fg_bg=s_field} sps_rate.register(facility.sps_ps_tbl[1], "process_rate", function (r) sps_rate.update(r * 1000) end) @@ -362,24 +365,24 @@ local function init(main) ---------------- TextBox{parent=main,x=145,y=16,text="RAW WASTE",alignment=ALIGN.CENTER,width=19,height=1,fg_bg=wh_gray} - local raw_waste = Rectangle{parent=main,x=145,y=17,border=border(1,colors.gray,true),width=19,height=3,thin=true,fg_bg=bw_fg_bg} - local sum_raw_waste = DataIndicator{parent=raw_waste,lu_colors=lu_col,label="SUM",unit="mB/t",format="%8.2f",value=0,width=17} + local raw_waste = Rectangle{parent=main,x=145,y=17,border=border(1,colors.gray,true),width=19,height=3,thin=true,fg_bg=s_hi_bright} + local sum_raw_waste = DataIndicator{parent=raw_waste,lu_colors=lu_c_d,label="SUM",unit="mB/t",format="%8.2f",value=0,width=17} sum_raw_waste.register(facility.ps, "burn_sum", sum_raw_waste.update) TextBox{parent=main,x=145,y=21,text="PROC. WASTE",alignment=ALIGN.CENTER,width=19,height=1,fg_bg=wh_gray} - local pr_waste = Rectangle{parent=main,x=145,y=22,border=border(1,colors.gray,true),width=19,height=5,thin=true,fg_bg=bw_fg_bg} - local pu = DataIndicator{parent=pr_waste,lu_colors=lu_col,label="Pu",unit="mB/t",format="%9.3f",value=0,width=17} - local po = DataIndicator{parent=pr_waste,lu_colors=lu_col,label="Po",unit="mB/t",format="%9.2f",value=0,width=17} - local popl = DataIndicator{parent=pr_waste,lu_colors=lu_col,label="PoPl",unit="mB/t",format="%7.2f",value=0,width=17} + local pr_waste = Rectangle{parent=main,x=145,y=22,border=border(1,colors.gray,true),width=19,height=5,thin=true,fg_bg=s_hi_bright} + local pu = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="Pu",unit="mB/t",format="%9.3f",value=0,width=17} + local po = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="Po",unit="mB/t",format="%9.2f",value=0,width=17} + local popl = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="PoPl",unit="mB/t",format="%7.2f",value=0,width=17} pu.register(facility.ps, "pu_rate", pu.update) po.register(facility.ps, "po_rate", po.update) popl.register(facility.ps, "po_pl_rate", popl.update) TextBox{parent=main,x=145,y=28,text="SPENT WASTE",alignment=ALIGN.CENTER,width=19,height=1,fg_bg=wh_gray} - local sp_waste = Rectangle{parent=main,x=145,y=29,border=border(1,colors.gray,true),width=19,height=3,thin=true,fg_bg=bw_fg_bg} - local sum_sp_waste = DataIndicator{parent=sp_waste,lu_colors=lu_col,label="SUM",unit="mB/t",format="%8.3f",value=0,width=17} + local sp_waste = Rectangle{parent=main,x=145,y=29,border=border(1,colors.gray,true),width=19,height=3,thin=true,fg_bg=s_hi_bright} + local sum_sp_waste = DataIndicator{parent=sp_waste,lu_colors=lu_c_d,label="SUM",unit="mB/t",format="%8.3f",value=0,width=17} sum_sp_waste.register(facility.ps, "spent_waste_rate", sum_sp_waste.update) end diff --git a/coordinator/ui/layout/front_panel.lua b/coordinator/ui/layout/front_panel.lua index ffd2a09..d2eb8ff 100644 --- a/coordinator/ui/layout/front_panel.lua +++ b/coordinator/ui/layout/front_panel.lua @@ -36,7 +36,7 @@ local led_grn = style.led_grn local function init(panel, num_units) local ps = iocontrol.get_db().fp.ps - TextBox{parent=panel,y=1,text="SCADA COORDINATOR",alignment=ALIGN.CENTER,height=1,fg_bg=style.fp.header} + TextBox{parent=panel,y=1,text="SCADA COORDINATOR",alignment=ALIGN.CENTER,height=1,fg_bg=style.fp_theme.header} local page_div = Div{parent=panel,x=1,y=3} @@ -68,7 +68,7 @@ local function init(panel, num_units) ---@diagnostic disable-next-line: undefined-field local comp_id = util.sprintf("(%d)", os.getComputerID()) - TextBox{parent=system,x=9,y=4,width=6,height=1,text=comp_id,fg_bg=style.fp_label} + TextBox{parent=system,x=9,y=4,width=6,height=1,text=comp_id,fg_bg=style.fp.disabled_fg} local monitors = Div{parent=main_page,width=16,height=17,x=18,y=2} @@ -89,7 +89,7 @@ local function init(panel, num_units) -- about footer -- - local about = Div{parent=main_page,width=15,height=3,x=1,y=16,fg_bg=style.fp_label} + local about = Div{parent=main_page,width=15,height=3,x=1,y=16,fg_bg=style.fp.disabled_fg} local fw_v = TextBox{parent=about,x=1,y=1,text="FW: v00.00.00",alignment=ALIGN.LEFT,height=1} local comms_v = TextBox{parent=about,x=1,y=2,text="NT: v00.00.00",alignment=ALIGN.LEFT,height=1} @@ -103,7 +103,7 @@ local function init(panel, num_units) -- API page local api_page = Div{parent=page_div,x=1,y=1,hidden=true} - local api_list = ListBox{parent=api_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=style.fp_text,nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} + local api_list = ListBox{parent=api_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=style.fp.text_fg,nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} local _ = Div{parent=api_list,height=1,hidden=true} -- padding -- assemble page panes @@ -113,11 +113,11 @@ local function init(panel, num_units) local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} local tabs = { - { name = "CRD", color = style.fp_text }, - { name = "API", color = style.fp_text }, + { name = "CRD", color = style.fp.text }, + { name = "API", color = style.fp.text }, } - TabBar{parent=panel,y=2,tabs=tabs,min_width=9,callback=page_pane.set_value,fg_bg=style.bw_fg_bg} + TabBar{parent=panel,y=2,tabs=tabs,min_width=9,callback=page_pane.set_value,fg_bg=style.fp_theme.highlight_box_bright} -- link pocket API list management to PGI pgi.link_elements(api_list, pkt_entry) diff --git a/coordinator/ui/layout/main_view.lua b/coordinator/ui/layout/main_view.lua index 64742c7..f31c200 100644 --- a/coordinator/ui/layout/main_view.lua +++ b/coordinator/ui/layout/main_view.lua @@ -21,14 +21,16 @@ local ALIGN = core.ALIGN -- create new main view ---@param main graphics_element main displaybox local function init(main) + local s_header = style.theme.header + local facility = iocontrol.get_db().facility local units = iocontrol.get_db().units -- window header message - local header = TextBox{parent=main,y=1,text="Nuclear Generation Facility SCADA Coordinator",alignment=ALIGN.CENTER,height=1,fg_bg=style.header} - local ping = DataIndicator{parent=main,x=1,y=1,label="SVTT",format="%d",value=0,unit="ms",lu_colors=style.lg_white,width=12,fg_bg=style.header} + local header = TextBox{parent=main,y=1,text="Nuclear Generation Facility SCADA Coordinator",alignment=ALIGN.CENTER,height=1,fg_bg=s_header} + local ping = DataIndicator{parent=main,x=1,y=1,label="SVTT",format="%d",value=0,unit="ms",lu_colors=style.lg_white,width=12,fg_bg=s_header} -- max length example: "01:23:45 AM - Wednesday, September 28 2022" - local datetime = TextBox{parent=main,x=(header.get_width()-42),y=1,text="",alignment=ALIGN.RIGHT,width=42,height=1,fg_bg=style.header} + local datetime = TextBox{parent=main,x=(header.get_width()-42),y=1,text="",alignment=ALIGN.RIGHT,width=42,height=1,fg_bg=s_header} ping.register(facility.ps, "sv_ping", ping.update) datetime.register(facility.ps, "date_time", datetime.set_value) @@ -66,8 +68,6 @@ local function init(main) -- command & control - cnc_y_start = cnc_y_start - -- induction matrix and process control interfaces are 24 tall + space needed for divider local cnc_bottom_align_start = main.get_height() - 26 diff --git a/coordinator/ui/style.lua b/coordinator/ui/style.lua index d9549a5..afa6b7b 100644 --- a/coordinator/ui/style.lua +++ b/coordinator/ui/style.lua @@ -2,79 +2,156 @@ -- Graphics Style Options -- -local core = require("graphics.core") +local core = require("graphics.core") +local themes = require("graphics.themes") +---@class crd_style local style = {} local cpair = core.cpair --- GLOBAL -- - --- add color mappings for front panel -colors.ivory = colors.pink -colors.yellow_hc = colors.purple -colors.red_off = colors.brown -colors.yellow_off = colors.magenta -colors.green_off = colors.lime - -- front panel styling -style.fp = {} +style.fp_theme = themes.sandstone +style.fp = themes.get_fp_style(style.fp_theme) -style.fp.root = cpair(colors.black, colors.ivory) -style.fp.header = cpair(colors.black, colors.lightGray) - -style.fp.colors = { - { c = colors.red, hex = 0xdf4949 }, -- RED ON - { c = colors.orange, hex = 0xffb659 }, - { c = colors.yellow, hex = 0xf9fb53 }, -- YELLOW ON - { c = colors.lime, hex = 0x16665a }, -- GREEN OFF - { c = colors.green, hex = 0x6be551 }, -- GREEN ON - { c = colors.cyan, hex = 0x34bac8 }, - { c = colors.lightBlue, hex = 0x6cc0f2 }, - { c = colors.blue, hex = 0x0096ff }, - { c = colors.purple, hex = 0xb156ee }, -- YELLOW HIGH CONTRAST - { c = colors.pink, hex = 0xdcd9ca }, -- IVORY - { c = colors.magenta, hex = 0x85862c }, -- YELLOW OFF - -- { c = colors.white, hex = 0xdcd9ca }, - { c = colors.lightGray, hex = 0xb1b8b3 }, - { c = colors.gray, hex = 0x575757 }, - -- { c = colors.black, hex = 0x191919 }, - { c = colors.brown, hex = 0x672223 } -- RED OFF -} +style.led_grn = cpair(colors.green, colors.green_off) -- main GUI styling -style.root = cpair(colors.black, colors.lightGray) -style.header = cpair(colors.white, colors.gray) -style.label = cpair(colors.gray, colors.lightGray) +---@class theme +local smooth_stone = { + text = colors.black, + text_inv = colors.white, + label = colors.gray, + label_dark = colors.gray, + disabled = colors.lightGray, + bg = colors.lightGray, + accent_light = colors.white, + accent_dark = colors.gray, -style.colors = { - { c = colors.red, hex = 0xdf4949 }, - { c = colors.orange, hex = 0xffb659 }, - { c = colors.yellow, hex = 0xfffc79 }, - { c = colors.lime, hex = 0x80ff80 }, - { c = colors.green, hex = 0x4aee8a }, - { c = colors.cyan, hex = 0x34bac8 }, - { c = colors.lightBlue, hex = 0x6cc0f2 }, - { c = colors.blue, hex = 0x0096ff }, - { c = colors.purple, hex = 0xb156ee }, - { c = colors.pink, hex = 0xf26ba2 }, - { c = colors.magenta, hex = 0xf9488a }, - -- { c = colors.white, hex = 0xf0f0f0 }, - { c = colors.lightGray, hex = 0xcacaca }, - { c = colors.gray, hex = 0x575757 }, - -- { c = colors.black, hex = 0x191919 }, - -- { c = colors.brown, hex = 0x7f664c } + fuel_color = colors.black, + + header = cpair(colors.white, colors.gray), + + text_fg = cpair(colors.black, colors._INHERIT), + label_fg = cpair(colors.gray, colors._INHERIT), + disabled_fg = cpair(colors.lightGray, colors._INHERIT), + + highlight_box = cpair(colors.black, colors.white), + highlight_box_bright = cpair(colors.black, colors.white), + field_box = cpair(colors.black, colors.white), + + colors = { + { c = colors.red, hex = 0xdf4949 }, + { c = colors.orange, hex = 0xffb659 }, + { c = colors.yellow, hex = 0xfffc79 }, + { c = colors.lime, hex = 0x80ff80 }, + { c = colors.green, hex = 0x4aee8a }, + { c = colors.cyan, hex = 0x34bac8 }, + { c = colors.lightBlue, hex = 0x6cc0f2 }, + { c = colors.blue, hex = 0x0096ff }, + { c = colors.purple, hex = 0xb156ee }, + { c = colors.pink, hex = 0xf26ba2 }, + { c = colors.magenta, hex = 0xf9488a }, + { c = colors.white, hex = 0xf0f0f0 }, + { c = colors.lightGray, hex = 0xcacaca }, + { c = colors.gray, hex = 0x575757 }, + { c = colors.black, hex = 0x191919 }, + { c = colors.brown, hex = 0x7f664c } + } } +---@type theme +local deepslate = { + text = colors.white, + text_inv = colors.black, + label = colors.lightGray, + label_dark = colors.gray, + disabled = colors.gray, + bg = colors.black, + accent_light = colors.gray, + accent_dark = colors.lightGray, + + fuel_color = colors.lightGray, + + header = cpair(colors.white, colors.gray), + + text_fg = cpair(colors.white, colors._INHERIT), + label_fg = cpair(colors.lightGray, colors._INHERIT), + disabled_fg = cpair(colors.gray, colors._INHERIT), + + highlight_box = cpair(colors.white, colors.gray), + highlight_box_bright = cpair(colors.black, colors.lightGray), + field_box = cpair(colors.white, colors.gray), + + colors = { + { c = colors.red, hex = 0xeb6a6c }, + { c = colors.orange, hex = 0xf2b86c }, + { c = colors.yellow, hex = 0xd9cf81 }, + { c = colors.lime, hex = 0x80ff80 }, + { c = colors.green, hex = 0x70e19b }, + { c = colors.cyan, hex = 0x7ccdd0 }, + { c = colors.lightBlue, hex = 0x99ceef }, + { c = colors.blue, hex = 0x60bcff }, + { c = colors.purple, hex = 0xc38aea }, + { c = colors.pink, hex = 0xff7fb8 }, + { c = colors.magenta, hex = 0xf980dd }, + { c = colors.white, hex = 0xd9d9d9 }, + { c = colors.lightGray, hex = 0x949494 }, + { c = colors.gray, hex = 0x575757 }, + { c = colors.black, hex = 0x262626 }, + { c = colors.brown, hex = 0xb18f6a } + } +} + +style.theme = smooth_stone + +style.root = cpair(style.theme.text, style.theme.bg) +style.label = cpair(style.theme.label, style.theme.bg) + +-- high contrast text (also tags) +style.hc_text = cpair(style.theme.text, style.theme.text_inv) +-- text on default background +style.text_colors = cpair(style.theme.text, style.theme.bg) +-- label & unit colors +style.lu_colors = cpair(style.theme.label, style.theme.label) +-- label & unit colors (darker if set) +style.lu_colors_dark = cpair(style.theme.label_dark, style.theme.label_dark) + +-- set themes per configurations +---@param main integer main theme ID (1 = smooth_stone, 2 = deepslate) +---@param fp integer fp theme ID (1 = sandstone, 2 = basalt) +function style.set_themes(main, fp) + if main == 1 then + style.theme = smooth_stone + elseif main == 2 then + style.theme = deepslate + end + + style.root = cpair(style.theme.text, style.theme.bg) + style.label = cpair(style.theme.label, style.theme.bg) + + style.hc_text = cpair(style.theme.text, style.theme.text_inv) + style.text_colors = cpair(style.theme.text, style.theme.bg) + style.lu_colors = cpair(style.theme.label, style.theme.label) + style.lu_colors_dark = cpair(style.theme.label_dark, style.theme.label_dark) + + if fp == 1 then + style.fp_theme = themes.sandstone + elseif fp == 2 then + style.fp_theme = themes.basalt + end + + style.fp = themes.get_fp_style(style.fp_theme) +end + -- COMMON COLOR PAIRS -- style.wh_gray = cpair(colors.white, colors.gray) style.bw_fg_bg = cpair(colors.black, colors.white) -style.text_colors = cpair(colors.black, colors.lightGray) -style.lu_colors = cpair(colors.gray, colors.gray) + style.hzd_fg_bg = style.wh_gray style.dis_colors = cpair(colors.white, colors.lightGray) @@ -87,10 +164,6 @@ style.ind_yel = cpair(colors.yellow, colors.gray) style.ind_red = cpair(colors.red, colors.gray) style.ind_wht = style.wh_gray -style.fp_text = cpair(colors.black, colors.ivory) -style.fp_label = cpair(colors.lightGray, colors.ivory) -style.led_grn = cpair(colors.green, colors.green_off) - -- UI COMPONENTS -- style.reactor = { diff --git a/graphics/core.lua b/graphics/core.lua index 3e53b83..e2587fc 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -7,7 +7,7 @@ local flasher = require("graphics.flasher") local core = {} -core.version = "2.1.1" +core.version = "2.2.1" core.flasher = flasher core.events = events @@ -61,6 +61,9 @@ end ---@field blit_fgd string ---@field blit_bkg string +-- add inherited flag, 3 isn't a pure color so it wouldn't be used +colors._INHERIT = 3 + -- create a new color pair definition ---@nodiscard ---@param a color diff --git a/graphics/element.lua b/graphics/element.lua index 939efd6..5b6d70d 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -234,11 +234,24 @@ function element.new(args, child_offset_x, child_offset_y) -- init colors if args.fg_bg ~= nil then - protected.fg_bg = args.fg_bg - elseif args.parent ~= nil then - protected.fg_bg = args.parent.get_fg_bg() + protected.fg_bg = core.cpair(args.fg_bg.fgd, args.fg_bg.bkg) end + if args.parent ~= nil then + local p_fg_bg = args.parent.get_fg_bg() + + if args.fg_bg == nil then + protected.fg_bg = core.cpair(p_fg_bg.fgd, p_fg_bg.bkg) + else + if protected.fg_bg.fgd == colors._INHERIT then protected.fg_bg = core.cpair(p_fg_bg.fgd, protected.fg_bg.bkg) end + if protected.fg_bg.bkg == colors._INHERIT then protected.fg_bg = core.cpair(protected.fg_bg.fgd, p_fg_bg.bkg) end + end + end + + -- check colors + element.assert(protected.fg_bg.fgd ~= colors._INHERIT, "could not determine foreground color to inherit") + element.assert(protected.fg_bg.bkg ~= colors._INHERIT, "could not determine background color to inherit") + -- set colors protected.window.setBackgroundColor(protected.fg_bg.bkg) protected.window.setTextColor(protected.fg_bg.fgd) diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index 9a0e621..7c2306f 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -138,23 +138,21 @@ local function hazard_button(args) -- handle mouse interaction ---@param event mouse_interaction mouse event function e.handle_mouse(event) - if e.enabled then - if core.events.was_clicked(event.type) then - -- change text color to indicate clicked - e.w_set_fgd(args.accent) - e.w_set_cur(3, 2) - e.w_write(args.text) + if e.enabled and core.events.was_clicked(event.type) and e.in_frame_bounds(event.current.x, event.current.y) then + -- change text color to indicate clicked + e.w_set_fgd(args.accent) + e.w_set_cur(3, 2) + e.w_write(args.text) - -- abort any other callbacks - tcd.abort(on_timeout) - tcd.abort(on_success) - tcd.abort(on_failure) + -- abort any other callbacks + tcd.abort(on_timeout) + tcd.abort(on_success) + tcd.abort(on_failure) - -- 1.5 second timeout - tcd.dispatch(1.5, on_timeout) + -- 1.5 second timeout + tcd.dispatch(1.5, on_timeout) - args.callback() - end + args.callback() end end diff --git a/graphics/elements/controls/radio_button.lua b/graphics/elements/controls/radio_button.lua index aee7060..be9b1ee 100644 --- a/graphics/elements/controls/radio_button.lua +++ b/graphics/elements/controls/radio_button.lua @@ -90,7 +90,8 @@ local function radio_button(args) -- handle mouse interaction ---@param event mouse_interaction 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 + if e.enabled and core.events.was_clicked(event.type) and + (event.initial.y == event.current.y) and e.in_frame_bounds(event.current.x, event.current.y) then -- determine what was pressed if args.options[event.current.y] ~= nil then e.value = event.current.y diff --git a/graphics/elements/controls/spinbox_numeric.lua b/graphics/elements/controls/spinbox_numeric.lua index 90edf18..e114c6a 100644 --- a/graphics/elements/controls/spinbox_numeric.lua +++ b/graphics/elements/controls/spinbox_numeric.lua @@ -127,20 +127,19 @@ local function spinbox(args) ---@param event mouse_interaction mouse event function e.handle_mouse(event) -- only handle if on an increment or decrement arrow - if e.enabled and core.events.was_clicked(event.type) and - (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 event.current.y == 1 then - digits[idx] = digits[idx] + 1 - elseif event.current.y == 3 then - digits[idx] = digits[idx] - 1 - end - - update_value() - show_num() + if e.enabled and core.events.was_clicked(event.type) and e.in_frame_bounds(event.current.x, event.current.y) and + (event.current.x ~= dec_point_x) and (event.current.y ~= 2) and + (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 event.current.y == 1 then + digits[idx] = digits[idx] + 1 + elseif event.current.y == 3 then + digits[idx] = digits[idx] - 1 end + + update_value() + show_num() end end end diff --git a/graphics/elements/controls/switch_button.lua b/graphics/elements/controls/switch_button.lua index f649b10..ac44ca6 100644 --- a/graphics/elements/controls/switch_button.lua +++ b/graphics/elements/controls/switch_button.lua @@ -58,7 +58,7 @@ local function switch_button(args) -- handle mouse interaction ---@param event mouse_interaction 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) and e.in_frame_bounds(event.current.x, event.current.y) then e.value = not e.value e.redraw() args.callback(e.value) diff --git a/graphics/elements/controls/tabbar.lua b/graphics/elements/controls/tabbar.lua index 9b604e1..c76781b 100644 --- a/graphics/elements/controls/tabbar.lua +++ b/graphics/elements/controls/tabbar.lua @@ -98,7 +98,7 @@ local function tabbar(args) ---@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 + if e.enabled and core.events.was_clicked(event.type) and e.in_frame_bounds(event.current.x, event.current.y) 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) diff --git a/graphics/elements/form/number_field.lua b/graphics/elements/form/number_field.lua index 66731ad..ef383ce 100644 --- a/graphics/elements/form/number_field.lua +++ b/graphics/elements/form/number_field.lua @@ -53,11 +53,11 @@ local function number_field(args) ---@param event mouse_interaction mouse event function e.handle_mouse(event) -- only handle if on an increment or decrement arrow - if e.enabled then + if e.enabled and e.in_frame_bounds(event.current.x, event.current.y) then if core.events.was_clicked(event.type) then e.take_focus() - if event.type == MOUSE_CLICK.UP and e.in_frame_bounds(event.current.x, event.current.y) then + if event.type == MOUSE_CLICK.UP then ifield.move_cursor(event.current.x) end elseif event.type == MOUSE_CLICK.DOUBLE_CLICK then diff --git a/graphics/elements/form/text_field.lua b/graphics/elements/form/text_field.lua index 843ec24..f912b9e 100644 --- a/graphics/elements/form/text_field.lua +++ b/graphics/elements/form/text_field.lua @@ -41,11 +41,11 @@ local function text_field(args) ---@param event mouse_interaction mouse event function e.handle_mouse(event) -- only handle if on an increment or decrement arrow - if e.enabled then + if e.enabled and e.in_frame_bounds(event.current.x, event.current.y) then if core.events.was_clicked(event.type) then e.take_focus() - if event.type == MOUSE_CLICK.UP and e.in_frame_bounds(event.current.x, event.current.y) then + if event.type == MOUSE_CLICK.UP then ifield.move_cursor(event.current.x) end elseif event.type == MOUSE_CLICK.DOUBLE_CLICK then diff --git a/graphics/themes.lua b/graphics/themes.lua new file mode 100644 index 0000000..c454aab --- /dev/null +++ b/graphics/themes.lua @@ -0,0 +1,172 @@ +-- +-- Graphics Themes +-- + +local core = require("graphics.core") + +local cpair = core.cpair + +---@class graphics_themes +local themes = {} + +-- add color mappings for front panels +colors.ivory = colors.pink +colors.yellow_hc = colors.purple +colors.red_off = colors.brown +colors.yellow_off = colors.magenta +colors.green_off = colors.lime + +--#region Types + +---@enum UI_THEME +themes.UI_THEME = { SMOOTH_STONE = 1, DEEPSLATE = 2 } +themes.UI_THEME_NAMES = { "Smooth Stone", "Deepslate" } + +-- attempts to get the string name of a main ui theme +---@nodiscard +---@param id any +---@return string|nil +function themes.ui_theme_name(id) + if id == themes.UI_THEME.SMOOTH_STONE or + id == themes.UI_THEME.DEEPSLATE then + return themes.UI_THEME_NAMES[id] + else return nil end +end + +---@enum FP_THEME +themes.FP_THEME = { SANDSTONE = 1, BASALT = 2 } +themes.FP_THEME_NAMES = { "Sandstone", "Basalt" } + +-- attempts to get the string name of a front panel theme +---@nodiscard +---@param id any +---@return string|nil +function themes.fp_theme_name(id) + if id == themes.FP_THEME.SANDSTONE or + id == themes.FP_THEME.BASALT then + return themes.FP_THEME_NAMES[id] + else return nil end +end + +---@enum COLOR_MODE +themes.COLOR_MODE = { + STANDARD = 1, + DEUTERANOPIA = 2, + PROTANOPIA = 3, + TRITANOPIA = 4 +} + +themes.COLOR_MODE_NAMES = { + "Standard", + "Deuteranopia", + "Protanopia", + "Tritanopia" +} + +-- attempts to get the string name of a color mode +---@nodiscard +---@param id any +---@return string|nil +function themes.color_mode_name(id) + if id == themes.COLOR_MODE.STANDARD or + id == themes.COLOR_MODE.DEUTERANOPIA or + id == themes.COLOR_MODE.PROTANOPIA or + id == themes.COLOR_MODE.TRITANOPIA then + return themes.COLOR_MODE_NAMES[id] + else return nil end +end + +--#endregion + +--#region Front Panel Themes + +---@class fp_theme +themes.sandstone = { + text = colors.black, + label = colors.lightGray, + label_dark = colors.gray, + disabled = colors.lightGray, + bg = colors.ivory, + + header = cpair(colors.black, colors.lightGray), + + highlight_box = cpair(colors.black, colors.lightGray), + highlight_box_bright = cpair(colors.black, colors.white), + field_box = cpair(colors.gray, colors.white), + + colors = { + { c = colors.red, hex = 0xdf4949 }, + { c = colors.orange, hex = 0xffb659 }, + { c = colors.yellow, hex = 0xf9fb53 }, + { c = colors.green_off, hex = 0x16665a }, + { c = colors.green, hex = 0x6be551 }, + { c = colors.cyan, hex = 0x34bac8 }, + { c = colors.lightBlue, hex = 0x6cc0f2 }, + { c = colors.blue, hex = 0x0096ff }, + { c = colors.yellow_hc, hex = 0xe3bc2a }, + { c = colors.ivory, hex = 0xdcd9ca }, + { c = colors.yellow_off, hex = 0x85862c }, + { c = colors.white, hex = 0xf0f0f0 }, + { c = colors.lightGray, hex = 0xb1b8b3 }, + { c = colors.gray, hex = 0x575757 }, + { c = colors.black, hex = 0x191919 }, + { c = colors.red_off, hex = 0x672223 } + } +} + +---@type fp_theme +themes.basalt = { + text = colors.white, + label = colors.gray, + label_dark = colors.ivory, + disabled = colors.lightGray, + bg = colors.ivory, + + header = cpair(colors.white, colors.gray), + + highlight_box = cpair(colors.white, colors.gray), + highlight_box_bright = cpair(colors.black, colors.lightGray), + field_box = cpair(colors.white, colors.gray), + + colors = { + { c = colors.red, hex = 0xf18486 }, + { c = colors.orange, hex = 0xffb659 }, + { c = colors.yellow, hex = 0xefe37c }, + { c = colors.green_off, hex = 0x436b41 }, + { c = colors.green, hex = 0x7ae175 }, + { c = colors.cyan, hex = 0x5ec7d1 }, + { c = colors.lightBlue, hex = 0x7dc6f2 }, + { c = colors.blue, hex = 0x56aae6 }, + { c = colors.yellow_hc, hex = 0xe9cd68 }, + { c = colors.ivory, hex = 0x4d4e52 }, + { c = colors.yellow_off, hex = 0x757040 }, + { c = colors.white, hex = 0xbfbfbf }, + { c = colors.lightGray, hex = 0x848794 }, + { c = colors.gray, hex = 0x5c5f68 }, + { c = colors.black, hex = 0x262626 }, + { c = colors.red_off, hex = 0x653839 } + } +} + +-- get style fields for a front panel based on the provided theme +---@param theme fp_theme +function themes.get_fp_style(theme) + ---@class fp_style + local style = { + root = cpair(theme.text, theme.bg), + + text = cpair(theme.text, theme.bg), + text_fg = cpair(theme.text, colors._INHERIT), + + label_fg = cpair(theme.label, colors._INHERIT), + label_d_fg = cpair(theme.label_dark, colors._INHERIT), + + disabled_fg = cpair(theme.disabled, colors._INHERIT) + } + + return style +end + +--#endregion + +return themes diff --git a/pocket/configure.lua b/pocket/configure.lua index 6c0f728..908ea4c 100644 --- a/pocket/configure.lua +++ b/pocket/configure.lua @@ -112,7 +112,7 @@ local fields = { { "AuthKey", "Facility Auth Key" , ""}, { "LogMode", "Log Mode", log.MODE.APPEND }, { "LogPath", "Log Path", "/log.txt" }, - { "LogDebug","Log Debug Messages", false } + { "LogDebug", "Log Debug Messages", false } } -- load data from the settings file diff --git a/reactor-plc/configure.lua b/reactor-plc/configure.lua index db9162d..5676a91 100644 --- a/reactor-plc/configure.lua +++ b/reactor-plc/configure.lua @@ -23,6 +23,8 @@ local RadioButton = require("graphics.elements.controls.radio_button") local NumberField = require("graphics.elements.form.number_field") local TextField = require("graphics.elements.form.text_field") +local IndLight = require("graphics.elements.indicators.light") + local println = util.println local tri = util.trinary @@ -34,8 +36,9 @@ local RIGHT = core.ALIGN.RIGHT -- changes to the config data/format to let the user know local changes = { - {"v1.6.2", { "AuthKey minimum length is now 8 (if set)" } }, - {"v1.6.8", { "ConnTimeout can now have a fractional part" } } + { "v1.6.2", { "AuthKey minimum length is now 8 (if set)" } }, + { "v1.6.8", { "ConnTimeout can now have a fractional part" } }, + { "v1.6.15", { "Added front panel UI theme", "Added color accessibility modes" } } } ---@class plc_configurator @@ -67,13 +70,18 @@ local g_lg_fg_bg = cpair(colors.gray, colors.lightGray) local nav_fg_bg = bw_fg_bg local btn_act_fg_bg = cpair(colors.white, colors.gray) +---@class _plc_cfg_tool_ctl local tool_ctl = { ask_config = false, has_config = false, viewing_config = false, importing_legacy = false, + jumped_to_color = false, view_cfg = nil, ---@type graphics_element + color_cfg = nil, ---@type graphics_element + color_next = nil, ---@type graphics_element + color_apply = nil, ---@type graphics_element settings_apply = nil, ---@type graphics_element set_networked = nil, ---@type function @@ -103,6 +111,8 @@ local tmp_cfg = { LogMode = 0, LogPath = "", LogDebug = false, + FrontPanelTheme = 1, + ColorMode = 1 } ---@class plc_config @@ -124,7 +134,9 @@ local fields = { { "AuthKey", "Facility Auth Key" , ""}, { "LogMode", "Log Mode", log.MODE.APPEND }, { "LogPath", "Log Path", "/log.txt" }, - { "LogDebug","Log Debug Messages", false } + { "LogDebug", "Log Debug Messages", false }, + { "FrontPanelTheme", "Front Panel Theme", 1 }, + { "ColorMode", "Color Mode", 1 } } local side_options = { "Top", "Bottom", "Left", "Right", "Front", "Back" } @@ -176,10 +188,11 @@ local function config_view(display) local plc_cfg = Div{parent=root_pane_div,x=1,y=1} local net_cfg = Div{parent=root_pane_div,x=1,y=1} local log_cfg = Div{parent=root_pane_div,x=1,y=1} + local clr_cfg = Div{parent=root_pane_div,x=1,y=1} local summary = Div{parent=root_pane_div,x=1,y=1} local changelog = Div{parent=root_pane_div,x=1,y=1} - local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,plc_cfg,net_cfg,log_cfg,summary,changelog}} + local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,plc_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog}} -- Main Page @@ -196,7 +209,7 @@ local function config_view(display) tool_ctl.viewing_config = true tool_ctl.gen_summary(settings_cfg) tool_ctl.settings_apply.hide(true) - main_pane.set_value(5) + main_pane.set_value(6) end if fs.exists("/reactor-plc/config.lua") then @@ -207,10 +220,21 @@ local function config_view(display) PushButton{parent=main_page,x=2,y=y_start,min_width=18,text="Configure System",callback=function()main_pane.set_value(2)end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg} tool_ctl.view_cfg = PushButton{parent=main_page,x=2,y=y_start+2,min_width=20,text="View Configuration",callback=view_config,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)} - if not tool_ctl.has_config then tool_ctl.view_cfg.disable() end + local function jump_color() + tool_ctl.jumped_to_color = true + tool_ctl.color_next.hide(true) + tool_ctl.color_apply.show() + main_pane.set_value(5) + end PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg} - PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(6)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + if not tool_ctl.has_config then + tool_ctl.view_cfg.disable() + tool_ctl.color_cfg.disable() + end --#region PLC @@ -419,10 +443,8 @@ local function config_view(display) tmp_cfg.LogMode = mode.get_value() - 1 tmp_cfg.LogPath = path.get_value() tmp_cfg.LogDebug = en_dbg.get_value() - tool_ctl.gen_summary(tmp_cfg) - tool_ctl.viewing_config = false - tool_ctl.importing_legacy = false - tool_ctl.settings_apply.show() + tool_ctl.color_apply.hide(true) + tool_ctl.color_next.show() main_pane.set_value(5) else path_err.show() end end @@ -436,6 +458,110 @@ local function config_view(display) --#endregion + --#region Color Options + + local clr_c_1 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_2 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49} + + local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}} + + TextBox{parent=clr_cfg,x=1,y=2,height=1,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)} + + TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color theme for the front panel."} + TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg} + + TextBox{parent=clr_c_1,x=1,y=7,height=1,text="Front Panel Theme"} + local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options={"Sandstone","Basalt"},callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."} + + local function recolor(value) + if value == 1 then + for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end + elseif value == 2 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf5e633) + term.setPaletteColor(colors.red, 0xff521a) + elseif value == 3 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf7c311) + term.setPaletteColor(colors.red, 0xfb5615) + elseif value == 4 then + term.setPaletteColor(colors.green, 0x00ecff) + term.setPaletteColor(colors.yellow, 0xffbc00) + term.setPaletteColor(colors.red, 0xff0000) + end + end + + local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options={"None","Protanopia","Deuteranopia","Tritanopia"},callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + local _ = IndLight{parent=clr_c_2,x=20,y=8,label="Good",colors=cpair(colors.black,colors.green),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=9,label="Warning",colors=cpair(colors.black,colors.yellow),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=10,label="Bad",colors=cpair(colors.black,colors.red),value=true} + + TextBox{parent=clr_c_2,x=20,y=12,height=6,text="Exact color varies by theme.",fg_bg=g_lg_fg_bg} + + PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + local function back_from_colors() + main_pane.set_value(util.trinary(tool_ctl.jumped_to_color, 1, 4)) + tool_ctl.jumped_to_color = false + recolor(1) + end + + local function show_access() + clr_pane.set_value(2) + recolor(c_mode.get_value()) + end + + local function submit_colors() + tmp_cfg.FrontPanelTheme = fp_theme.get_value() + tmp_cfg.ColorMode = c_mode.get_value() + + if tool_ctl.jumped_to_color then + settings.set("FrontPanelTheme", tmp_cfg.FrontPanelTheme) + settings.set("ColorMode", tmp_cfg.ColorMode) + + if settings.save("/reactor-plc.settings") then + load_settings(settings_cfg, true) + load_settings(ini_cfg) + clr_pane.set_value(3) + else + clr_pane.set_value(4) + end + else + tool_ctl.gen_summary(tmp_cfg) + tool_ctl.viewing_config = false + tool_ctl.importing_legacy = false + tool_ctl.settings_apply.show() + main_pane.set_value(6) + end + end + + PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg} + + tool_ctl.color_apply.hide(true) + + local function c_go_home() + main_pane.set_value(1) + clr_pane.set_value(1) + end + + TextBox{parent=clr_c_3,x=1,y=1,height=1,text="Settings saved!"} + PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."} + PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + --#endregion + --#region Summary and Saving local sum_c_1 = Div{parent=summary,x=2,y=4,width=49} @@ -456,7 +582,7 @@ local function config_view(display) tool_ctl.importing_legacy = false tool_ctl.settings_apply.show() else - main_pane.set_value(4) + main_pane.set_value(5) end end @@ -487,6 +613,8 @@ local function config_view(display) try_set(mode, ini_cfg.LogMode) try_set(path, ini_cfg.LogPath) try_set(en_dbg, ini_cfg.LogDebug) + try_set(fp_theme, ini_cfg.FrontPanelTheme) + try_set(c_mode, ini_cfg.ColorMode) tool_ctl.view_cfg.enable() @@ -511,6 +639,7 @@ local function config_view(display) main_pane.set_value(1) plc_pane.set_value(1) net_pane.set_value(1) + clr_pane.set_value(1) sum_pane.set_value(1) end @@ -588,7 +717,7 @@ local function config_view(display) tool_ctl.gen_summary(tmp_cfg) sum_pane.set_value(1) - main_pane.set_value(5) + main_pane.set_value(6) tool_ctl.importing_legacy = true end @@ -617,9 +746,15 @@ local function config_view(display) local raw = cfg[f[1]] local val = util.strval(raw) - if f[1] == "AuthKey" then val = string.rep("*", string.len(val)) end - if f[1] == "LogMode" then val = util.trinary(raw == log.MODE.APPEND, "append", "replace") end - if f[1] == "EmerCoolColor" and raw ~= nil then val = rsio.color_name(raw) end + if f[1] == "AuthKey" then val = string.rep("*", string.len(val)) + elseif f[1] == "LogMode" then val = util.trinary(raw == log.MODE.APPEND, "append", "replace") + elseif f[1] == "EmerCoolColor" and raw ~= nil then val = rsio.color_name(raw) + elseif f[1] == "FrontPanelTheme" then + if raw == 1 then val = "Sandstone" elseif raw == 2 then val = "Basalt" end + elseif f[1] == "ColorMode" then + if raw == 1 then val = "Standard" elseif raw == 2 then val = "Protanopia" elseif raw == 3 then val = "Deuteranopia" elseif raw == 4 then val = "Tritanopia" end + end + if val == "nil" then val = "" end local c = util.trinary(alternate, g_lg_fg_bg, cpair(colors.gray,colors.white)) diff --git a/reactor-plc/panel/front_panel.lua b/reactor-plc/panel/front_panel.lua index 41737e8..7c087a8 100644 --- a/reactor-plc/panel/front_panel.lua +++ b/reactor-plc/panel/front_panel.lua @@ -34,8 +34,12 @@ local ind_red = style.ind_red -- create new front panel view ---@param panel graphics_element main displaybox local function init(panel) - local header = TextBox{parent=panel,y=1,text="REACTOR PLC - UNIT ?",alignment=ALIGN.CENTER,height=1,fg_bg=style.header} - header.register(databus.ps, "unit_id", function (id) header.set_value(util.c("REACTOR PLC - UNIT ", id)) end) + local s_hi_box = style.theme.highlight_box + + local disabled_fg = style.fp.disabled_fg + + local header = TextBox{parent=panel,y=1,text="FISSION REACTOR PLC - UNIT ?",alignment=ALIGN.CENTER,height=1,fg_bg=style.theme.header} + header.register(databus.ps, "unit_id", function (id) header.set_value(util.c("FISSION REACTOR PLC - UNIT ", id)) end) -- -- system indicators @@ -75,7 +79,7 @@ local function init(panel) ---@diagnostic disable-next-line: undefined-field local comp_id = util.sprintf("(%d)", os.getComputerID()) - TextBox{parent=system,x=9,y=5,width=6,height=1,text=comp_id,fg_bg=cpair(colors.lightGray,colors.ivory)} + TextBox{parent=system,x=9,y=5,width=6,height=1,text=comp_id,fg_bg=disabled_fg} -- -- status & controls @@ -91,12 +95,12 @@ local function init(panel) emer_cool.register(databus.ps, "emer_cool", emer_cool.update) end - local status_trip_rct = Rectangle{parent=status,width=20,height=3,x=1,border=border(1,colors.lightGray,true),even_inner=true,fg_bg=cpair(colors.black,colors.ivory)} - local status_trip = Div{parent=status_trip_rct,width=18,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + local status_trip_rct = Rectangle{parent=status,width=20,height=3,x=1,border=border(1,s_hi_box.bkg,true),even_inner=true} + local status_trip = Div{parent=status_trip_rct,width=18,height=1,fg_bg=s_hi_box} local scram = LED{parent=status_trip,width=10,label="RPS TRIP",colors=ind_red,flash=true,period=flasher.PERIOD.BLINK_250_MS} - local controls_rct = Rectangle{parent=status,width=17,height=3,x=1,border=border(1,colors.white,true),even_inner=true,fg_bg=cpair(colors.black,colors.ivory)} - local controls = Div{parent=controls_rct,width=15,height=1,fg_bg=cpair(colors.black,colors.white)} + local controls_rct = Rectangle{parent=status,width=17,height=3,x=1,border=border(1,s_hi_box.bkg,true),even_inner=true} + local controls = Div{parent=controls_rct,width=15,height=1,fg_bg=s_hi_box} PushButton{parent=controls,x=1,y=1,min_width=7,text="SCRAM",callback=databus.rps_scram,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.black,colors.red_off)} PushButton{parent=controls,x=9,y=1,min_width=7,text="RESET",callback=databus.rps_reset,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=cpair(colors.black,colors.yellow_off)} @@ -107,9 +111,9 @@ local function init(panel) -- about footer -- - local about = Rectangle{parent=panel,width=32,height=3,x=2,y=16,border=border(1,colors.ivory),thin=true,fg_bg=cpair(colors.black,colors.white)} - local fw_v = TextBox{parent=about,x=2,y=1,text="FW: v00.00.00",alignment=ALIGN.LEFT,height=1} - local comms_v = TextBox{parent=about,x=17,y=1,text="NT: v00.00.00",alignment=ALIGN.LEFT,height=1} + local about = Div{parent=panel,width=15,height=3,x=1,y=18,fg_bg=disabled_fg} + local fw_v = TextBox{parent=about,x=1,y=1,text="FW: v00.00.00",alignment=ALIGN.LEFT,height=1} + local comms_v = TextBox{parent=about,x=1,y=2,text="NT: v00.00.00",alignment=ALIGN.LEFT,height=1} fw_v.register(databus.ps, "version", function (version) fw_v.set_value(util.c("FW: ", version)) end) comms_v.register(databus.ps, "comms_version", function (version) comms_v.set_value(util.c("NT: v", version)) end) @@ -118,7 +122,7 @@ local function init(panel) -- rps list -- - local rps = Rectangle{parent=panel,width=16,height=16,x=36,y=3,border=border(1,colors.lightGray),thin=true,fg_bg=cpair(colors.black,colors.lightGray)} + local rps = Rectangle{parent=panel,width=16,height=16,x=36,y=3,border=border(1,s_hi_box.bkg),thin=true,fg_bg=s_hi_box} local rps_man = LED{parent=rps,label="MANUAL",colors=ind_red} local rps_auto = LED{parent=rps,label="AUTOMATIC",colors=ind_red} local rps_tmo = LED{parent=rps,label="TIMEOUT",colors=ind_red} diff --git a/reactor-plc/panel/style.lua b/reactor-plc/panel/style.lua index 1cf783c..5aca524 100644 --- a/reactor-plc/panel/style.lua +++ b/reactor-plc/panel/style.lua @@ -2,46 +2,30 @@ -- Graphics Style Options -- -local core = require("graphics.core") +local core = require("graphics.core") +local themes = require("graphics.themes") +---@class plc_style local style = {} local cpair = core.cpair --- GLOBAL -- - --- remap global colors -colors.ivory = colors.pink -colors.yellow_hc = colors.purple -colors.red_off = colors.brown -colors.yellow_off = colors.magenta -colors.green_off = colors.lime - -style.root = cpair(colors.black, colors.ivory) -style.header = cpair(colors.black, colors.lightGray) - -style.colors = { - { c = colors.red, hex = 0xdf4949 }, -- RED ON - { c = colors.orange, hex = 0xffb659 }, - { c = colors.yellow, hex = 0xf9fb53 }, -- YELLOW ON - { c = colors.lime, hex = 0x16665a }, -- GREEN OFF - { c = colors.green, hex = 0x6be551 }, -- GREEN ON - { c = colors.cyan, hex = 0x34bac8 }, - { c = colors.lightBlue, hex = 0x6cc0f2 }, - { c = colors.blue, hex = 0x0096ff }, - { c = colors.purple, hex = 0xb156ee }, -- YELLOW HIGH CONTRAST - { c = colors.pink, hex = 0xdcd9ca }, -- IVORY - { c = colors.magenta, hex = 0x85862c }, -- YELLOW OFF - -- { c = colors.white, hex = 0xdcd9ca }, - { c = colors.lightGray, hex = 0xb1b8b3 }, - { c = colors.gray, hex = 0x575757 }, - -- { c = colors.black, hex = 0x191919 }, - { c = colors.brown, hex = 0x672223 } -- RED OFF -} - --- COMMON COLOR PAIRS -- +style.theme = themes.sandstone +style.fp = themes.get_fp_style(style.theme) style.ind_grn = cpair(colors.green, colors.green_off) style.ind_red = cpair(colors.red, colors.red_off) +-- set theme per configuration +---@param fp integer fp theme ID (1 = sandstone, 2 = basalt) +function style.set_theme(fp) + if fp == 1 then + style.theme = themes.sandstone + elseif fp == 2 then + style.theme = themes.basalt + end + + style.fp = themes.get_fp_style(style.theme) +end + return style diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index eec1e4d..560f3ba 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -52,6 +52,9 @@ function plc.load_config() config.LogPath = settings.get("LogPath") config.LogDebug = settings.get("LogDebug") + config.FrontPanelTheme = settings.get("FrontPanelTheme") + config.ColorMode = settings.get("ColorMode") + local cfv = util.new_validator() cfv.assert_type_bool(config.Networked) @@ -78,6 +81,11 @@ function plc.load_config() cfv.assert_type_str(config.LogPath) cfv.assert_type_bool(config.LogDebug) + cfv.assert_type_int(config.FrontPanelTheme) + cfv.assert_range(config.FrontPanelTheme, 1, 2) + cfv.assert_type_int(config.ColorMode) + cfv.assert_range(config.ColorMode, 1, 4) + -- check emergency coolant configuration if enabled if config.EmerCoolEnable then cfv.assert_eq(rsio.is_valid_side(config.EmerCoolSide), true) diff --git a/reactor-plc/renderer.lua b/reactor-plc/renderer.lua index 2613600..31af361 100644 --- a/reactor-plc/renderer.lua +++ b/reactor-plc/renderer.lua @@ -18,11 +18,15 @@ local ui = { } -- try to start the UI +---@param theme integer front panel theme ID (1 = sandstone, 2 = basalt) ---@return boolean success, any error_msg -function renderer.try_start_ui() +function renderer.try_start_ui(theme) local status, msg = true, nil if ui.display == nil then + -- set theme + style.set_theme(theme) + -- reset terminal term.setTextColor(colors.white) term.setBackgroundColor(colors.black) @@ -30,13 +34,13 @@ function renderer.try_start_ui() term.setCursorPos(1, 1) -- set overridden colors - for i = 1, #style.colors do - term.setPaletteColor(style.colors[i].c, style.colors[i].hex) + for i = 1, #style.theme.colors do + term.setPaletteColor(style.theme.colors[i].c, style.theme.colors[i].hex) end -- init front panel view status, msg = pcall(function () - ui.display = DisplayBox{window=term.current(),fg_bg=style.root} + ui.display = DisplayBox{window=term.current(),fg_bg=style.fp.root} panel_view(ui.display) end) @@ -64,9 +68,9 @@ function renderer.close_ui() ui.display = nil -- restore colors - for i = 1, #style.colors do - local r, g, b = term.nativePaletteColor(style.colors[i].c) - term.setPaletteColor(style.colors[i].c, r, g, b) + for i = 1, #style.theme.colors do + local r, g, b = term.nativePaletteColor(style.theme.colors[i].c) + term.setPaletteColor(style.theme.colors[i].c, r, g, b) end -- reset terminal diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 9c3d382..66f6d77 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.6.14" +local R_PLC_VERSION = "v1.6.15" local println = util.println local println_ts = util.println_ts @@ -183,7 +183,7 @@ local function main() -- front panel time! if not renderer.ui_ready() then local message - plc_state.fp_ok, message = renderer.try_start_ui() + plc_state.fp_ok, message = renderer.try_start_ui(config.FrontPanelTheme) if not plc_state.fp_ok then println_ts(util.c("UI error: ", message)) diff --git a/rtu/configure.lua b/rtu/configure.lua index 131623b..acc419f 100644 --- a/rtu/configure.lua +++ b/rtu/configure.lua @@ -24,6 +24,8 @@ local RadioButton = require("graphics.elements.controls.radio_button") local NumberField = require("graphics.elements.form.number_field") local TextField = require("graphics.elements.form.text_field") +local IndLight = require("graphics.elements.indicators.light") + local println = util.println local tri = util.trinary @@ -73,7 +75,8 @@ assert(#PORT_DSGN == rsio.NUM_PORTS) -- changes to the config data/format to let the user know local changes = { - {"v1.7.9", { "ConnTimeout can now have a fractional part" } } + { "v1.7.9", { "ConnTimeout can now have a fractional part" } }, + { "v1.7.15", { "Added front panel UI theme", "Added color accessibility modes" } } } ---@class rtu_rs_definition @@ -119,13 +122,15 @@ local g_lg_fg_bg = cpair(colors.gray, colors.lightGray) local nav_fg_bg = bw_fg_bg local btn_act_fg_bg = cpair(colors.white, colors.gray) +---@class _rtu_cfg_tool_ctl local tool_ctl = { ask_config = false, has_config = false, viewing_config = false, importing_legacy = false, importing_any_dc = false, - peri_cfg_editing = false, ---@type string|false + jumped_to_color = false, + peri_cfg_editing = false, ---@type integer|false peri_cfg_manual = false, rs_cfg_port = IO.F_SCRAM, ---@type IO_PORT rs_cfg_editing = false, ---@type integer|false @@ -133,6 +138,9 @@ local tool_ctl = { view_gw_cfg = nil, ---@type graphics_element dev_cfg = nil, ---@type graphics_element rs_cfg = nil, ---@type graphics_element + color_cfg = nil, ---@type graphics_element + color_next = nil, ---@type graphics_element + color_apply = nil, ---@type graphics_element settings_apply = nil, ---@type graphics_element settings_confirm = nil, ---@type graphics_element @@ -181,7 +189,9 @@ local tmp_cfg = { AuthKey = nil, ---@type string|nil LogMode = 0, LogPath = "", - LogDebug = false + LogDebug = false, + FrontPanelTheme = 1, + ColorMode = 1 } ---@class rtu_config @@ -198,7 +208,9 @@ local fields = { { "AuthKey", "Facility Auth Key", "" }, { "LogMode", "Log Mode", log.MODE.APPEND }, { "LogPath", "Log Path", "/log.txt" }, - { "LogDebug","Log Debug Messages", false } + { "LogDebug", "Log Debug Messages", false }, + { "FrontPanelTheme", "Front Panel Theme", 1 }, + { "ColorMode", "Color Mode", 1 } } local side_options = { "Top", "Bottom", "Left", "Right", "Front", "Back" } @@ -266,12 +278,13 @@ local function config_view(display) local spkr_cfg = Div{parent=root_pane_div,x=1,y=1} local net_cfg = Div{parent=root_pane_div,x=1,y=1} local log_cfg = Div{parent=root_pane_div,x=1,y=1} + local clr_cfg = Div{parent=root_pane_div,x=1,y=1} local summary = Div{parent=root_pane_div,x=1,y=1} local changelog = Div{parent=root_pane_div,x=1,y=1} local peri_cfg = Div{parent=root_pane_div,x=1,y=1} local rs_cfg = Div{parent=root_pane_div,x=1,y=1} - local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,spkr_cfg,net_cfg,log_cfg,summary,changelog,peri_cfg,rs_cfg}} + local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,spkr_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,peri_cfg,rs_cfg}} --#region Main Page @@ -290,7 +303,7 @@ local function config_view(display) tool_ctl.gen_summary(settings_cfg) tool_ctl.settings_apply.hide(true) tool_ctl.settings_confirm.hide(true) - main_pane.set_value(5) + main_pane.set_value(6) end if fs.exists("/rtu/config.lua") then @@ -300,12 +313,12 @@ local function config_view(display) local function show_peri_conns() tool_ctl.gen_peri_summary(ini_cfg) - main_pane.set_value(7) + main_pane.set_value(8) end local function show_rs_conns() tool_ctl.gen_rs_summary(ini_cfg) - main_pane.set_value(8) + main_pane.set_value(9) end PushButton{parent=main_page,x=2,y=y_start,min_width=19,text="Configure Gateway",callback=function()main_pane.set_value(2)end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg} @@ -313,15 +326,24 @@ local function config_view(display) tool_ctl.dev_cfg = PushButton{parent=main_page,x=2,y=y_start+4,min_width=24,text="Peripheral Connections",callback=show_peri_conns,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)} tool_ctl.rs_cfg = PushButton{parent=main_page,x=2,y=y_start+6,min_width=22,text="Redstone Connections",callback=show_rs_conns,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)} + local function jump_color() + tool_ctl.jumped_to_color = true + tool_ctl.color_next.hide(true) + tool_ctl.color_apply.show() + main_pane.set_value(5) + end + + PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg} + tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + if not tool_ctl.has_config then tool_ctl.view_gw_cfg.disable() tool_ctl.dev_cfg.disable() tool_ctl.rs_cfg.disable() + tool_ctl.color_cfg.disable() end - PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg} - PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(6)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} - --#endregion --#region Speakers @@ -480,11 +502,8 @@ local function config_view(display) tmp_cfg.LogMode = mode.get_value() - 1 tmp_cfg.LogPath = path.get_value() tmp_cfg.LogDebug = en_dbg.get_value() - tool_ctl.gen_summary(tmp_cfg) - tool_ctl.viewing_config = false - tool_ctl.importing_legacy = false - tool_ctl.settings_apply.show() - tool_ctl.settings_confirm.hide(true) + tool_ctl.color_apply.hide(true) + tool_ctl.color_next.show() main_pane.set_value(5) else path_err.show() end end @@ -494,6 +513,106 @@ local function config_view(display) --#endregion + --#region Color Options + + local clr_c_1 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_2 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49} + + local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}} + + TextBox{parent=clr_cfg,x=1,y=2,height=1,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)} + + TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color theme for the front panel."} + TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg} + + TextBox{parent=clr_c_1,x=1,y=7,height=1,text="Front Panel Theme"} + local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options={"Sandstone","Basalt"},callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."} + + local function recolor(value) + if value == 1 then + for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end + elseif value == 2 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf5e633) + term.setPaletteColor(colors.red, 0xff521a) + elseif value == 3 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf7c311) + term.setPaletteColor(colors.red, 0xfb5615) + elseif value == 4 then + term.setPaletteColor(colors.green, 0x00ecff) + term.setPaletteColor(colors.yellow, 0xffbc00) + term.setPaletteColor(colors.red, 0xff0000) + end + end + + local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options={"None","Protanopia","Deuteranopia","Tritanopia"},callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + local _ = IndLight{parent=clr_c_2,x=20,y=8,label="Good",colors=cpair(colors.black,colors.green),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=9,label="Warning",colors=cpair(colors.black,colors.yellow),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=10,label="Bad",colors=cpair(colors.black,colors.red),value=true} + + TextBox{parent=clr_c_2,x=20,y=12,height=6,text="Exact color varies by theme.",fg_bg=g_lg_fg_bg} + + PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + local function back_from_colors() + main_pane.set_value(util.trinary(tool_ctl.jumped_to_color, 1, 4)) + tool_ctl.jumped_to_color = false + recolor(1) + end + + local function show_access() + clr_pane.set_value(2) + recolor(c_mode.get_value()) + end + + local function submit_colors() + tmp_cfg.FrontPanelTheme = fp_theme.get_value() + tmp_cfg.ColorMode = c_mode.get_value() + + if tool_ctl.jumped_to_color then + settings.set("FrontPanelTheme", tmp_cfg.FrontPanelTheme) + settings.set("ColorMode", tmp_cfg.ColorMode) + + if settings.save("/rtu.settings") then + load_settings(settings_cfg, true) + load_settings(ini_cfg) + clr_pane.set_value(3) + else + clr_pane.set_value(4) + end + else + tool_ctl.gen_summary(tmp_cfg) + tool_ctl.viewing_config = false + tool_ctl.importing_legacy = false + tool_ctl.settings_apply.show() + tool_ctl.settings_confirm.hide(true) + main_pane.set_value(6) + end + end + + PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg} + + tool_ctl.color_apply.hide(true) + + TextBox{parent=clr_c_3,x=1,y=1,height=1,text="Settings saved!"} + PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."} + PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + --#endregion + --#region Summary and Saving local sum_c_1 = Div{parent=summary,x=2,y=4,width=49} @@ -520,7 +639,7 @@ local function config_view(display) end tool_ctl.viewing_config = false - else main_pane.set_value(4) end + else main_pane.set_value(5) end end ---@param element graphics_element @@ -552,6 +671,8 @@ local function config_view(display) try_set(mode, ini_cfg.LogMode) try_set(path, ini_cfg.LogPath) try_set(en_dbg, ini_cfg.LogDebug) + try_set(fp_theme, ini_cfg.FrontPanelTheme) + try_set(c_mode, ini_cfg.ColorMode) if not exclude_conns then tmp_cfg.Peripherals = deep_copy_peri(ini_cfg.Peripherals) @@ -1257,7 +1378,7 @@ local function config_view(display) tool_ctl.gen_summary(tmp_cfg) if tool_ctl.importing_any_dc then sum_pane.set_value(7) else sum_pane.set_value(1) end - main_pane.set_value(5) + main_pane.set_value(6) tool_ctl.settings_apply.hide(true) tool_ctl.settings_confirm.show() tool_ctl.importing_legacy = true @@ -1271,6 +1392,7 @@ local function config_view(display) main_pane.set_value(1) net_pane.set_value(1) + clr_pane.set_value(1) sum_pane.set_value(1) peri_pane.set_value(1) rs_pane.set_value(1) @@ -1301,8 +1423,14 @@ local function config_view(display) local raw = cfg[f[1]] local val = util.strval(raw) - if f[1] == "AuthKey" then val = string.rep("*", string.len(val)) end - if f[1] == "LogMode" then val = util.trinary(raw == log.MODE.APPEND, "append", "replace") end + if f[1] == "AuthKey" then val = string.rep("*", string.len(val)) + elseif f[1] == "LogMode" then val = util.trinary(raw == log.MODE.APPEND, "append", "replace") + elseif f[1] == "FrontPanelTheme" then + if raw == 1 then val = "Sandstone" elseif raw == 2 then val = "Basalt" end + elseif f[1] == "ColorMode" then + if raw == 1 then val = "Standard" elseif raw == 2 then val = "Protanopia" elseif raw == 3 then val = "Deuteranopia" elseif raw == 4 then val = "Tritanopia" end + end + if val == "nil" then val = "" end local c = util.trinary(alternate, g_lg_fg_bg, cpair(colors.gray,colors.white)) diff --git a/rtu/panel/front_panel.lua b/rtu/panel/front_panel.lua index 206ea21..9989e9a 100644 --- a/rtu/panel/front_panel.lua +++ b/rtu/panel/front_panel.lua @@ -22,8 +22,6 @@ local ALIGN = core.ALIGN local cpair = core.cpair -local fp_label = style.fp_label - local ind_grn = style.ind_grn local UNIT_TYPE_LABELS = { "UNKNOWN", "REDSTONE", "BOILER", "TURBINE", "DYNAMIC TANK", "IND MATRIX", "SPS", "SNA", "ENV DETECTOR" } @@ -32,7 +30,9 @@ local UNIT_TYPE_LABELS = { "UNKNOWN", "REDSTONE", "BOILER", "TURBINE", "DYNAMIC ---@param panel graphics_element main displaybox ---@param units table unit list local function init(panel, units) - TextBox{parent=panel,y=1,text="RTU GATEWAY",alignment=ALIGN.CENTER,height=1,fg_bg=style.header} + local disabled_fg = style.fp.disabled_fg + + TextBox{parent=panel,y=1,text="RTU GATEWAY",alignment=ALIGN.CENTER,height=1,fg_bg=style.theme.header} -- -- system indicators @@ -64,17 +64,17 @@ local function init(panel, units) ---@diagnostic disable-next-line: undefined-field local comp_id = util.sprintf("(%d)", os.getComputerID()) - TextBox{parent=system,x=9,y=4,width=6,height=1,text=comp_id,fg_bg=fp_label} + TextBox{parent=system,x=9,y=4,width=6,height=1,text=comp_id,fg_bg=disabled_fg} - TextBox{parent=system,x=1,y=14,text="SPEAKERS",height=1,width=8,fg_bg=style.label} - local speaker_count = DataIndicator{parent=system,x=10,y=14,label="",format="%3d",value=0,width=3,fg_bg=cpair(colors.gray,colors.white)} + TextBox{parent=system,x=1,y=14,text="SPEAKERS",height=1,width=8,fg_bg=style.fp.text_fg} + local speaker_count = DataIndicator{parent=system,x=10,y=14,label="",format="%3d",value=0,width=3,fg_bg=style.theme.field_box} speaker_count.register(databus.ps, "speaker_count", speaker_count.update) -- -- about label -- - local about = Div{parent=panel,width=15,height=3,x=1,y=18,fg_bg=fp_label} + local about = Div{parent=panel,width=15,height=3,x=1,y=18,fg_bg=disabled_fg} local fw_v = TextBox{parent=about,x=1,y=1,text="FW: v00.00.00",alignment=ALIGN.LEFT,height=1} local comms_v = TextBox{parent=about,x=1,y=2,text="NT: v00.00.00",alignment=ALIGN.LEFT,height=1} @@ -116,7 +116,7 @@ local function init(panel, units) -- assignment (unit # or facility) local for_unit = util.trinary(unit.reactor == 0, "\x1a FACIL ", "\x1a UNIT " .. unit.reactor) - TextBox{parent=unit_hw_statuses,y=i,x=19,text=for_unit,height=1,fg_bg=fp_label} + TextBox{parent=unit_hw_statuses,y=i,x=19,text=for_unit,height=1,fg_bg=disabled_fg} end end diff --git a/rtu/panel/style.lua b/rtu/panel/style.lua index bfc52cf..36fd542 100644 --- a/rtu/panel/style.lua +++ b/rtu/panel/style.lua @@ -2,47 +2,29 @@ -- Graphics Style Options -- -local core = require("graphics.core") +local core = require("graphics.core") +local themes = require("graphics.themes") +---@class rtu_style local style = {} local cpair = core.cpair --- GLOBAL -- - --- remap global colors -colors.ivory = colors.pink -colors.yellow_hc = colors.purple -colors.red_off = colors.brown -colors.yellow_off = colors.magenta -colors.green_off = colors.lime - -style.root = cpair(colors.black, colors.ivory) -style.header = cpair(colors.black, colors.lightGray) - -style.colors = { - { c = colors.red, hex = 0xdf4949 }, -- RED ON - { c = colors.orange, hex = 0xffb659 }, - { c = colors.yellow, hex = 0xf9fb53 }, -- YELLOW ON - { c = colors.lime, hex = 0x16665a }, -- GREEN OFF - { c = colors.green, hex = 0x6be551 }, -- GREEN ON - { c = colors.cyan, hex = 0x34bac8 }, - { c = colors.lightBlue, hex = 0x6cc0f2 }, - { c = colors.blue, hex = 0x0096ff }, - { c = colors.purple, hex = 0xb156ee }, -- YELLOW HIGH CONTRAST - { c = colors.pink, hex = 0xdcd9ca }, -- IVORY - { c = colors.magenta, hex = 0x85862c }, -- YELLOW OFF - -- { c = colors.white, hex = 0xdcd9ca }, - { c = colors.lightGray, hex = 0xb1b8b3 }, - { c = colors.gray, hex = 0x575757 }, - -- { c = colors.black, hex = 0x191919 }, - { c = colors.brown, hex = 0x672223 } -- RED OFF -} - --- COMMON COLOR PAIRS -- - -style.fp_label = cpair(colors.lightGray, colors.ivory) +style.theme = themes.sandstone +style.fp = themes.get_fp_style(style.theme) style.ind_grn = cpair(colors.green, colors.green_off) +-- set theme per configuration +---@param fp integer fp theme ID (1 = sandstone, 2 = basalt) +function style.set_theme(fp) + if fp == 1 then + style.theme = themes.sandstone + elseif fp == 2 then + style.theme = themes.basalt + end + + style.fp = themes.get_fp_style(style.theme) +end + return style diff --git a/rtu/renderer.lua b/rtu/renderer.lua index a212c39..2a1a235 100644 --- a/rtu/renderer.lua +++ b/rtu/renderer.lua @@ -19,11 +19,15 @@ local ui = { -- try to start the UI ---@param units table RTU units +---@param theme integer front panel theme ID (1 = sandstone, 2 = basalt) ---@return boolean success, any error_msg -function renderer.try_start_ui(units) +function renderer.try_start_ui(units, theme) local status, msg = true, nil if ui.display == nil then + -- set theme + style.set_theme(theme) + -- reset terminal term.setTextColor(colors.white) term.setBackgroundColor(colors.black) @@ -31,13 +35,13 @@ function renderer.try_start_ui(units) term.setCursorPos(1, 1) -- set overridden colors - for i = 1, #style.colors do - term.setPaletteColor(style.colors[i].c, style.colors[i].hex) + for i = 1, #style.theme.colors do + term.setPaletteColor(style.theme.colors[i].c, style.theme.colors[i].hex) end -- init front panel view status, msg = pcall(function () - ui.display = DisplayBox{window=term.current(),fg_bg=style.root} + ui.display = DisplayBox{window=term.current(),fg_bg=style.fp.root} panel_view(ui.display, units) end) @@ -65,9 +69,9 @@ function renderer.close_ui() ui.display = nil -- restore colors - for i = 1, #style.colors do - local r, g, b = term.nativePaletteColor(style.colors[i].c) - term.setPaletteColor(style.colors[i].c, r, g, b) + for i = 1, #style.theme.colors do + local r, g, b = term.nativePaletteColor(style.theme.colors[i].c) + term.setPaletteColor(style.theme.colors[i].c, r, g, b) end -- reset terminal diff --git a/rtu/rtu.lua b/rtu/rtu.lua index bac230f..ab13bbd 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -29,15 +29,20 @@ function rtu.load_config() config.Redstone = settings.get("Redstone") config.SpeakerVolume = settings.get("SpeakerVolume") + config.SVR_Channel = settings.get("SVR_Channel") config.RTU_Channel = settings.get("RTU_Channel") config.ConnTimeout = settings.get("ConnTimeout") config.TrustedRange = settings.get("TrustedRange") config.AuthKey = settings.get("AuthKey") + config.LogMode = settings.get("LogMode") config.LogPath = settings.get("LogPath") config.LogDebug = settings.get("LogDebug") + config.FrontPanelTheme = settings.get("FrontPanelTheme") + config.ColorMode = settings.get("ColorMode") + local cfv = util.new_validator() cfv.assert_type_num(config.SpeakerVolume) @@ -61,6 +66,11 @@ function rtu.load_config() cfv.assert_type_str(config.LogPath) cfv.assert_type_bool(config.LogDebug) + cfv.assert_type_int(config.FrontPanelTheme) + cfv.assert_range(config.FrontPanelTheme, 1, 2) + cfv.assert_type_int(config.ColorMode) + cfv.assert_range(config.ColorMode, 1, 4) + cfv.assert_type_table(config.Peripherals) cfv.assert_type_table(config.Redstone) diff --git a/rtu/startup.lua b/rtu/startup.lua index 90b81a0..8888d05 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -506,7 +506,7 @@ local function main() if sys_config() then -- start UI local message - rtu_state.fp_ok, message = renderer.try_start_ui(units) + rtu_state.fp_ok, message = renderer.try_start_ui(units, config.FrontPanelTheme) if not rtu_state.fp_ok then println_ts(util.c("UI error: ", message)) diff --git a/supervisor/configure.lua b/supervisor/configure.lua index 34398b6..2f7bcd6 100644 --- a/supervisor/configure.lua +++ b/supervisor/configure.lua @@ -22,6 +22,8 @@ local RadioButton = require("graphics.elements.controls.radio_button") local NumberField = require("graphics.elements.form.number_field") local TextField = require("graphics.elements.form.text_field") +local IndLight = require("graphics.elements.indicators.light") + local println = util.println local tri = util.trinary @@ -32,7 +34,9 @@ local CENTER = core.ALIGN.CENTER local RIGHT = core.ALIGN.RIGHT -- changes to the config data/format to let the user know -local changes = {} +local changes = { + { "v1.2.12", { "Added front panel UI theme", "Added color accessibility modes" } } +} ---@class svr_configurator local configurator = {} @@ -63,13 +67,18 @@ local g_lg_fg_bg = cpair(colors.gray, colors.lightGray) local nav_fg_bg = bw_fg_bg local btn_act_fg_bg = cpair(colors.white, colors.gray) +---@class _svr_cfg_tool_ctl local tool_ctl = { ask_config = false, has_config = false, viewing_config = false, importing_legacy = false, + jumped_to_color = false, view_cfg = nil, ---@type graphics_element + color_cfg = nil, ---@type graphics_element + color_next = nil, ---@type graphics_element + color_apply = nil, ---@type graphics_element settings_apply = nil, ---@type graphics_element gen_summary = nil, ---@type function @@ -108,6 +117,8 @@ local tmp_cfg = { LogMode = 0, LogPath = "", LogDebug = false, + FrontPanelTheme = 1, + ColorMode = 1 } ---@class svr_config @@ -134,7 +145,9 @@ local fields = { { "AuthKey", "Facility Auth Key" , ""}, { "LogMode", "Log Mode", log.MODE.APPEND }, { "LogPath", "Log Path", "/log.txt" }, - { "LogDebug","Log Debug Messages", false } + { "LogDebug", "Log Debug Messages", false }, + { "FrontPanelTheme", "Front Panel Theme", 1 }, + { "ColorMode", "Color Mode", 1 } } -- load data from the settings file @@ -164,11 +177,12 @@ local function config_view(display) local svr_cfg = Div{parent=root_pane_div,x=1,y=1} local net_cfg = Div{parent=root_pane_div,x=1,y=1} local log_cfg = Div{parent=root_pane_div,x=1,y=1} + local clr_cfg = Div{parent=root_pane_div,x=1,y=1} local summary = Div{parent=root_pane_div,x=1,y=1} local changelog = Div{parent=root_pane_div,x=1,y=1} local import_err = Div{parent=root_pane_div,x=1,y=1} - local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,svr_cfg,net_cfg,log_cfg,summary,changelog,import_err}} + local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,svr_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,import_err}} -- Main Page @@ -185,7 +199,7 @@ local function config_view(display) tool_ctl.viewing_config = true tool_ctl.gen_summary(settings_cfg) tool_ctl.settings_apply.hide(true) - main_pane.set_value(5) + main_pane.set_value(6) end if fs.exists("/supervisor/config.lua") then @@ -196,10 +210,21 @@ local function config_view(display) PushButton{parent=main_page,x=2,y=y_start,min_width=18,text="Configure System",callback=function()main_pane.set_value(2)end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg} tool_ctl.view_cfg = PushButton{parent=main_page,x=2,y=y_start+2,min_width=20,text="View Configuration",callback=view_config,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)} - if not tool_ctl.has_config then tool_ctl.view_cfg.disable() end + local function jump_color() + tool_ctl.jumped_to_color = true + tool_ctl.color_next.hide(true) + tool_ctl.color_apply.show() + main_pane.set_value(5) + end PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg} - PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(6)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + if not tool_ctl.has_config then + tool_ctl.view_cfg.disable() + tool_ctl.color_cfg.disable() + end --#region Facility @@ -721,10 +746,8 @@ local function config_view(display) tmp_cfg.LogMode = mode.get_value() - 1 tmp_cfg.LogPath = path.get_value() tmp_cfg.LogDebug = en_dbg.get_value() - tool_ctl.gen_summary(tmp_cfg) - tool_ctl.viewing_config = false - tool_ctl.importing_legacy = false - tool_ctl.settings_apply.show() + tool_ctl.color_apply.hide(true) + tool_ctl.color_next.show() main_pane.set_value(5) else path_err.show() end end @@ -734,6 +757,110 @@ local function config_view(display) --#endregion + --#region Color Options + + local clr_c_1 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_2 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49} + local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49} + + local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}} + + TextBox{parent=clr_cfg,x=1,y=2,height=1,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)} + + TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color theme for the front panel."} + TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg} + + TextBox{parent=clr_c_1,x=1,y=7,height=1,text="Front Panel Theme"} + local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options={"Sandstone","Basalt"},callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."} + + local function recolor(value) + if value == 1 then + for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end + elseif value == 2 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf5e633) + term.setPaletteColor(colors.red, 0xff521a) + elseif value == 3 then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf7c311) + term.setPaletteColor(colors.red, 0xfb5615) + elseif value == 4 then + term.setPaletteColor(colors.green, 0x00ecff) + term.setPaletteColor(colors.yellow, 0xffbc00) + term.setPaletteColor(colors.red, 0xff0000) + end + end + + local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options={"None","Protanopia","Deuteranopia","Tritanopia"},callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta} + + local _ = IndLight{parent=clr_c_2,x=20,y=8,label="Good",colors=cpair(colors.black,colors.green),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=9,label="Warning",colors=cpair(colors.black,colors.yellow),value=true} + _ = IndLight{parent=clr_c_2,x=20,y=10,label="Bad",colors=cpair(colors.black,colors.red),value=true} + + TextBox{parent=clr_c_2,x=20,y=12,height=6,text="Exact color varies by theme.",fg_bg=g_lg_fg_bg} + + PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + local function back_from_colors() + main_pane.set_value(util.trinary(tool_ctl.jumped_to_color, 1, 4)) + tool_ctl.jumped_to_color = false + recolor(1) + end + + local function show_access() + clr_pane.set_value(2) + recolor(c_mode.get_value()) + end + + local function submit_colors() + tmp_cfg.FrontPanelTheme = fp_theme.get_value() + tmp_cfg.ColorMode = c_mode.get_value() + + if tool_ctl.jumped_to_color then + settings.set("FrontPanelTheme", tmp_cfg.FrontPanelTheme) + settings.set("ColorMode", tmp_cfg.ColorMode) + + if settings.save("/supervisor.settings") then + load_settings(settings_cfg, true) + load_settings(ini_cfg) + clr_pane.set_value(3) + else + clr_pane.set_value(4) + end + else + tool_ctl.gen_summary(tmp_cfg) + tool_ctl.viewing_config = false + tool_ctl.importing_legacy = false + tool_ctl.settings_apply.show() + main_pane.set_value(6) + end + end + + PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg} + + tool_ctl.color_apply.hide(true) + + local function c_go_home() + main_pane.set_value(1) + clr_pane.set_value(1) + end + + TextBox{parent=clr_c_3,x=1,y=1,height=1,text="Settings saved!"} + PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."} + PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)} + PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} + + --#endregion + --#region Summary and Saving local sum_c_1 = Div{parent=summary,x=2,y=4,width=49} @@ -754,7 +881,7 @@ local function config_view(display) tool_ctl.importing_legacy = false tool_ctl.settings_apply.show() else - main_pane.set_value(4) + main_pane.set_value(5) end end @@ -787,6 +914,8 @@ local function config_view(display) try_set(mode, ini_cfg.LogMode) try_set(path, ini_cfg.LogPath) try_set(en_dbg, ini_cfg.LogDebug) + try_set(fp_theme, ini_cfg.FrontPanelTheme) + try_set(c_mode, ini_cfg.ColorMode) for i = 1, #ini_cfg.CoolingConfig do local cfg, elems = ini_cfg.CoolingConfig[i], tool_ctl.cooling_elems[i] @@ -824,6 +953,7 @@ local function config_view(display) main_pane.set_value(1) svr_pane.set_value(1) net_pane.set_value(1) + clr_pane.set_value(1) sum_pane.set_value(1) end @@ -887,7 +1017,7 @@ local function config_view(display) if config.REACTOR_COOLING == nil or tmp_cfg.UnitCount ~= #config.REACTOR_COOLING then import_err_msg.set_value("Cooling configuration table length must match the number of units.") - main_pane.set_value(7) + main_pane.set_value(8) return end @@ -896,7 +1026,7 @@ local function config_view(display) if type(cfg) ~= "table" then import_err_msg.set_value("Cooling configuration for unit " .. i .. " must be a table.") - main_pane.set_value(7) + main_pane.set_value(8) return end @@ -907,14 +1037,14 @@ local function config_view(display) if not (util.is_int(tmp_cfg.FacilityTankMode) and tmp_cfg.FacilityTankMode >= 0 and tmp_cfg.FacilityTankMode <= 8) then import_err_msg.set_value("Invalid tank mode present in config. FAC_TANK_MODE must be a number 0 through 8.") - main_pane.set_value(7) + main_pane.set_value(8) return end if config.FAC_TANK_MODE > 0 then if config.FAC_TANK_DEFS == nil or tmp_cfg.UnitCount ~= #config.FAC_TANK_DEFS then import_err_msg.set_value("Facility tank definitions table length must match the number of units when using facility tanks.") - main_pane.set_value(7) + main_pane.set_value(8) return end @@ -945,7 +1075,7 @@ local function config_view(display) tool_ctl.gen_summary(tmp_cfg) sum_pane.set_value(1) - main_pane.set_value(5) + main_pane.set_value(6) tool_ctl.importing_legacy = true end @@ -976,6 +1106,10 @@ local function config_view(display) if f[1] == "AuthKey" then val = string.rep("*", string.len(val)) elseif f[1] == "LogMode" then val = util.trinary(raw == log.MODE.APPEND, "append", "replace") + elseif f[1] == "FrontPanelTheme" then + if raw == 1 then val = "Sandstone" elseif raw == 2 then val = "Basalt" end + elseif f[1] == "ColorMode" then + if raw == 1 then val = "Standard" elseif raw == 2 then val = "Protanopia" elseif raw == 3 then val = "Deuteranopia" elseif raw == 4 then val = "Tritanopia" end elseif f[1] == "CoolingConfig" and type(cfg.CoolingConfig) == "table" then val = "" diff --git a/supervisor/panel/components/pdg_entry.lua b/supervisor/panel/components/pdg_entry.lua index 6cb07f7..5bee335 100644 --- a/supervisor/panel/components/pdg_entry.lua +++ b/supervisor/panel/components/pdg_entry.lua @@ -17,31 +17,32 @@ local ALIGN = core.ALIGN local cpair = core.cpair -local black_lg = style.black_lg -local lg_white = style.lg_white - -- create a pocket diagnostics list entry ---@param parent graphics_element parent ---@param id integer PDG session ID local function init(parent, id) + local s_hi_box = style.theme.highlight_box + + local label_fg = style.fp.label_fg + -- root div local root = Div{parent=parent,x=2,y=2,height=4,width=parent.get_width()-2,hidden=true} - local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=style.bw_fg_bg} + local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=style.theme.highlight_box_bright} local ps_prefix = "pdg_" .. id .. "_" - TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=black_lg} - local pdg_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,height=1,fg_bg=black_lg,nav_active=cpair(colors.gray,colors.black)} - TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=black_lg} + TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=s_hi_box} + local pdg_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,height=1,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)} + TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=s_hi_box} pdg_addr.register(databus.ps, ps_prefix .. "addr", pdg_addr.set_value) TextBox{parent=entry,x=10,y=2,text="FW:",width=3,height=1} - local pdg_fw_v = TextBox{parent=entry,x=14,y=2,text=" ------- ",width=20,height=1,fg_bg=lg_white} + local pdg_fw_v = TextBox{parent=entry,x=14,y=2,text=" ------- ",width=20,height=1,fg_bg=label_fg} pdg_fw_v.register(databus.ps, ps_prefix .. "fw", pdg_fw_v.set_value) TextBox{parent=entry,x=35,y=2,text="RTT:",width=4,height=1} - local pdg_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=lg_white} - TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=lg_white} + local pdg_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=label_fg} + TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=label_fg} pdg_rtt.register(databus.ps, ps_prefix .. "rtt", pdg_rtt.update) pdg_rtt.register(databus.ps, ps_prefix .. "rtt_color", pdg_rtt.recolor) diff --git a/supervisor/panel/components/rtu_entry.lua b/supervisor/panel/components/rtu_entry.lua index 240c596..03c4c62 100644 --- a/supervisor/panel/components/rtu_entry.lua +++ b/supervisor/panel/components/rtu_entry.lua @@ -17,35 +17,36 @@ local ALIGN = core.ALIGN local cpair = core.cpair -local black_lg = style.black_lg -local lg_white = style.lg_white - -- create an RTU list entry ---@param parent graphics_element parent ---@param id integer RTU session ID local function init(parent, id) + local s_hi_box = style.theme.highlight_box + + local label_fg = style.fp.label_fg + -- root div local root = Div{parent=parent,x=2,y=2,height=4,width=parent.get_width()-2,hidden=true} - local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=style.bw_fg_bg} + local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=style.theme.highlight_box_bright} local ps_prefix = "rtu_" .. id .. "_" - TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=black_lg} - local rtu_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,height=1,fg_bg=black_lg,nav_active=cpair(colors.gray,colors.black)} - TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=black_lg} + TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=s_hi_box} + local rtu_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,height=1,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)} + TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=s_hi_box} rtu_addr.register(databus.ps, ps_prefix .. "addr", rtu_addr.set_value) TextBox{parent=entry,x=10,y=2,text="UNITS:",width=7,height=1} - local unit_count = DataIndicator{parent=entry,x=17,y=2,label="",unit="",format="%2d",value=0,width=2,fg_bg=style.gray_white} + local unit_count = DataIndicator{parent=entry,x=17,y=2,label="",unit="",format="%2d",value=0,width=2,fg_bg=style.fp.label_d_fg} unit_count.register(databus.ps, ps_prefix .. "units", unit_count.set_value) TextBox{parent=entry,x=21,y=2,text="FW:",width=3,height=1} - local rtu_fw_v = TextBox{parent=entry,x=25,y=2,text=" ------- ",width=9,height=1,fg_bg=lg_white} + local rtu_fw_v = TextBox{parent=entry,x=25,y=2,text=" ------- ",width=9,height=1,fg_bg=label_fg} rtu_fw_v.register(databus.ps, ps_prefix .. "fw", rtu_fw_v.set_value) TextBox{parent=entry,x=36,y=2,text="RTT:",width=4,height=1} - local rtu_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=lg_white} - TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=lg_white} + local rtu_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=label_fg} + TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=label_fg} rtu_rtt.register(databus.ps, ps_prefix .. "rtt", rtu_rtt.update) rtu_rtt.register(databus.ps, ps_prefix .. "rtt_color", rtu_rtt.recolor) diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index 8e37400..add7fcf 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -29,18 +29,18 @@ local ALIGN = core.ALIGN local cpair = core.cpair -local bw_fg_bg = style.bw_fg_bg - -local black_lg = style.black_lg -local lg_white = style.lg_white -local gry_wht = style.gray_white - local ind_grn = style.ind_grn -- create new front panel view ---@param panel graphics_element main displaybox local function init(panel) - TextBox{parent=panel,y=1,text="SCADA SUPERVISOR",alignment=ALIGN.CENTER,height=1,fg_bg=style.header} + local s_hi_box = style.theme.highlight_box + local s_hi_bright = style.theme.highlight_box_bright + + local label_fg = style.fp.label_fg + local label_d_fg = style.fp.label_d_fg + + TextBox{parent=panel,y=1,text="SCADA SUPERVISOR",alignment=ALIGN.CENTER,height=1,fg_bg=style.theme.header} local page_div = Div{parent=panel,x=1,y=3} @@ -66,13 +66,13 @@ local function init(panel) ---@diagnostic disable-next-line: undefined-field local comp_id = util.sprintf("(%d)", os.getComputerID()) - TextBox{parent=system,x=9,y=4,width=6,height=1,text=comp_id,fg_bg=style.fp_label} + TextBox{parent=system,x=9,y=4,width=6,height=1,text=comp_id,fg_bg=style.fp.disabled_fg} -- -- about footer -- - local about = Div{parent=main_page,width=15,height=3,x=1,y=16,fg_bg=style.fp_label} + local about = Div{parent=main_page,width=15,height=3,x=1,y=16,fg_bg=style.fp.disabled_fg} local fw_v = TextBox{parent=about,x=1,y=1,text="FW: v00.00.00",alignment=ALIGN.LEFT,height=1} local comms_v = TextBox{parent=about,x=1,y=2,text="NT: v00.00.00",alignment=ALIGN.LEFT,height=1} @@ -90,25 +90,25 @@ local function init(panel) for i = 1, supervisor.config.UnitCount do local ps_prefix = "plc_" .. i .. "_" - local plc_entry = Div{parent=plc_list,height=3,fg_bg=bw_fg_bg} + local plc_entry = Div{parent=plc_list,height=3,fg_bg=s_hi_bright} - TextBox{parent=plc_entry,x=1,y=1,text="",width=8,height=1,fg_bg=black_lg} - TextBox{parent=plc_entry,x=1,y=2,text="UNIT "..i,alignment=ALIGN.CENTER,width=8,height=1,fg_bg=black_lg} - TextBox{parent=plc_entry,x=1,y=3,text="",width=8,height=1,fg_bg=black_lg} + TextBox{parent=plc_entry,x=1,y=1,text="",width=8,height=1,fg_bg=s_hi_box} + TextBox{parent=plc_entry,x=1,y=2,text="UNIT "..i,alignment=ALIGN.CENTER,width=8,height=1,fg_bg=s_hi_box} + TextBox{parent=plc_entry,x=1,y=3,text="",width=8,height=1,fg_bg=s_hi_box} local conn = LED{parent=plc_entry,x=10,y=2,label="LINK",colors=ind_grn} conn.register(databus.ps, ps_prefix .. "conn", conn.update) - local plc_addr = TextBox{parent=plc_entry,x=17,y=2,text=" --- ",width=5,height=1,fg_bg=gry_wht} + local plc_addr = TextBox{parent=plc_entry,x=17,y=2,text=" --- ",width=5,height=1,fg_bg=label_d_fg} plc_addr.register(databus.ps, ps_prefix .. "addr", plc_addr.set_value) TextBox{parent=plc_entry,x=23,y=2,text="FW:",width=3,height=1} - local plc_fw_v = TextBox{parent=plc_entry,x=27,y=2,text=" ------- ",width=9,height=1,fg_bg=lg_white} + local plc_fw_v = TextBox{parent=plc_entry,x=27,y=2,text=" ------- ",width=9,height=1,fg_bg=label_fg} plc_fw_v.register(databus.ps, ps_prefix .. "fw", plc_fw_v.set_value) TextBox{parent=plc_entry,x=37,y=2,text="RTT:",width=4,height=1} - local plc_rtt = DataIndicator{parent=plc_entry,x=42,y=2,label="",unit="",format="%4d",value=0,width=4,fg_bg=lg_white} - TextBox{parent=plc_entry,x=47,y=2,text="ms",width=4,height=1,fg_bg=lg_white} + local plc_rtt = DataIndicator{parent=plc_entry,x=42,y=2,label="",unit="",format="%4d",value=0,width=4,fg_bg=label_fg} + TextBox{parent=plc_entry,x=47,y=2,text="ms",width=4,height=1,fg_bg=label_fg} plc_rtt.register(databus.ps, ps_prefix .. "rtt", plc_rtt.update) plc_rtt.register(databus.ps, ps_prefix .. "rtt_color", plc_rtt.recolor) @@ -124,29 +124,29 @@ local function init(panel) -- coordinator page local crd_page = Div{parent=page_div,x=1,y=1,hidden=true} - local crd_box = Div{parent=crd_page,x=2,y=2,width=49,height=4,fg_bg=bw_fg_bg} + local crd_box = Div{parent=crd_page,x=2,y=2,width=49,height=4,fg_bg=s_hi_bright} local crd_conn = LED{parent=crd_box,x=2,y=2,label="CONNECTION",colors=ind_grn} crd_conn.register(databus.ps, "crd_conn", crd_conn.update) - TextBox{parent=crd_box,x=4,y=3,text="COMPUTER",width=8,height=1,fg_bg=gry_wht} - local crd_addr = TextBox{parent=crd_box,x=13,y=3,text="---",width=5,height=1,fg_bg=gry_wht} + TextBox{parent=crd_box,x=4,y=3,text="COMPUTER",width=8,height=1,fg_bg=label_d_fg} + local crd_addr = TextBox{parent=crd_box,x=13,y=3,text="---",width=5,height=1,fg_bg=label_d_fg} crd_addr.register(databus.ps, "crd_addr", crd_addr.set_value) TextBox{parent=crd_box,x=22,y=2,text="FW:",width=3,height=1} - local crd_fw_v = TextBox{parent=crd_box,x=26,y=2,text=" ------- ",width=9,height=1,fg_bg=lg_white} + local crd_fw_v = TextBox{parent=crd_box,x=26,y=2,text=" ------- ",width=9,height=1,fg_bg=label_fg} crd_fw_v.register(databus.ps, "crd_fw", crd_fw_v.set_value) TextBox{parent=crd_box,x=36,y=2,text="RTT:",width=4,height=1} - local crd_rtt = DataIndicator{parent=crd_box,x=41,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=lg_white} - TextBox{parent=crd_box,x=47,y=2,text="ms",width=4,height=1,fg_bg=lg_white} + local crd_rtt = DataIndicator{parent=crd_box,x=41,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=label_fg} + TextBox{parent=crd_box,x=47,y=2,text="ms",width=4,height=1,fg_bg=label_fg} crd_rtt.register(databus.ps, "crd_rtt", crd_rtt.update) crd_rtt.register(databus.ps, "crd_rtt_color", crd_rtt.recolor) -- pocket diagnostics page local pkt_page = Div{parent=page_div,x=1,y=1,hidden=true} - local pdg_list = ListBox{parent=pkt_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=cpair(colors.black,colors.ivory),nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} + local pdg_list = ListBox{parent=pkt_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=style.fp.text_fg,nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} local _ = Div{parent=pdg_list,height=1,hidden=true} -- padding -- assemble page panes @@ -156,14 +156,14 @@ local function init(panel) local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} local tabs = { - { name = "SVR", color = cpair(colors.black, colors.ivory) }, - { name = "PLC", color = cpair(colors.black, colors.ivory) }, - { name = "RTU", color = cpair(colors.black, colors.ivory) }, - { name = "CRD", color = cpair(colors.black, colors.ivory) }, - { name = "PKT", color = cpair(colors.black, colors.ivory) }, + { name = "SVR", color = style.fp.text }, + { name = "PLC", color = style.fp.text }, + { name = "RTU", color = style.fp.text }, + { name = "CRD", color = style.fp.text }, + { name = "PKT", color = style.fp.text }, } - TabBar{parent=panel,y=2,tabs=tabs,min_width=9,callback=page_pane.set_value,fg_bg=bw_fg_bg} + TabBar{parent=panel,y=2,tabs=tabs,min_width=9,callback=page_pane.set_value,fg_bg=style.theme.highlight_box_bright} -- link RTU/PDG list management to PGI pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry) diff --git a/supervisor/panel/style.lua b/supervisor/panel/style.lua index 49bfb4f..efcc9b7 100644 --- a/supervisor/panel/style.lua +++ b/supervisor/panel/style.lua @@ -2,53 +2,29 @@ -- Graphics Style Options -- -local core = require("graphics.core") +local core = require("graphics.core") +local themes = require("graphics.themes") +---@class svr_style local style = {} local cpair = core.cpair --- GLOBAL -- - --- remap global colors -colors.ivory = colors.pink -colors.yellow_hc = colors.purple -colors.red_off = colors.brown -colors.yellow_off = colors.magenta -colors.green_off = colors.lime - -style.root = cpair(colors.black, colors.ivory) -style.header = cpair(colors.black, colors.lightGray) - -style.colors = { - { c = colors.red, hex = 0xdf4949 }, -- RED ON - { c = colors.orange, hex = 0xffb659 }, - { c = colors.yellow, hex = 0xf9fb53 }, -- YELLOW ON - { c = colors.lime, hex = 0x16665a }, -- GREEN OFF - { c = colors.green, hex = 0x6be551 }, -- GREEN ON - { c = colors.cyan, hex = 0x34bac8 }, - { c = colors.lightBlue, hex = 0x6cc0f2 }, - { c = colors.blue, hex = 0x0008fe }, -- LCD BLUE - { c = colors.purple, hex = 0xe3bc2a }, -- YELLOW HIGH CONTRAST - { c = colors.pink, hex = 0xdcd9ca }, -- IVORY - { c = colors.magenta, hex = 0x85862c }, -- YELLOW OFF - -- { c = colors.white, hex = 0xdcd9ca }, - { c = colors.lightGray, hex = 0xb1b8b3 }, - { c = colors.gray, hex = 0x575757 }, - -- { c = colors.black, hex = 0x191919 }, - { c = colors.brown, hex = 0x672223 } -- RED OFF -} - --- COMMON COLOR PAIRS -- - -style.text_fg_bg = cpair(colors.black, colors.ivory) -style.bw_fg_bg = cpair(colors.black, colors.white) -style.fp_label = cpair(colors.lightGray, colors.ivory) - -style.black_lg = cpair(colors.black, colors.lightGray) -style.lg_white = cpair(colors.lightGray, colors.white) -style.gray_white = cpair(colors.gray, colors.white) +style.theme = themes.sandstone +style.fp = themes.get_fp_style(style.theme) style.ind_grn = cpair(colors.green, colors.green_off) +-- set theme per configuration +---@param fp integer fp theme ID (1 = sandstone, 2 = basalt) +function style.set_theme(fp) + if fp == 1 then + style.theme = themes.sandstone + elseif fp == 2 then + style.theme = themes.basalt + end + + style.fp = themes.get_fp_style(style.theme) +end + return style diff --git a/supervisor/renderer.lua b/supervisor/renderer.lua index 73333d0..8f9389f 100644 --- a/supervisor/renderer.lua +++ b/supervisor/renderer.lua @@ -19,11 +19,15 @@ local ui = { } -- try to start the UI +---@param theme integer front panel theme ID (1 = sandstone, 2 = basalt) ---@return boolean success, any error_msg -function renderer.try_start_ui() +function renderer.try_start_ui(theme) local status, msg = true, nil if ui.display == nil then + -- set theme + style.set_theme(theme) + -- reset terminal term.setTextColor(colors.white) term.setBackgroundColor(colors.black) @@ -31,13 +35,13 @@ function renderer.try_start_ui() term.setCursorPos(1, 1) -- set overridden colors - for i = 1, #style.colors do - term.setPaletteColor(style.colors[i].c, style.colors[i].hex) + for i = 1, #style.theme.colors do + term.setPaletteColor(style.theme.colors[i].c, style.theme.colors[i].hex) end -- init front panel view status, msg = pcall(function () - ui.display = DisplayBox{window=term.current(),fg_bg=style.root} + ui.display = DisplayBox{window=term.current(),fg_bg=style.fp.root} panel_view(ui.display) end) @@ -70,9 +74,9 @@ function renderer.close_ui() ui.display = nil -- restore colors - for i = 1, #style.colors do - local r, g, b = term.nativePaletteColor(style.colors[i].c) - term.setPaletteColor(style.colors[i].c, r, g, b) + for i = 1, #style.theme.colors do + local r, g, b = term.nativePaletteColor(style.theme.colors[i].c) + term.setPaletteColor(style.theme.colors[i].c, r, g, b) end -- reset terminal diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 72c0c97..d9c2229 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -21,7 +21,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v1.2.11" +local SUPERVISOR_VERSION = "v1.2.12" local println = util.println local println_ts = util.println_ts @@ -118,7 +118,7 @@ local function main() databus.tx_hw_modem(true) -- start UI - local fp_ok, message = renderer.try_start_ui() + local fp_ok, message = renderer.try_start_ui(config.FrontPanelTheme) if not fp_ok then println_ts(util.c("UI error: ", message)) diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 27bf22c..43536c6 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -43,6 +43,9 @@ function supervisor.load_config() config.LogPath = settings.get("LogPath") config.LogDebug = settings.get("LogDebug") + config.FrontPanelTheme = settings.get("FrontPanelTheme") + config.ColorMode = settings.get("ColorMode") + local cfv = util.new_validator() cfv.assert_type_int(config.UnitCount) @@ -81,6 +84,11 @@ function supervisor.load_config() cfv.assert_type_str(config.LogPath) cfv.assert_type_bool(config.LogDebug) + cfv.assert_type_int(config.FrontPanelTheme) + cfv.assert_range(config.FrontPanelTheme, 1, 2) + cfv.assert_type_int(config.ColorMode) + cfv.assert_range(config.ColorMode, 1, 4) + return cfv.valid() end