From 1f451ff92adfd82607761e5e935968c1446fef6f Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Mon, 11 Mar 2024 23:31:31 -0400 Subject: [PATCH] #340 coordinator colorblind support --- coordinator/configure.lua | 12 +-- coordinator/iocontrol.lua | 2 +- coordinator/renderer.lua | 27 +++++-- coordinator/startup.lua | 7 +- coordinator/ui/components/process_ctl.lua | 20 ++--- coordinator/ui/components/unit_detail.lua | 49 ++++++------ coordinator/ui/components/unit_flow.lua | 12 +-- coordinator/ui/layout/front_panel.lua | 43 +++++++++- coordinator/ui/style.lua | 95 +++++++++++++++++------ graphics/themes.lua | 3 + 10 files changed, 187 insertions(+), 83 deletions(-) diff --git a/coordinator/configure.lua b/coordinator/configure.lua index b2576c5..1480dd7 100644 --- a/coordinator/configure.lua +++ b/coordinator/configure.lua @@ -843,15 +843,15 @@ local function config_view(display) 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 + elseif value == themes.COLOR_MODE.DEUTERANOPIA then term.setPaletteColor(colors.green, 0x1081ff) term.setPaletteColor(colors.yellow, 0xf7c311) term.setPaletteColor(colors.red, 0xfb5615) - elseif value == 4 then + elseif value == themes.COLOR_MODE.PROTANOPIA then + term.setPaletteColor(colors.green, 0x1081ff) + term.setPaletteColor(colors.yellow, 0xf5e633) + term.setPaletteColor(colors.red, 0xff521a) + elseif value == themes.COLOR_MODE.TRITANOPIA then term.setPaletteColor(colors.green, 0x00ecff) term.setPaletteColor(colors.yellow, 0xffbc00) term.setPaletteColor(colors.red, 0xff0000) diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index 312d194..0cb50e4 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -403,7 +403,7 @@ function iocontrol.fp_pkt_rtt(session_id, rtt) elseif rtt > WARN_RTT then io.fp.ps.publish("pkt_" .. session_id .. "_rtt_color", colors.yellow_hc) else - io.fp.ps.publish("pkt_" .. session_id .. "_rtt_color", colors.green) + io.fp.ps.publish("pkt_" .. session_id .. "_rtt_color", colors.green_hc) end end diff --git a/coordinator/renderer.lua b/coordinator/renderer.lua index c05afee..ad275dc 100644 --- a/coordinator/renderer.lua +++ b/coordinator/renderer.lua @@ -16,6 +16,7 @@ local unit_view = require("coordinator.ui.layout.unit_view") local core = require("graphics.core") local flasher = require("graphics.flasher") +local themes = require("graphics.themes") local DisplayBox = require("graphics.elements.displaybox") @@ -24,6 +25,7 @@ local renderer = {} -- render engine local engine = { + color_mode = 1, ---@type COLOR_MODE monitors = nil, ---@type monitors_struct|nil dmesg_window = nil, ---@type table|nil ui_ready = false, @@ -50,6 +52,12 @@ local function _init_display(monitor) for i = 1, #style.theme.colors do monitor.setPaletteColor(style.theme.colors[i].c, style.theme.colors[i].hex) end + + -- apply color mode + local c_mode_overrides = style.theme.color_modes[engine.color_mode] + for i = 1, #c_mode_overrides do + monitor.setPaletteColor(c_mode_overrides[i].c, c_mode_overrides[i].hex) + end end -- print out that the monitor is too small @@ -62,10 +70,13 @@ local function _print_too_small(monitor) monitor.write("monitor too small") end --- disable the flow view ----@param disable boolean -function renderer.legacy_disable_flow_view(disable) - engine.disable_flow_view = disable +-- apply renderer configurations +---@param config crd_config +function renderer.configure(config) + style.set_themes(config.MainTheme, config.FrontPanelTheme, config.ColorMode ~= themes.COLOR_MODE.STANDARD) + + engine.color_mode = config.ColorMode + engine.disable_flow_view = config.DisableFlowView end -- link to the monitor peripherals @@ -100,6 +111,12 @@ function renderer.init_displays() for i = 1, #style.fp_theme.colors do term.setPaletteColor(style.fp_theme.colors[i].c, style.fp_theme.colors[i].hex) end + + -- apply color mode + local c_mode_overrides = style.fp_theme.color_modes[engine.color_mode] + for i = 1, #c_mode_overrides do + term.setPaletteColor(c_mode_overrides[i].c, c_mode_overrides[i].hex) + end end -- initialize the dmesg output window @@ -118,7 +135,7 @@ function renderer.try_start_fp() -- show front panel view on terminal status, msg = pcall(function () engine.ui.front_panel = DisplayBox{window=term.native(),fg_bg=style.fp.root} - panel_view(engine.ui.front_panel, #engine.monitors.unit_displays) + panel_view(engine.ui.front_panel, #engine.monitors.unit_displays, engine.color_mode) end) if status then diff --git a/coordinator/startup.lua b/coordinator/startup.lua index feeafd0..5b3c46b 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -22,9 +22,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local style = require("coordinator.ui.style") - -local COORDINATOR_VERSION = "v1.2.12" +local COORDINATOR_VERSION = "v1.3.0" local CHUNK_LOAD_DELAY_S = 30.0 @@ -122,8 +120,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.configure(config) renderer.set_displays(monitors) renderer.init_displays() renderer.init_dmesg() diff --git a/coordinator/ui/components/process_ctl.lua b/coordinator/ui/components/process_ctl.lua index e1c3252..fb0c939 100644 --- a/coordinator/ui/components/process_ctl.lua +++ b/coordinator/ui/components/process_ctl.lua @@ -30,11 +30,6 @@ local border = core.border local bw_fg_bg = style.bw_fg_bg -local ind_grn = style.ind_grn -local ind_yel = style.ind_yel -local ind_red = style.ind_red -local ind_wht = style.ind_wht - local period = core.flasher.PERIOD -- new process control view @@ -50,6 +45,11 @@ local function new_view(root, x, y) local dis_colors = style.dis_colors local arrow_fg_bg = cpair(style.theme.label, s_hi_box.bkg) + local ind_grn = style.ind_grn + local ind_yel = style.ind_yel + local ind_red = style.ind_red + local ind_wht = style.ind_wht + 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) @@ -68,7 +68,7 @@ local function new_view(root, x, y) facility.ack_alarms_ack = ack_a.on_response local all_ok = IndicatorLight{parent=main,y=5,label="Unit Systems Online",colors=ind_grn} - local rad_mon = TriIndicatorLight{parent=main,label="Radiation Monitor",c1=colors.gray,c2=colors.yellow,c3=colors.green} + local rad_mon = TriIndicatorLight{parent=main,label="Radiation Monitor",c1=style.ind_bkg,c2=ind_yel.fgd,c3=ind_grn.fgd} local ind_mat = IndicatorLight{parent=main,label="Induction Matrix",colors=ind_grn} local sps = IndicatorLight{parent=main,label="SPS Connected",colors=ind_grn} @@ -219,7 +219,7 @@ local function new_view(root, x, y) if i <= facility.num_units then tag_fg_bg = cpair(colors.black, colors.cyan) ind_fg_bg = cpair(style.theme.text, s_hi_box.bkg) - ind_off = style.theme.label + ind_off = style.ind_hi_box_bg end local _y = ((i - 1) * 5) + 1 @@ -228,8 +228,8 @@ local function new_view(root, x, y) TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Status",width=7,height=2} local lights = Div{parent=stat_div,x=9,y=_y,width=14,height=4,fg_bg=ind_fg_bg} - local ready = IndicatorLight{parent=lights,x=2,y=2,label="Ready",colors=cpair(colors.green,ind_off)} - local degraded = IndicatorLight{parent=lights,x=2,y=3,label="Degraded",colors=cpair(colors.red,ind_off),flash=true,period=period.BLINK_250_MS} + local ready = IndicatorLight{parent=lights,x=2,y=2,label="Ready",colors=cpair(ind_grn.fgd,ind_off)} + local degraded = IndicatorLight{parent=lights,x=2,y=3,label="Degraded",colors=cpair(ind_red.fgd,ind_off),flash=true,period=period.BLINK_250_MS} if i <= facility.num_units then local unit = units[i] ---@type ioctl_unit @@ -341,7 +341,7 @@ local function new_view(root, x, y) 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(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)} + 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.checkbox_bg)} waste_prod.register(facility.ps, "process_waste_product", waste_prod.set_value) pu_fallback.register(facility.ps, "process_pu_fallback", pu_fallback.set_value) diff --git a/coordinator/ui/components/unit_detail.lua b/coordinator/ui/components/unit_detail.lua index d76c9d8..2264b00 100644 --- a/coordinator/ui/components/unit_detail.lua +++ b/coordinator/ui/components/unit_detail.lua @@ -37,11 +37,6 @@ local border = core.border local bw_fg_bg = style.bw_fg_bg local gry_wht = style.gray_white -local ind_grn = style.ind_grn -local ind_yel = style.ind_yel -local ind_red = style.ind_red -local ind_wht = style.ind_wht - local period = core.flasher.PERIOD -- create a unit view @@ -58,6 +53,12 @@ local function init(parent, id) local dis_colors = style.dis_colors local arrow_fg_bg = cpair(style.theme.label, s_hi_box.bkg) + local ind_bkg = style.ind_bkg + local ind_grn = style.ind_grn + local ind_yel = style.ind_yel + local ind_red = style.ind_red + local ind_wht = style.ind_wht + local db = iocontrol.get_db() local unit = db.units[id] ---@type ioctl_unit local f_ps = db.facility.ps @@ -158,9 +159,9 @@ local function init(parent, id) local annunciator = Div{parent=main,width=23,height=18,x=22,y=3} -- connectivity - local plc_online = IndicatorLight{parent=annunciator,label="PLC Online",colors=cpair(colors.green,colors.red)} + local plc_online = IndicatorLight{parent=annunciator,label="PLC Online",colors=cpair(ind_grn.fgd,ind_red.fgd)} local plc_hbeat = IndicatorLight{parent=annunciator,label="PLC Heartbeat",colors=ind_wht} - local rad_mon = TriIndicatorLight{parent=annunciator,label="Radiation Monitor",c1=colors.gray,c2=colors.yellow,c3=colors.green} + local rad_mon = TriIndicatorLight{parent=annunciator,label="Radiation Monitor",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_grn.fgd} plc_online.register(u_ps, "PLCOnline", plc_online.update) plc_hbeat.register(u_ps, "PLCHeartbeat", plc_hbeat.update) @@ -217,7 +218,7 @@ local function init(parent, id) local rps_loc = IndicatorLight{parent=rps_annunc,label="Coolant Level Low Low",colors=ind_yel} local rps_flt = IndicatorLight{parent=rps_annunc,label="PPM Fault",colors=ind_yel,flash=true,period=period.BLINK_500_MS} local rps_tmo = IndicatorLight{parent=rps_annunc,label="Connection Timeout",colors=ind_yel,flash=true,period=period.BLINK_500_MS} - local rps_sfl = IndicatorLight{parent=rps_annunc,label="System Failure",colors=cpair(colors.orange,colors.gray),flash=true,period=period.BLINK_500_MS} + local rps_sfl = IndicatorLight{parent=rps_annunc,label="System Failure",colors=ind_red,flash=true,period=period.BLINK_500_MS} rps_trp.register(u_ps, "rps_tripped", rps_trp.update) rps_dmg.register(u_ps, "high_dmg", rps_dmg.update) @@ -238,7 +239,7 @@ local function init(parent, id) local rcs_tags = Div{parent=rcs,width=2,height=16,x=1,y=7} local c_flt = IndicatorLight{parent=rcs_annunc,label="RCS Hardware Fault",colors=ind_yel} - local c_emg = TriIndicatorLight{parent=rcs_annunc,label="Emergency Coolant",c1=colors.gray,c2=colors.white,c3=colors.green} + local c_emg = TriIndicatorLight{parent=rcs_annunc,label="Emergency Coolant",c1=ind_bkg,c2=ind_wht.fgd,c3=ind_grn.fgd} local c_cfm = IndicatorLight{parent=rcs_annunc,label="Coolant Feed Mismatch",colors=ind_yel} local c_brm = IndicatorLight{parent=rcs_annunc,label="Boil Rate Mismatch",colors=ind_yel} local c_sfm = IndicatorLight{parent=rcs_annunc,label="Steam Feed Mismatch",colors=ind_yel} @@ -294,7 +295,7 @@ 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=hc_text} - local t1_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=colors.gray,c2=colors.yellow,c3=colors.red} + local t1_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_red.fgd} t1_sdo.register(t_ps[1], "SteamDumpOpen", t1_sdo.update) TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=hc_text} @@ -315,7 +316,7 @@ local function init(parent, id) end 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} + local t2_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_red.fgd} t2_sdo.register(t_ps[2], "SteamDumpOpen", t2_sdo.update) TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=hc_text} @@ -335,7 +336,7 @@ local function init(parent, id) if available_space > 3 then _add_space() end 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} + local t3_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_red.fgd} t3_sdo.register(t_ps[3], "SteamDumpOpen", t3_sdo.update) TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=hc_text} @@ -405,20 +406,20 @@ local function init(parent, id) 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} - local a_dmg = AlarmLight{parent=alarm_panel,x=6,label="Critical Damage",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} + local a_brc = AlarmLight{parent=alarm_panel,x=6,y=2,label="Containment Breach",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} + local a_rad = AlarmLight{parent=alarm_panel,x=6,label="Containment Radiation",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} + local a_dmg = AlarmLight{parent=alarm_panel,x=6,label="Critical Damage",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} alarm_panel.line_break() - local a_rcl = AlarmLight{parent=alarm_panel,x=6,label="Reactor Lost",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} - local a_rcd = AlarmLight{parent=alarm_panel,x=6,label="Reactor Damage",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} - local a_rot = AlarmLight{parent=alarm_panel,x=6,label="Reactor Over Temp",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} - local a_rht = AlarmLight{parent=alarm_panel,x=6,label="Reactor High Temp",c1=colors.gray,c2=colors.yellow,c3=colors.green,flash=true,period=period.BLINK_500_MS} - local a_rwl = AlarmLight{parent=alarm_panel,x=6,label="Reactor Waste Leak",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} - local a_rwh = AlarmLight{parent=alarm_panel,x=6,label="Reactor Waste High",c1=colors.gray,c2=colors.yellow,c3=colors.green,flash=true,period=period.BLINK_500_MS} + local a_rcl = AlarmLight{parent=alarm_panel,x=6,label="Reactor Lost",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} + local a_rcd = AlarmLight{parent=alarm_panel,x=6,label="Reactor Damage",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} + local a_rot = AlarmLight{parent=alarm_panel,x=6,label="Reactor Over Temp",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} + local a_rht = AlarmLight{parent=alarm_panel,x=6,label="Reactor High Temp",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_500_MS} + local a_rwl = AlarmLight{parent=alarm_panel,x=6,label="Reactor Waste Leak",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} + local a_rwh = AlarmLight{parent=alarm_panel,x=6,label="Reactor Waste High",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_500_MS} alarm_panel.line_break() - local a_rps = AlarmLight{parent=alarm_panel,x=6,label="RPS Transient",c1=colors.gray,c2=colors.yellow,c3=colors.green,flash=true,period=period.BLINK_500_MS} - local a_clt = AlarmLight{parent=alarm_panel,x=6,label="RCS Transient",c1=colors.gray,c2=colors.yellow,c3=colors.green,flash=true,period=period.BLINK_500_MS} - local a_tbt = AlarmLight{parent=alarm_panel,x=6,label="Turbine Trip",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} + local a_rps = AlarmLight{parent=alarm_panel,x=6,label="RPS Transient",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_500_MS} + local a_clt = AlarmLight{parent=alarm_panel,x=6,label="RCS Transient",c1=ind_bkg,c2=ind_yel.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_500_MS} + local a_tbt = AlarmLight{parent=alarm_panel,x=6,label="Turbine Trip",c1=ind_bkg,c2=ind_red.fgd,c3=ind_grn.fgd,flash=true,period=period.BLINK_250_MS} a_brc.register(u_ps, "Alarm_1", a_brc.update) a_rad.register(u_ps, "Alarm_2", a_rad.update) diff --git a/coordinator/ui/components/unit_flow.lua b/coordinator/ui/components/unit_flow.lua index 115450b..39c2c00 100644 --- a/coordinator/ui/components/unit_flow.lua +++ b/coordinator/ui/components/unit_flow.lua @@ -30,9 +30,6 @@ local pipe = core.pipe local wh_gray = style.wh_gray local lg_gray = style.lg_gray -local ind_grn = style.ind_grn -local ind_wht = style.ind_wht - -- make a new unit flow window ---@param parent graphics_element parent ---@param x integer top left x @@ -46,6 +43,9 @@ local function make(parent, x, y, wide, unit) local lu_c = style.lu_colors local lu_c_d = style.lu_colors_dark + local ind_grn = style.ind_grn + local ind_wht = style.ind_wht + local height = 16 local v_start = 1 + ((unit.unit_id - 1) * 5) @@ -112,7 +112,7 @@ local function make(parent, x, y, wide, unit) 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) - local boiler = Rectangle{parent=root,x=_wide(47,40),y=1,border=border(1, colors.gray, true),width=19,height=5,fg_bg=wh_gray} + local boiler = Rectangle{parent=root,x=_wide(47,40),y=1,border=border(1,colors.gray,true),width=19,height=5,fg_bg=wh_gray} TextBox{parent=boiler,y=1,text="THERMO-ELECTRIC",alignment=ALIGN.CENTER,height=1} TextBox{parent=boiler,y=3,text=util.trinary(unit.num_boilers>1,"BOILERS","BOILER"),alignment=ALIGN.CENTER,height=1} TextBox{parent=root,x=_wide(47,40),y=2,text="\x1b \x80 \x1a",width=1,height=3,fg_bg=lg_gray} @@ -131,7 +131,7 @@ local function make(parent, x, y, wide, unit) st_rate.register(unit.unit_ps, "heating_rate", st_rate.update) end - local turbine = Rectangle{parent=root,x=_wide(93,79),y=1,border=border(1, colors.gray, true),width=19,height=5,fg_bg=wh_gray} + local turbine = Rectangle{parent=root,x=_wide(93,79),y=1,border=border(1,colors.gray,true),width=19,height=5,fg_bg=wh_gray} TextBox{parent=turbine,y=1,text="STEAM TURBINE",alignment=ALIGN.CENTER,height=1} TextBox{parent=turbine,y=3,text=util.trinary(unit.num_turbines>1,"GENERATORS","GENERATOR"),alignment=ALIGN.CENTER,height=1} TextBox{parent=root,x=_wide(93,79),y=2,text="\x1b \x80 \x1a",width=1,height=3,fg_bg=lg_gray} @@ -139,7 +139,7 @@ local function make(parent, x, y, wide, unit) for i = 1, unit.num_turbines do local ry = 1 + (2 * (i - 1)) + prv_yo TextBox{parent=root,x=_wide(125,103),y=ry,text="\x10\x11\x7f",fg_bg=text_c,width=3,height=1} - local state = TriIndicatorLight{parent=root,x=_wide(129,107),y=ry,label=v_names[i+4],c1=colors.gray,c2=colors.yellow,c3=colors.red} + local state = TriIndicatorLight{parent=root,x=_wide(129,107),y=ry,label=v_names[i+4],c1=style.ind_bkg,c2=style.ind_yel.fgd,c3=style.ind_red.fgd} state.register(unit.turbine_ps_tbl[i], "SteamDumpOpen", state.update) end diff --git a/coordinator/ui/layout/front_panel.lua b/coordinator/ui/layout/front_panel.lua index d2eb8ff..459a9f0 100644 --- a/coordinator/ui/layout/front_panel.lua +++ b/coordinator/ui/layout/front_panel.lua @@ -13,6 +13,7 @@ local style = require("coordinator.ui.style") local pkt_entry = require("coordinator.ui.components.pkt_entry") local core = require("graphics.core") +local themes = require("graphics.themes") local Div = require("graphics.elements.div") local ListBox = require("graphics.elements.listbox") @@ -24,6 +25,8 @@ local TabBar = require("graphics.elements.controls.tabbar") local LED = require("graphics.elements.indicators.led") local RGBLED = require("graphics.elements.indicators.ledrgb") +local LINK_STATE = types.PANEL_LINK_STATE + local ALIGN = core.ALIGN local cpair = core.cpair @@ -33,7 +36,8 @@ local led_grn = style.led_grn -- create new front panel view ---@param panel graphics_element main displaybox ---@param num_units integer number of units (number of unit monitors) -local function init(panel, num_units) +---@param color_mode COLOR_MODE color mode +local function init(panel, num_units, color_mode) local ps = iocontrol.get_db().fp.ps TextBox{parent=panel,y=1,text="SCADA COORDINATOR",alignment=ALIGN.CENTER,height=1,fg_bg=style.fp_theme.header} @@ -56,12 +60,43 @@ local function init(panel, num_units) heartbeat.register(ps, "heartbeat", heartbeat.update) local modem = LED{parent=system,label="MODEM",colors=led_grn} - local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,colors.gray}} - network.update(types.PANEL_LINK_STATE.DISCONNECTED) + + if color_mode == themes.COLOR_MODE.STANDARD then + local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,colors.gray}} + network.update(types.PANEL_LINK_STATE.DISCONNECTED) + network.register(ps, "link_state", network.update) + else + local nt_lnk = RGBLED{parent=system,label="NT LINKED",colors={colors.red_off,colors.red,colors.green}} + local nt_ver = RGBLED{parent=system,label="NT VERSION",colors={colors.red_off,colors.red,colors.green}} + + nt_lnk.register(ps, "link_state", function (state) + local value = 2 + + if state == LINK_STATE.DISCONNECTED then + value = 1 + elseif state == LINK_STATE.LINKED then + value = 3 + end + + nt_lnk.update(value) + end) + + nt_ver.register(ps, "link_state", function (state) + local value = 3 + + if state == LINK_STATE.BAD_VERSION then + value = 2 + elseif state == LINK_STATE.DISCONNECTED then + value = 1 + end + + nt_ver.update(value) + end) + end + system.line_break() modem.register(ps, "has_modem", modem.update) - network.register(ps, "link_state", network.update) local speaker = LED{parent=system,label="SPEAKER",colors=led_grn} speaker.register(ps, "has_speaker", speaker.update) diff --git a/coordinator/ui/style.lua b/coordinator/ui/style.lua index afa6b7b..6c91b2c 100644 --- a/coordinator/ui/style.lua +++ b/coordinator/ui/style.lua @@ -2,6 +2,8 @@ -- Graphics Style Options -- +local util = require("scada-common.util") + local core = require("graphics.core") local themes = require("graphics.themes") @@ -27,6 +29,7 @@ local smooth_stone = { label_dark = colors.gray, disabled = colors.lightGray, bg = colors.lightGray, + checkbox_bg = colors.black, accent_light = colors.white, accent_dark = colors.gray, @@ -59,6 +62,30 @@ local smooth_stone = { { c = colors.gray, hex = 0x575757 }, { c = colors.black, hex = 0x191919 }, { c = colors.brown, hex = 0x7f664c } + }, + + -- color re-mappings for assistive modes + color_modes = { + -- standard + {}, + -- deuteranopia + { + { c = colors.blue, hex = 0x1081ff }, + { c = colors.yellow, hex = 0xf7c311 }, + { c = colors.red, hex = 0xfb5615 }, + }, + -- protanopia + { + { c = colors.blue, hex = 0x1081ff }, + { c = colors.yellow, hex = 0xf5e633 }, + { c = colors.red, hex = 0xff521a }, + }, + -- tritanopia + { + { c = colors.blue, hex = 0x40cbd7 }, + { c = colors.yellow, hex = 0xffbc00 }, + { c = colors.red, hex = 0xff0000 }, + } } } @@ -70,6 +97,7 @@ local deepslate = { label_dark = colors.gray, disabled = colors.gray, bg = colors.black, + checkbox_bg = colors.gray, accent_light = colors.gray, accent_dark = colors.lightGray, @@ -102,44 +130,72 @@ local deepslate = { { c = colors.gray, hex = 0x575757 }, { c = colors.black, hex = 0x262626 }, { c = colors.brown, hex = 0xb18f6a } + }, + + -- color re-mappings for assistive modes + color_modes = { + -- standard + {}, + -- deuteranopia + { + { c = colors.blue, hex = 0x65aeff }, + { c = colors.yellow, hex = 0xf7c311 }, + { c = colors.red, hex = 0xfb5615 }, + }, + -- protanopia + { + { c = colors.blue, hex = 0x65aeff }, + { c = colors.yellow, hex = 0xf5e633 }, + { c = colors.red, hex = 0xff8058 }, + }, + -- tritanopia + { + { c = colors.blue, hex = 0x00ecff }, + { c = colors.yellow, hex = 0xffbc00 }, + { c = colors.red, hex = 0xdf4949 }, + } } } 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 +---@param colorblind boolean true if in a colorblind mode +function style.set_themes(main, fp, colorblind) + style.ind_bkg = colors.gray + + style.ind_hi_box_bg = util.trinary(colorblind, colors.black, colors.gray) + + if main == themes.UI_THEME.SMOOTH_STONE then style.theme = smooth_stone - elseif main == 2 then + style.ind_bkg = util.trinary(colorblind, colors.black, colors.gray) + elseif main == themes.UI_THEME.DEEPSLATE then style.theme = deepslate + style.ind_hi_box_bg = util.trinary(colorblind, colors.black, colors.lightGray) end 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) - if fp == 1 then + style.ind_grn = cpair(util.trinary(colorblind, colors.blue, colors.green), style.ind_bkg) + style.ind_yel = cpair(colors.yellow, style.ind_bkg) + style.ind_red = cpair(colors.red, style.ind_bkg) + style.ind_wht = cpair(colors.white, style.ind_bkg) + + if fp == themes.FP_THEME.SANDSTONE then style.fp_theme = themes.sandstone - elseif fp == 2 then + elseif fp == themes.FP_THEME.BASALT then style.fp_theme = themes.basalt end @@ -159,11 +215,6 @@ style.lg_gray = cpair(colors.lightGray, colors.gray) style.lg_white = cpair(colors.lightGray, colors.white) style.gray_white = cpair(colors.gray, colors.white) -style.ind_grn = cpair(colors.green, colors.gray) -style.ind_yel = cpair(colors.yellow, colors.gray) -style.ind_red = cpair(colors.red, colors.gray) -style.ind_wht = style.wh_gray - -- UI COMPONENTS -- style.reactor = { diff --git a/graphics/themes.lua b/graphics/themes.lua index a8376b2..5de1ae3 100644 --- a/graphics/themes.lua +++ b/graphics/themes.lua @@ -121,6 +121,7 @@ themes.sandstone = { -- deuteranopia { { c = colors.green, hex = 0x1081ff }, + { c = colors.green_hc, hex = 0x1081ff }, { c = colors.green_off, hex = 0x141414 }, { c = colors.yellow, hex = 0xf7c311 }, { c = colors.yellow_off, hex = 0x141414 }, @@ -130,6 +131,7 @@ themes.sandstone = { -- protanopia { { c = colors.green, hex = 0x1081ff }, + { c = colors.green_hc, hex = 0x1081ff }, { c = colors.green_off, hex = 0x141414 }, { c = colors.yellow, hex = 0xf5e633 }, { c = colors.yellow_off, hex = 0x141414 }, @@ -139,6 +141,7 @@ themes.sandstone = { -- tritanopia { { c = colors.green, hex = 0x40cbd7 }, + { c = colors.green_hc, hex = 0x40cbd7 }, { c = colors.green_off, hex = 0x141414 }, { c = colors.yellow, hex = 0xffbc00 }, { c = colors.yellow_off, hex = 0x141414 },