mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
scroll freq
This commit is contained in:
@@ -478,6 +478,7 @@ type
|
||||
procedure WebOnANF(On_: Boolean);
|
||||
procedure WebOnFreqB(Hz: Double);
|
||||
procedure WebOnActiveVfo(Idx: Integer);
|
||||
procedure WebOnCenter(Hz: Double);
|
||||
// Synchronize-обёртки (выполняются в UI-потоке)
|
||||
procedure SyncWebFreq;
|
||||
procedure SyncWebMode;
|
||||
@@ -498,6 +499,7 @@ type
|
||||
procedure SyncWebANF;
|
||||
procedure SyncWebFreqB;
|
||||
procedure SyncWebActiveVfo;
|
||||
procedure SyncWebCenter;
|
||||
procedure BtnWfAGCClick(Sender: TObject);
|
||||
procedure BtnWfNFClick(Sender: TObject);
|
||||
procedure BtnHidePanelClick(Sender: TObject);
|
||||
@@ -828,6 +830,7 @@ begin
|
||||
FWebServer.OnANF := WebOnANF;
|
||||
FWebServer.OnFreqB := WebOnFreqB;
|
||||
FWebServer.OnActiveVfo := WebOnActiveVfo;
|
||||
FWebServer.OnCenter := WebOnCenter;
|
||||
FWebServer.Start;
|
||||
FSMeterPeak := -130;
|
||||
FSMeterMin := -130;
|
||||
@@ -4755,6 +4758,30 @@ begin
|
||||
ActivateVfo(FWebSyncInt);
|
||||
end;
|
||||
|
||||
// ── CTUN drag center scroll (из веба) ────────────────────────────────────
|
||||
|
||||
procedure TMainForm.WebOnCenter(Hz: Double);
|
||||
begin
|
||||
FWebSyncFreq := Hz;
|
||||
FWebSyncM := SyncWebCenter;
|
||||
TThread.Synchronize(nil, FWebSyncM);
|
||||
end;
|
||||
|
||||
procedure TMainForm.SyncWebCenter;
|
||||
begin
|
||||
// Сдвигаем DDC-центр без смены VFO (аналог CTUN-drag в десктопе)
|
||||
FCenterFreq := FWebSyncFreq;
|
||||
if FWDSPReady then
|
||||
begin
|
||||
if FActiveVfo = 0 then FDSPEngine.SetShift(FVfoA - FCenterFreq)
|
||||
else FDSPEngine.SetShift(FVfoB - FCenterFreq);
|
||||
end;
|
||||
if FNetwork.Connected and FNetwork.Running then
|
||||
FNetwork.UpdateState(FCenterFreq, FCenterFreq, FDriveLevel, FTransmitting, True, True);
|
||||
FRulerLastFreq := -1.0; FRulerLastVfo := -1.0;
|
||||
FSpectrumDirty := True;
|
||||
end;
|
||||
|
||||
procedure TMainForm.TrkDriveChange(Sender: TObject);
|
||||
begin
|
||||
FDriveLevel := Round(TrkDrive.Position / 100.0 * 255);
|
||||
|
||||
+47
-4
@@ -449,10 +449,53 @@ begin
|
||||
'cv.addEventListener("contextmenu",e=>e.preventDefault());' +
|
||||
'cv.addEventListener("mouseenter",()=>{wTarget=cv.id;});' +
|
||||
'cv.addEventListener("wheel",wh,{passive:false,capture:true});' +
|
||||
'cv.addEventListener("mousedown",e=>{audioKick();wTarget=cv.id;if(e.button===2){markerOn=Math.abs(markerX-e.offsetX)>=8||!markerOn;markerX=e.offsetX;return;}if(e.button!==0)return;dragging=true;dragX0=e.offsetX;dragCen0=cur.center_hz||0;dragVfo0=activeVfoHz();dragMs=0;});' +
|
||||
'cv.addEventListener("mousemove",e=>{wTarget=cv.id;hoverX=e.offsetX;if(markerOn)markerX=e.offsetX;if(!dragging)return;const n=Date.now();if(n-dragMs<35)return;dragMs=n;const dHz=(e.offsetX-dragX0)/Math.max(1,cv.clientWidth)*(cur.span_hz||0);if(cur.ctun)ws2({cmd:"freq",hz:Math.round(dragCen0-dHz)});else{const nf=cl(Math.round(dragVfo0-dHz),30000,60000000);setActiveVfoHz(nf);if(activeVfo==="A")cur.vfo_a_hz=nf;else cur.vfo_b_hz=nf;renderVfos();pend("freq");ws2({cmd:"freq",hz:nf});}});' +
|
||||
'cv.addEventListener("mouseup",e=>{if(e.button===2)return;if(Math.abs(e.offsetX-dragX0)<4){const nf=cl(Math.round(xToHz(e.offsetX,cv.clientWidth)/100)*100,30000,60000000);setActiveVfoHz(nf);if(activeVfo==="A")cur.vfo_a_hz=nf;else cur.vfo_b_hz=nf;renderVfos();pend("freq");ws2({cmd:"freq",hz:nf});}dragging=false;});' +
|
||||
'cv.addEventListener("mouseleave",()=>{if(!markerOn)hoverX=-1;wTarget="";dragging=false;});}' +
|
||||
'cv.addEventListener("mousedown",e=>{' +
|
||||
'audioKick();wTarget=cv.id;' +
|
||||
'if(e.button===2){markerOn=Math.abs(markerX-e.offsetX)>=8||!markerOn;markerX=e.offsetX;return;}' +
|
||||
'if(e.button!==0)return;' +
|
||||
'dragging=true;dragX0=e.offsetX;' +
|
||||
// CTUN ON: drag scrolls the spectrum window (center moves, VFO stays)
|
||||
// CTUN OFF: drag moves active VFO (and center follows it)
|
||||
'dragCen0=cur.center_hz||activeVfoHz();' +
|
||||
'dragVfo0=activeVfoHz();' +
|
||||
'dragMs=0;' +
|
||||
'cv.style.cursor="ew-resize";' +
|
||||
'});' +
|
||||
'cv.addEventListener("mousemove",e=>{' +
|
||||
'wTarget=cv.id;hoverX=e.offsetX;' +
|
||||
'if(markerOn&&!dragging)markerX=e.offsetX;' +
|
||||
'if(!dragging)return;' +
|
||||
'const n=Date.now();if(n-dragMs<16)return;dragMs=n;' +
|
||||
'const span=cur.span_hz||192000;' +
|
||||
'const dHz=(e.offsetX-dragX0)/Math.max(1,cv.clientWidth)*span;' +
|
||||
'if(cur.ctun){' +
|
||||
// CTUN ON: move DDC center window, VFO marker moves on screen
|
||||
'const newCen=Math.round(dragCen0-dHz);' +
|
||||
'cur.center_hz=newCen;' +
|
||||
'ws2({cmd:"set_center",hz:newCen});'
|
||||
+ '} else {' +
|
||||
// CTUN OFF: move active VFO, center follows → update center_hz locally
|
||||
'const nf=cl(Math.round(dragVfo0-dHz),30000,60000000);' +
|
||||
'setActiveVfoHz(nf);' +
|
||||
// Optimistically update center so ruler/filter band stay in sync while dragging
|
||||
'cur.center_hz=nf;' +
|
||||
'if(activeVfo==="A"){cur.vfo_a_hz=nf;}else{cur.vfo_b_hz=nf;}' +
|
||||
'renderVfos();pend("freq");ws2({cmd:"freq",hz:nf});' +
|
||||
'}' +
|
||||
'});' +
|
||||
'cv.addEventListener("mouseup",e=>{' +
|
||||
'cv.style.cursor="";' +
|
||||
'if(e.button===2)return;' +
|
||||
'if(dragging&&Math.abs(e.offsetX-dragX0)<4){' +
|
||||
// Click (no drag): tune active VFO to clicked frequency
|
||||
'const nf=cl(Math.round(xToHz(e.offsetX,cv.clientWidth)/100)*100,30000,60000000);' +
|
||||
'setActiveVfoHz(nf);cur.center_hz=nf;' +
|
||||
'if(activeVfo==="A")cur.vfo_a_hz=nf;else cur.vfo_b_hz=nf;' +
|
||||
'renderVfos();pend("freq");ws2({cmd:"freq",hz:nf});' +
|
||||
'}' +
|
||||
'dragging=false;' +
|
||||
'});' +
|
||||
'cv.addEventListener("mouseleave",()=>{cv.style.cursor="";if(!markerOn)hoverX=-1;wTarget="";dragging=false;});}' +
|
||||
'bindCv(specCv);bindCv(wfCv);' +
|
||||
'window.addEventListener("wheel",e=>{if(e.target?.closest?.(".vfo-ro"))return;if(!wTarget){if(e.target===specCv)wTarget="spec";else if(e.target===wfCv)wTarget="wf";}if(wTarget)doWheel(e);},{passive:false,capture:true});' +
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ type
|
||||
TWebCmdANF = procedure(On_: Boolean) of object;
|
||||
TWebCmdFreqB = procedure(Hz: Double) of object;
|
||||
TWebCmdActiveVfo = procedure(Idx: Integer) of object;
|
||||
TWebCmdCenter = procedure(Hz: Double) of object;
|
||||
|
||||
// ── Главный класс сервера ─────────────────────────────────────────────────
|
||||
TWebServer = class
|
||||
@@ -202,6 +203,7 @@ type
|
||||
FOnANF: TWebCmdANF;
|
||||
FOnFreqB: TWebCmdFreqB;
|
||||
FOnActiveVfo: TWebCmdActiveVfo;
|
||||
FOnCenter: TWebCmdCenter;
|
||||
|
||||
FWebClientActive: Boolean;
|
||||
|
||||
@@ -267,6 +269,7 @@ type
|
||||
property OnANF: TWebCmdANF read FOnANF write FOnANF;
|
||||
property OnFreqB: TWebCmdFreqB read FOnFreqB write FOnFreqB;
|
||||
property OnActiveVfo: TWebCmdActiveVfo read FOnActiveVfo write FOnActiveVfo;
|
||||
property OnCenter: TWebCmdCenter read FOnCenter write FOnCenter;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@@ -972,6 +975,12 @@ begin
|
||||
if ModeValue > 1 then ModeValue := 1;
|
||||
FStateLock.Enter; FActiveVfo := ModeValue; FStateLock.Leave;
|
||||
if Assigned(FOnActiveVfo) then FOnActiveVfo(ModeValue);
|
||||
end
|
||||
else if Cmd = 'set_center' then
|
||||
begin
|
||||
HzF := JsonGetFloat(Json, 'hz', FCenterHz);
|
||||
FStateLock.Enter; FCenterHz := HzF; FStateLock.Leave;
|
||||
if Assigned(FOnCenter) then FOnCenter(HzF);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user