add trancverter

This commit is contained in:
2026-05-14 20:24:50 +03:00
parent aea9f02df8
commit 020b9422e0
6 changed files with 1083 additions and 66 deletions
+25 -2
View File
@@ -374,8 +374,21 @@ begin
'const BAND_N=["160m","80m","60m","40m","30m","20m","17m","15m","12m","10m","6m"];' +
'const BAND_F=[1900000,3750000,5357000,7100000,10125000,14200000,18120000,21200000,24940000,28500000,50150000];' +
'(function(){const s=q("bandSel");BAND_N.forEach((n,i)=>{const o=document.createElement("option");o.value=i;o.textContent=n;s.appendChild(o);});s.onchange=()=>ws2({cmd:"band",idx:+s.value});})();' +
'function updBand(vfo){let bi=0,bd=1e15;BAND_F.forEach((f,i)=>{const d=Math.abs((vfo||0)-f);if(d<bd){bd=d;bi=i;}});q("bandSel").value=bi;}' +
// XVTR-band list, обновляется из state ("xvtr_bands":[{idx,name},...]).
// Активное значение — "xvtr_current" (-1 = HF). В <select> используем
// значения "h<n>" для HF и "x<idx>" для XVTR, чтобы различать.
'let XVTR_BANDS=[];let XVTR_CUR=-1;' +
'function rebuildBandSel(){const s=q("bandSel");if(!s)return;' +
'const saved=s.value;s.innerHTML="";' +
'BAND_N.forEach((n,i)=>{const o=document.createElement("option");o.value="h"+i;o.textContent=n;s.appendChild(o);});' +
'XVTR_BANDS.forEach(xb=>{const o=document.createElement("option");o.value="x"+xb.idx;o.textContent=xb.name||("X"+(xb.idx+1));s.appendChild(o);});' +
// Восстановить выбор: предпочитаем "current XVTR"; иначе сохраним прежнее
'if(XVTR_CUR>=0)s.value="x"+XVTR_CUR; else if(saved)s.value=saved;' +
'}' +
'(function(){const s=q("bandSel");BAND_N.forEach((n,i)=>{const o=document.createElement("option");o.value="h"+i;o.textContent=n;s.appendChild(o);});' +
's.onchange=()=>{const v=s.value;if(!v)return;if(v[0]==="x")ws2({cmd:"xvtr_band",idx:+v.slice(1)});else if(v[0]==="h")ws2({cmd:"band",idx:+v.slice(1)});};' +
'})();' +
'function updBand(vfo){if(XVTR_CUR>=0){q("bandSel").value="x"+XVTR_CUR;return;}let bi=0,bd=1e15;BAND_F.forEach((f,i)=>{const d=Math.abs((vfo||0)-f);if(d<bd){bd=d;bi=i;}});q("bandSel").value="h"+bi;}' +
'let smAvg=-130,smPeak=-130,smMin=-130;' +
'function dbToX(db,bx,bw){const DB_MIN=-127,DB_MAX=-13;return Math.max(bx,Math.min(bx+bw,Math.round(bx+(db-DB_MIN)/(DB_MAX-DB_MIN)*bw)));}' +
@@ -438,6 +451,16 @@ begin
'function applyState(msg){' +
'Object.keys(msg).forEach(function(k){var pk=PEND_MAP[k];if(!pk||!isPending(pk))cur[k]=msg[k];});' +
// Перестраиваем bandSel если изменился список XVTR или текущий индекс
'if(msg.xvtr_bands!=null||msg.xvtr_current!=null){' +
'const newBands=msg.xvtr_bands||XVTR_BANDS;' +
'const newCur=(msg.xvtr_current!=null)?msg.xvtr_current:XVTR_CUR;' +
'const bandsChanged=JSON.stringify(newBands)!==JSON.stringify(XVTR_BANDS);' +
'const curChanged=newCur!==XVTR_CUR;' +
'XVTR_BANDS=newBands;XVTR_CUR=newCur;' +
'if(bandsChanged)rebuildBandSel();' +
'else if(curChanged){const s=q("bandSel");if(s&&XVTR_CUR>=0)s.value="x"+XVTR_CUR;}' +
'}' +
// Обновляем localCenter/localSpan из сервера только когда пользователь не тянет
'if(!dragging&&Date.now()-wheelActiveTs>300){' +
// В CTUN без DUP: TX-спектр WDSP центрирован по vfo_a_hz, а не по DDC LO.