diff options
-rwxr-xr-x | app.mjs | 196 | ||||
-rw-r--r-- | profile.yaml | 176 |
2 files changed, 227 insertions, 145 deletions
@@ -66,47 +66,28 @@ const getKeyConf = (i) => { return null; }; -const rectifyLabel = (conf) => { +const getTextStyles = (conf) => { // conf must be non-null - let text, font; - let color_bg = [], - color_fg = []; + let font; + let color_bg = []; + let color_fg = []; if (isObject(conf)) { - text = [conf.text]; - color_bg = [conf.color_bg]; - color_fg = [conf.color_fg]; - if (conf.text2 != null) { - text.push(conf.text2); - } - if (conf.text3 != null) { - text.push(conf.text3); - } - if (conf.color_bg2) { - color_bg.push(conf.color_bg2); - } - if (conf.color_fg2) { - color_fg.push(conf.color_fg2); - } - if (conf.color_bg3) { - color_bg.push(conf.color_bg3); - } - if (conf.color_fg3) { - color_fg.push(conf.color_fg3); - } - let size = [conf.size != null ? conf.size : labelSize]; - size.push(conf.size2 != null ? conf.size2 : size[0] * 0.9); - size.push(conf.size3 != null ? conf.size3 : size[1]); + const size = Array.isArray(conf.size) ? conf.size : [conf.size]; + color_bg = Array.isArray(conf.color_bg) + ? conf.color_bg + : [conf.color_bg]; + color_fg = Array.isArray(conf.color_fg) + ? conf.color_fg + : [conf.color_fg]; font = []; for (let i = 0; i < size.length; i++) { - font.push(`${size[i]}px '${labelFont}'`); + font.push(`${size[i] ? size[i] : labelSize}px '${labelFont}'`); } } else { - text = [conf.toString()]; font = [`${labelSize}px '${labelFont}'`]; } return { - text, font, color_bg, color_fg, @@ -135,7 +116,12 @@ const drawKey = async (id, conf, pressed) => { c.strokeRect(padding, padding, w - padding * 2, h - padding * 2); if (conf != null) { - drawMultiLineText(c, conf); + renderMultiLineText( + c, + getLabelText(conf), + getTextStyles(conf), + conf, + ); } // otherwise the empty key style is still drawn }); @@ -170,9 +156,8 @@ const drawSideKnobs = async (side, confs, highlight) => { h - y_padding * 2, ); if (Array.isArray(confs) && confs.length > i && confs[i] != null) { - const { text, font, color_bg, color_fg } = rectifyLabel( - confs[i], - ); + const { font, color_bg, color_fg } = getTextStyles(confs[i]); + const text = getLabelText(confs[i]); if (color_bg[0]) { c.fillStyle = color_bg[0]; c.fillRect( @@ -201,11 +186,11 @@ const drawSideKnobs = async (side, confs, highlight) => { }); }; -const drawMultiLineText = (c, conf) => { +const renderMultiLineText = (c, text, styles, conf) => { const w = c.canvas.width; const h = c.canvas.height; - const { text, font, color_fg } = rectifyLabel(conf); + const { font, color_fg } = styles; c.save(); c.font = font[0]; @@ -244,24 +229,59 @@ const drawMultiLineText = (c, conf) => { c.restore(); }; -const formatDisplayText = (formatter, values) => { - if (formatter) { - return Function( - "$d", - `"use strict"; return(\`${formatter}\`);`, - )(values); +const getLabelText = (conf) => { + let text; + if (isObject(conf)) { + text = Array.isArray(conf.label) ? conf.label : [conf.label]; + } else { + text = [conf.toString()]; } - if (isNaN(values[0])) { - return "X"; + return text; +}; + +const formatValues = (conf, values, n = 1) => { + const f = (fmt) => { + if (fmt) { + return Function("$d", `"use strict"; return(\`${fmt}\`);`)(values); + } + if (isNaN(values[0])) { + return "X"; + } + return values[0].toFixed(0).toString(); + }; + + let last; + let text = []; + const formatter = Array.isArray(conf.formatter) + ? conf.formatter + : [conf.formatter]; + for (let i = 0; i < n; i++) { + let fmt = formatter[i] || last; + text.push(f(fmt)); + last = fmt; } - return values[0].toFixed(0).toString(); + return text; }; -const formatDisplayColor = (color, values) => { - if (color) { - return Function("$d", `"use strict"; return(\`${color}\`);`)(values); +const formatColors = (color_name, conf, values, n = 1) => { + const f = (fmt, v) => { + if (fmt) { + return Function("$d", `"use strict"; return(\`${fmt}\`);`)(values); + } + return "#fff"; + }; + + let last; + let color = []; + const formatter = Array.isArray(conf[color_name]) + ? conf[color_name] + : [conf[color_name]]; + for (let i = 0; i < n; i++) { + let fmt = formatter[i] || last; + color.push(f(fmt)); + last = fmt; } - return "#fff"; + return color; }; const renderAttitudeIndicator = (c, display, values) => { @@ -381,21 +401,18 @@ const renderTextGauge = (c, display, values) => { c.strokeStyle = fg; c.lineWidth = 1; - drawMultiLineText(c, { - text: formatDisplayText(display.formatter, values), - text2: display.formatter2 - ? formatDisplayText(display.formatter2, values) - : undefined, - text3: display.formatter3 - ? formatDisplayText(display.formatter3, values) - : undefined, + const text = formatValues(display, values, display.formatter.length); + // TODO: cache this + const styles = getTextStyles({ size: display.size, - size2: display.size2, - size3: display.size3, - color_fg: formatDisplayColor(display.color_fg, values), - color_fg2: formatDisplayColor(display.color_fg2, values), - color_fg3: formatDisplayColor(display.color_fg3, values), + color_fg: formatColors( + "color_fg", + display, + values, + display.formatter.length, + ), }); + renderMultiLineText(c, text, styles, {}); }; const renderMeterGauge = (c, display, values) => { @@ -415,7 +432,7 @@ const renderMeterGauge = (c, display, values) => { reading = min; } - const text = formatDisplayText(display.formatter, values); + const text = formatValues(display, values); // draw background c.fillStyle = bg; @@ -704,7 +721,7 @@ const renderHSI = (c, display, values) => { c.lineTo(dx * f, dy * f); } - c.font = `14px '${labelFont}'`; + c.font = `16px '${labelFont}'`; c.fillText("N", -5, -0.5 * r); if (isNumber(hdg_bug)) { @@ -762,10 +779,59 @@ const renderHSI = (c, display, values) => { c.stroke(); }; +const renderBarGauge = (c, display, values) => { + const bg = "black"; + const fg = "white"; + const w = c.canvas.width; + const h = c.canvas.height; + + // draw background + c.fillStyle = bg; + c.fillRect(0, 0, w, h); + c.fillStyle = fg; + c.strokeStyle = fg; + + const slotWidth = 10; + const slotHeight = 60; + const barWidth = slotWidth * 0.6; + const barD = (slotWidth - barWidth) / 2; + + const text = formatValues(display, values, 4); + const label = getLabelText(display); + // TODO: cache this + const { font, color_fg } = getTextStyles({ + size: [12, 12, 12, 12], + color_fg: formatColors("color_fg", display, values, 4), + }); + + c.rotate(Math.PI / 2); + + let y = -(w - (slotWidth + 10) * text.length) / 2; + let x = (h - slotHeight) / 2; + for (let i = 0; i < text.length; i++) { + c.lineWidth = 1; + c.strokeRect(x, y - barWidth, slotHeight, barWidth); + const r = Math.max(Math.min(values[i], 1), 0); + c.fillStyle = color_fg[i] ? color_fg[i] : fg; + const xx = x + slotHeight * (1 - r); + c.fillRect(xx + 1, y - barWidth + 1, slotHeight * r - 1, barWidth - 1); + c.lineWidth = 2; + c.moveTo(xx + 1, y + 2); + c.lineTo(xx + 1, y - barWidth - 2); + c.stroke(); + c.fillStyle = fg; + c.font = font[i]; + const t = `${label[i]} ${text[i]}`; + c.fillText(t, x, y - slotWidth + 2); + y -= slotWidth + 10; + } +}; + const drawGauge = async (key, label, values) => { const types = { meter: renderMeterGauge, text: renderTextGauge, + bar: renderBarGauge, attitude: renderAttitudeIndicator, ias: renderIAS, alt: renderAltimeter, diff --git a/profile.yaml b/profile.yaml index 89ba690..bff7ffd 100644 --- a/profile.yaml +++ b/profile.yaml @@ -5,20 +5,20 @@ # # Page 0 - left: - - text: Thr. + - label: Thr. inc: xplane_cmd: sim/engines/throttle_up dec: xplane_cmd: sim/engines/throttle_down pressed: xplane_cmd: sim/engines/throttle_full - - text: Prop + - label: Prop color_bg: '#0000ff' inc: xplane_cmd: sim/engines/prop_up dec: xplane_cmd: sim/engines/prop_down - - text: Mix. + - label: Mix. inc: xplane_cmd: sim/engines/mixture_up dec: @@ -27,19 +27,19 @@ xplane_cmd: sim/engines/mixture_max color_bg: '#ff0000' right: - - text: HDG + - label: HDG inc: xplane_cmd: sim/GPS/g1000n1_hdg_up dec: xplane_cmd: sim/GPS/g1000n1_hdg_down pressed: xplane_cmd: sim/GPS/g1000n1_hdg_sync - - text: ALT + - label: ALT inc: xplane_cmd: sim/GPS/g1000n1_alt_inner_up dec: xplane_cmd: sim/GPS/g1000n1_alt_inner_down - - text: CRS + - label: CRS inc: xplane_cmd: sim/GPS/g1000n1_crs_up dec: @@ -48,23 +48,28 @@ xplane_cmd: sim/GPS/g1000n1_crs_sync keys: - display: - type: meter + type: bar freq: 6 source: + - xplane_dataref: sim/cockpit2/engine/actuators/throttle_ratio[0] + - xplane_dataref: sim/cockpit2/engine/actuators/prop_ratio[0] + - xplane_dataref: sim/cockpit2/engine/actuators/mixture_ratio[0] - xplane_dataref: sim/flightmodel/controls/flaprat - min: 0 - max: 1 - stops: - - color: 'gray' - value_begin: 0 - value_end: 0.2 - - color: 'gray' - value_begin: 0.4 - value_end: 0.6 - - color: 'gray' - value_begin: 0.8 - value_end: 1 - formatter: '${$d[0] != null ? ($d[0] * 100).toFixed(0) : "X"}%' + label: + - T + - P + - M + - F + formatter: + - '${$d[0] != null ? ($d[0] * 100).toFixed(0) : "X"}%' + - '${$d[1] != null ? ($d[1] * 100).toFixed(0) : "X"}%' + - '${$d[2] != null ? ($d[2] * 100).toFixed(0) : "X"}%' + - '${$d[3] != null ? ($d[3] * 100).toFixed(0) : "X"}%' + color_fg: + - white + - blue + - red + - gray - display: type: meter freq: 1, @@ -94,8 +99,9 @@ - color: 'red' value_begin: 2700 value_end: 3000 - - text: Flaps - text2: Up + - label: + - Flaps + - Up pressed: xplane_cmd: sim/flight_controls/flaps_up - display: @@ -130,8 +136,9 @@ - xplane_dataref: sim/cockpit2/gauges/indicators/altitude_ft_pilot # alt - xplane_dataref: sim/cockpit2/gauges/indicators/vvi_fpm_pilot # vs - xplane_dataref: sim/cockpit/autopilot/altitude - - text: Flaps - text2: Down + - label: + - Flaps + - Down pressed: xplane_cmd: sim/flight_controls/flaps_down - display: @@ -139,10 +146,12 @@ source: - xplane_dataref: sim/cockpit/autopilot/autopilot_state - xplane_dataref: sim/cockpit2/radios/actuators/HSI_source_select_pilot - formatter: '${($d[0] & 2) ? "HDG" : (($d[0] & 0x200) ? "NAV" : "ROL")} ${($d[0] & 0x10) ? "VS" : (($d[0] & 0x40) ? "FLC" : (($d[0] & 0x4000) ? "ALT" : "PIT"))}' - formatter2: '${$d[1] == 0 ? "NAV1" : ($d[1] == 1 ? "NAV2" : ($d[1] == 2 ? "GPS" : "X"))}' - size: 16 - size2: 16 + formatter: + - '${($d[0] & 2) ? "HDG" : (($d[0] & 0x200) ? "NAV" : "ROL")} ${($d[0] & 0x10) ? "VS" : (($d[0] & 0x40) ? "FLC" : (($d[0] & 0x4000) ? "ALT" : "PIT"))}' + - '${$d[1] == 0 ? "NAV1" : ($d[1] == 1 ? "NAV2" : ($d[1] == 2 ? "GPS" : "X"))}' + size: + - 16 + - 16 - display: type: hsi freq: 12 @@ -183,32 +192,37 @@ - xplane_dataref: sim/cockpit/radios/gps_course_degtm - xplane_dataref: sim/cockpit2/radios/actuators/nav1_obs_deg_mag_pilot - xplane_dataref: sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot - formatter: '${$d[0] != null ? $d[0].toFixed(0).padStart(3, "0") : "xxx"}' - formatter2: 'HDG ${$d[1] != null ? $d[1].toFixed(0).padStart(3, "0") : "xxx"}' - formatter3: 'CRS ${($d[2] == 2 ? $d[3] : ($d[2] == 0 ? $d[4] : ($d[2] == 1 ? $d[5] : 0))).toFixed(0).padStart(3, "0")}' - color_fg2: 'cyan' - color_fg3: '${($d[2] == 2 ? "magenta" : ($d[2] == 0 ? "#2dfe54" : ($d[2] == 1 ? "#2dfe54" : "magenta")))}' - size2: 16 - size3: 16 - - text: Brake + formatter: + - '${$d[0] != null ? $d[0].toFixed(0).padStart(3, "0") : "000"}' + - 'HDG ${$d[1] != null ? $d[1].toFixed(0).padStart(3, "0") : "000"}' + - 'CRS ${($d[2] == 2 ? $d[3] : ($d[2] == 0 ? $d[4] : ($d[2] == 1 ? $d[5] : 0))).toFixed(0).padStart(3, "0")}' + color_fg: + - white + - cyan + - '${($d[2] == 2 ? "magenta" : ($d[2] == 0 ? "#2dfe54" : ($d[2] == 1 ? "#2dfe54" : "magenta")))}' + size: + - null + - 16 + - 16 + - label: Brake pressed: xplane_cmd: sim/flight_controls/brakes_toggle_regular # Page 1 - right: - - text: HDG + - label: HDG inc: xplane_cmd: sim/GPS/g1000n1_hdg_up dec: xplane_cmd: sim/GPS/g1000n1_hdg_down pressed: xplane_cmd: sim/GPS/g1000n1_hdg_sync - - text: ALT + - label: ALT inc: xplane_cmd: sim/GPS/g1000n1_alt_inner_up dec: xplane_cmd: sim/GPS/g1000n1_alt_inner_down - - text: CRS + - label: CRS inc: xplane_cmd: sim/GPS/g1000n1_crs_up dec: @@ -216,40 +230,40 @@ pressed: xplane_cmd: sim/GPS/g1000n1_crs_sync keys: - - text: AP + - label: AP pressed: xplane_cmd: sim/GPS/g1000n1_ap - - text: FD + - label: FD pressed: xplane_cmd: sim/GPS/g1000n1_fd - - text: HDG + - label: HDG pressed: xplane_cmd: sim/GPS/g1000n1_hdg - - text: ALT + - label: ALT pressed: xplane_cmd: sim/GPS/g1000n1_alt - - text: NAV + - label: NAV pressed: xplane_cmd: sim/GPS/g1000n1_nav - - text: VNV + - label: VNV pressed: xplane_cmd: sim/GPS/g1000n1_vnv - - text: APR + - label: APR pressed: xplane_cmd: sim/GPS/g1000n1_apr - - text: BC + - label: BC pressed: xplane_cmd: sim/GPS/g1000n1_bc - - text: VS + - label: VS pressed: xplane_cmd: sim/GPS/g1000n1_vs - - text: UP + - label: UP pressed: xplane_cmd: sim/GPS/g1000n1_nose_up - - text: FLC + - label: FLC pressed: xplane_cmd: sim/GPS/g1000n1_flc - - text: DN + - label: DN pressed: xplane_cmd: sim/GPS/g1000n1_nose_down color: '#1a62fd' @@ -257,7 +271,7 @@ # Page 2 - left: # left knob labels - - text: FMS out + - label: FMS out size: 20 inc: xplane_cmd: sim/GPS/g1000n1_fms_outer_up @@ -265,7 +279,7 @@ xplane_cmd: sim/GPS/g1000n1_fms_outer_down pressed: xplane_cmd: sim/GPS/g1000n1_cursor - - text: FMS in + - label: FMS in size: 20 inc: xplane_cmd: sim/GPS/g1000n1_fms_inner_up @@ -273,14 +287,14 @@ xplane_cmd: sim/GPS/g1000n1_fms_inner_down pressed: xplane_cmd: sim/GPS/g1000n1_cursor - - text: BARO + - label: BARO inc: xplane_cmd: sim/GPS/g1000n1_baro_up dec: xplane_cmd: sim/GPS/g1000n1_baro_down right: # right knob labels - - text: FMS out + - label: FMS out size: 20 inc: xplane_cmd: sim/GPS/g1000n3_fms_outer_up @@ -288,7 +302,7 @@ xplane_cmd: sim/GPS/g1000n3_fms_outer_down pressed: xplane_cmd: sim/GPS/g1000n3_cursor - - text: FMS in + - label: FMS in size: 20 inc: xplane_cmd: sim/GPS/g1000n3_fms_inner_up @@ -299,47 +313,47 @@ - keys: # 12 touchable keys from left to right, top to bottom - - text: -D-> + - label: -D-> pressed: xplane_cmd: sim/GPS/g1000n1_direct - - text: MENU + - label: MENU pressed: xplane_cmd: sim/GPS/g1000n1_menu - - text: -D-> + - label: -D-> pressed: xplane_cmd: sim/GPS/g1000n3_direct - - text: MENU + - label: MENU pressed: xplane_cmd: sim/GPS/g1000n3_menu - - text: FPL + - label: FPL pressed: xplane_cmd: sim/GPS/g1000n1_fpl - - text: PROC + - label: PROC pressed: xplane_cmd: sim/GPS/g1000n1_proc - - text: FPL + - label: FPL pressed: xplane_cmd: sim/GPS/g1000n3_fpl - - text: PROC + - label: PROC pressed: xplane_cmd: sim/GPS/g1000n3_proc - - text: CLR + - label: CLR pressed: xplane_cmd: sim/GPS/g1000n1_clr - - text: ENT + - label: ENT pressed: xplane_cmd: sim/GPS/g1000n1_ent - - text: CLR + - label: CLR pressed: xplane_cmd: sim/GPS/g1000n3_clr - - text: ENT + - label: ENT pressed: xplane_cmd: sim/GPS/g1000n3_ent color: 'yellow' # Page 3 - left: - - text: COM in + - label: COM in size: 20 inc: xplane_cmd: sim/GPS/g1000n1_com_inner_up @@ -347,7 +361,7 @@ xplane_cmd: sim/GPS/g1000n1_com_inner_down pressed: xplane_cmd: sim/GPS/g1000n1_com12 - - text: COM out + - label: COM out size: 20 inc: xplane_cmd: sim/GPS/g1000n1_com_outer_up @@ -357,7 +371,7 @@ xplane_cmd: sim/GPS/g1000n1_com12 - '' right: - - text: NAV in + - label: NAV in size: 20 inc: xplane_cmd: sim/GPS/g1000n1_nav_inner_up @@ -365,7 +379,7 @@ xplane_cmd: sim/GPS/g1000n1_nav_inner_down pressed: xplane_cmd: sim/GPS/g1000n1_nav12 - - text: NAV out + - label: NAV out size: 20 inc: xplane_cmd: sim/GPS/g1000n1_nav_outer_up @@ -375,28 +389,30 @@ xplane_cmd: sim/GPS/g1000n1_nav12 - '' keys: - - text: <-COM + - label: <-COM pressed: xplane_cmd: sim/GPS/g1000n1_com_ff - - text: <-NAV + - label: <-NAV pressed: xplane_cmd: sim/GPS/g1000n1_nav_ff - '' - '' - - text: COM1 - text2: Mic + - label: + - COM1 + - Mic pressed: xplane_cmd: sim/audio_panel/transmit_audio_com1 - - text: COM1 + - label: COM1 pressed: xplane_cmd: sim/audio_panel/monitor_audio_com1 - '' - '' - - text: COM2 - text2: Mic + - label: + - COM2 + - Mic pressed: xplane_cmd: sim/audio_panel/transmit_audio_com2 - - text: COM2 + - label: COM2 pressed: xplane_cmd: sim/audio_panel/monitor_audio_com2 - '' |