Merge branch 'refactor/extract-modules'

Extract helpers out of MainForm into structured modules:
- BoardUtils: BoardTypeName, FreqToBandIdx (removes duplication with DeviceForm)
- WisdomBuilder: TWisdomBuildThread + TWisdomProgressDialog
- UISync: TDeviceFoundSync/TStatusUISync/TDDCSeqSync via callbacks
- PlatformUtils: HasOpenGLSpectrumSwitch, CurrentScreenDPI

Minor cleanup: unused local constants, stale comments in AudioOutput.
This commit is contained in:
2026-05-26 19:38:50 +03:00
8 changed files with 328 additions and 305 deletions
+2 -9
View File
@@ -186,10 +186,7 @@ const
PA_CONTINUE = LongInt(0); PA_CONTINUE = LongInt(0);
PA_NO_DEV = TPaDeviceIndex(-1); PA_NO_DEV = TPaDeviceIndex(-1);
// --------------------------------------------------------------------------- // Callback modeled after pa_out_cb from piHPSDR/portaudio.c
// Callback — точная копия pa_out_cb из оригинала
// ---------------------------------------------------------------------------
function PaOutCallback(inputBuffer, outputBuffer: Pointer; function PaOutCallback(inputBuffer, outputBuffer: Pointer;
framesPerBuffer: LongWord; framesPerBuffer: LongWord;
timeInfo: Pointer; timeInfo: Pointer;
@@ -567,11 +564,7 @@ begin
end; end;
end; end;
// --------------------------------------------------------------------------- // WriteDouble — modeled after audio_write() from piHPSDR/portaudio.c
// WriteDouble — точная копия audio_write() из оригинала
// ---------------------------------------------------------------------------
// WriteDouble — точная копия audio_write() из piHPSDR/portaudio.c
// Вызывается per-sample из Write. Мьютекс держится весь цикл в Write. // Вызывается per-sample из Write. Мьютекс держится весь цикл в Write.
procedure TAudioOutput.WriteDouble(Left, Right: Double); procedure TAudioOutput.WriteDouble(Left, Right: Double);
var var
+50
View File
@@ -0,0 +1,50 @@
unit BoardUtils;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
function BoardTypeName(BoardType: Integer): string;
function FreqToBandIdx(Hz: Double): Integer;
implementation
uses SysUtils;
function BoardTypeName(BoardType: Integer): string;
begin
case BoardType of
1: Result := 'HERMES (ANAN-10/100)';
2: Result := 'HERMES-E (ANAN-10E/100B)';
3: Result := 'ANGELIA (ANAN-100D)';
4: Result := 'ORION (ANAN-200D)';
5: Result := 'ORION MkII (ANAN-7000/8000)';
6: Result := 'HERMES-LITE 2';
10: Result := 'SATURN (G2)';
else Result := Format('Unknown Board #%d', [BoardType]);
end;
end;
function FreqToBandIdx(Hz: Double): Integer;
const
BAND_LO: array[0..10] of Double = (
1800000, 3500000, 5330000, 7000000, 10100000,
14000000, 18068000, 21000000, 24890000, 28000000, 50000000);
BAND_HI: array[0..10] of Double = (
2000000, 4000000, 5410000, 7300000, 10150000,
14350000, 18168000, 21450000, 24990000, 29700000, 54000000);
var
i: Integer;
begin
Result := -1;
for i := 0 to 10 do
if (Hz >= BAND_LO[i]) and (Hz <= BAND_HI[i]) then
begin
Result := i;
Exit;
end;
end;
end.
+2 -18
View File
@@ -6,10 +6,8 @@ interface
uses uses
Classes, SysUtils, FlatButton, FlatEdit, FlatListBox, AppTheme, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FlatButton, FlatEdit, FlatListBox, AppTheme, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls, ComCtrls, IniFiles; StdCtrls, ExtCtrls, ComCtrls, IniFiles,
BoardUtils;
// Декодирование типа платы (совпадает с MainForm.BoardTypeName)
function BoardTypeName(BoardType: Integer): string;
const const
DEVICE_CFG_FILE = 'hpsdr_devices.ini'; DEVICE_CFG_FILE = 'hpsdr_devices.ini';
@@ -114,20 +112,6 @@ type
implementation implementation
function BoardTypeName(BoardType: Integer): string;
begin
case BoardType of
1: Result := 'HERMES (ANAN-10/100)';
2: Result := 'HERMES-E (ANAN-10E/100B)';
3: Result := 'ANGELIA (ANAN-100D)';
4: Result := 'ORION (ANAN-200D)';
5: Result := 'ORION MkII (ANAN-7000/8000)';
6: Result := 'HERMES-LITE 2';
10: Result := 'SATURN (G2)';
else Result := Format('Unknown Board #%d', [BoardType]);
end;
end;
const const
CLR_BG = TColor($00121212); CLR_BG = TColor($00121212);
CLR_PANEL = TColor($001A1A1A); CLR_PANEL = TColor($001A1A1A);
+5 -277
View File
@@ -26,7 +26,6 @@ uses
FlatButton, FlatSlider, FlatDropDown, AppTheme, Forms, Controls, Graphics, Dialogs, FlatButton, FlatSlider, FlatDropDown, AppTheme, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls, Buttons, Menus, Math, Types, StdCtrls, ExtCtrls, Buttons, Menus, Math, Types,
OpenGLContext, OpenGLContext,
FlatProgressBar,
LCLIntf, LCLType, GraphType, LCLIntf, LCLType, GraphType,
HPSDRProtocol, HPSDRNetwork, HPSDRProtocol, HPSDRNetwork,
WDSP, WDSPEngine, AudioOutput, AudioInput, WDSP, WDSPEngine, AudioOutput, AudioInput,
@@ -37,7 +36,8 @@ uses
WidebandView, WidebandView,
StatusBar, StatusBar,
PlatformUtils, PlatformUtils,
WinFirewall; WinFirewall,
BoardUtils, WisdomBuilder, UISync;
const const
CLR_BG = TColor($00101010); CLR_BG = TColor($00101010);
@@ -138,45 +138,6 @@ type
Display: string; Display: string;
end; end;
// Синхронизирующий объект для OnDeviceFound
TDeviceFoundSync = class
private
FForm: TObject; // TMainForm, через forward ref
FDev: THPSDRDevice;
FEntry: string;
public
constructor Create(AForm: TObject; const D: THPSDRDevice; const E: string);
procedure Execute;
end;
// Синхронизирующий объект для HP Status
TStatusUISync = class
private
FForm: TObject;
FFwdW: Double;
FSWRV: Double;
FSupplyV: Double;
FSupplyA: Double;
FPLLLock: Boolean;
FHWPTT: Boolean;
FADCOverload: Byte;
public
constructor Create(AForm: TObject; FW, SW, SV, SA: Double; PLL, HWPTT: Boolean;
ADCOverload: Byte);
procedure Execute;
end;
// Синхронизирующий объект для DDC IQ
TDDCSeqSync = class
private
FForm: TObject;
FDDCIdx: Integer;
FSeq: LongWord;
public
constructor Create(AForm: TObject; Idx: Integer; Seq: LongWord);
procedure Execute;
end;
{ TMainForm } { TMainForm }
TMainForm = class(TForm) TMainForm = class(TForm)
private private
@@ -750,30 +711,6 @@ type
var Handled: Boolean); var Handled: Boolean);
end; end;
TWisdomBuildThread = class(TThread)
private
FDirectory: string;
FError: string;
protected
procedure Execute; override;
public
constructor Create(const ADirectory: string);
property ErrorText: string read FError;
end;
TWisdomProgressDialog = class(TForm)
private
FInfoLabel: TLabel;
FProgress: TFlatProgressBar;
FTimer: TTimer;
FThread: TWisdomBuildThread;
FPhase: Integer;
procedure TimerTick(Sender: TObject);
public
constructor Create(AOwner: TComponent; AThread: TWisdomBuildThread;
const ATheme: TAppTheme); reintroduce;
end;
var var
MainForm: TMainForm; MainForm: TMainForm;
@@ -783,20 +720,6 @@ uses SettingsForm;
{$R *.lfm} {$R *.lfm}
function HasOpenGLSpectrumSwitch: Boolean;
var
I: Integer;
S: string;
begin
Result := False;
for I := 1 to ParamCount do
begin
S := LowerCase(ParamStr(I));
if (S = '--opengl') or (S = '-opengl') or (S = '/opengl') then
Exit(True);
end;
end;
function TMainForm.LeftPanelButtonWidth(PanelWidth, ColCount, function TMainForm.LeftPanelButtonWidth(PanelWidth, ColCount,
ColIndex: Integer): Integer; ColIndex: Integer): Integer;
var var
@@ -822,179 +745,10 @@ begin
LEFT_PANEL_BTN_GAP); LEFT_PANEL_BTN_GAP);
end; end;
constructor TWisdomBuildThread.Create(const ADirectory: string);
begin
inherited Create(False);
FreeOnTerminate := False;
FDirectory := ADirectory;
FError := '';
end;
procedure TWisdomBuildThread.Execute;
var
DirA: AnsiString;
begin
try
if not Assigned(@WDSPwisdom) then Exit;
DirA := AnsiString(FDirectory);
WDSPwisdom(PAnsiChar(DirA));
except
on E: Exception do
FError := E.ClassName + ': ' + E.Message;
end;
end;
constructor TWisdomProgressDialog.Create(AOwner: TComponent;
AThread: TWisdomBuildThread; const ATheme: TAppTheme);
begin
inherited CreateNew(AOwner);
FThread := AThread;
FPhase := 0;
Caption := 'WDSP Wisdom';
Width := 520;
Height := 140;
Position := poScreenCenter;
BorderStyle := bsDialog;
BorderIcons := [];
Color := ATheme.BG;
Font.Name := 'Courier New';
Font.Size := 9;
Font.Color := ATheme.Text;
FInfoLabel := TLabel.Create(Self);
FInfoLabel.Parent := Self;
FInfoLabel.SetBounds(16, 16, 480, 40);
FInfoLabel.AutoSize := False;
FInfoLabel.WordWrap := True;
FInfoLabel.Font.Color := ATheme.Text;
FInfoLabel.Caption :=
'Creating FFTW wisdom for WDSP. This is done once and may take a while on the first run.';
FProgress := TFlatProgressBar.Create(Self);
FProgress.Parent := Self;
FProgress.SetBounds(16, 72, 480, 22);
FProgress.Min := 0;
FProgress.Max := 100;
FProgress.Position := 0;
FProgress.SetAppTheme(ATheme);
FTimer := TTimer.Create(Self);
FTimer.Interval := 250;
FTimer.OnTimer := TimerTick;
FTimer.Enabled := True;
end;
procedure TWisdomProgressDialog.TimerTick(Sender: TObject);
var
P: PAnsiChar;
S: string;
begin
FPhase := (FPhase + 7) mod 101;
FProgress.Position := FPhase;
if Assigned(@wisdom_get_status) then
begin
P := wisdom_get_status;
if P <> nil then
begin
S := Trim(string(AnsiString(P)));
if S <> '' then
FInfoLabel.Caption := S;
end;
end;
if Assigned(FThread) and FThread.Finished then
begin
FTimer.Enabled := False;
ModalResult := mrOk;
end;
end;
// ===========================================================================
// Общая функция декодирования типа платы — используется везде
// ===========================================================================
function BoardTypeName(BoardType: Integer): string;
begin
case BoardType of
1: Result := 'HERMES (ANAN-10/100)';
2: Result := 'HERMES-E (ANAN-10E/100B)';
3: Result := 'ANGELIA (ANAN-100D)';
4: Result := 'ORION (ANAN-200D)';
5: Result := 'ORION MkII (ANAN-7000/8000)';
6: Result := 'HERMES-LITE 2';
10: Result := 'SATURN (G2)';
else Result := Format('Unknown Board #%d', [BoardType]);
end;
end;
// ===========================================================================
// Sync helpers
// ===========================================================================
constructor TDeviceFoundSync.Create(AForm: TObject;
const D: THPSDRDevice; const E: string);
begin
inherited Create;
FForm := AForm;
FDev := D;
FEntry := E;
end;
procedure TDeviceFoundSync.Execute;
begin
TMainForm(FForm).DoAddDevice(FDev, FEntry);
end;
constructor TStatusUISync.Create(AForm: TObject;
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean; ADCOverload: Byte);
begin
inherited Create;
FForm := AForm;
FFwdW := FW;
FSWRV := SW;
FSupplyV := SV;
FSupplyA := SA;
FPLLLock := PLL;
FHWPTT := HWPTT;
FADCOverload := ADCOverload;
end;
procedure TStatusUISync.Execute;
begin
TMainForm(FForm).DoUpdateStatus(FFwdW, FSWRV, FSupplyV, FSupplyA, FPLLLock, FHWPTT,
FADCOverload);
end;
constructor TDDCSeqSync.Create(AForm: TObject; Idx: Integer; Seq: LongWord);
begin
inherited Create;
FForm := AForm;
FDDCIdx := Idx;
FSeq := Seq;
end;
procedure TDDCSeqSync.Execute;
begin
TMainForm(FForm).DoUpdateDDCSeqOrNoDevice(FDDCIdx, FSeq);
end;
// ===========================================================================
// FormCreate / FormDestroy
// ===========================================================================
// =========================================================================== // ===========================================================================
// Settings helpers // Settings helpers
// =========================================================================== // ===========================================================================
function CurrentScreenDPI: Integer;
begin
Result := Screen.PixelsPerInch;
if Result <= 0 then Result := 96;
end;
procedure TMainForm.RestoreWindowBounds; procedure TMainForm.RestoreWindowBounds;
var var
L, T, Wd, Ht, SavedDPI, CurDPI: Integer; L, T, Wd, Ht, SavedDPI, CurDPI: Integer;
@@ -1666,7 +1420,6 @@ const
LEFT_W = 232; LEFT_W = 232;
TOP_VFO_W = 244; TOP_VFO_W = 244;
TOP_VFO_FREQ_H = 47; TOP_VFO_FREQ_H = 47;
TOP_VFO_BTN_H = 14;
var var
i, X, Y, W: Integer; i, X, Y, W: Integer;
B: TFlatButton; B: TFlatButton;
@@ -2381,7 +2134,6 @@ const
MARGIN = 4; MARGIN = 4;
TOP_OFFSET = 2; TOP_OFFSET = 2;
TOP_VFO_FREQ_H = 47; TOP_VFO_FREQ_H = 47;
VFO_BTN_W = 20;
VFO_BTN_FREQ_GAP = 4; VFO_BTN_FREQ_GAP = 4;
VFO_FREQ_LEFT_PAD = 2; VFO_FREQ_LEFT_PAD = 2;
VFO_FREQ_RIGHT_PAD = 8; VFO_FREQ_RIGHT_PAD = 8;
@@ -3394,7 +3146,7 @@ begin
Entry := Format('%s %s FW:%d DDC:%d', Entry := Format('%s %s FW:%d DDC:%d',
[Dev.IPAddress, BoardName, [Dev.IPAddress, BoardName,
Dev.FirmwareVersion, Dev.NumDDCs]); Dev.FirmwareVersion, Dev.NumDDCs]);
Sync := TDeviceFoundSync.Create(Self, Dev, Entry); Sync := TDeviceFoundSync.Create(DoAddDevice, Dev, Entry);
try try
M := Sync.Execute; M := Sync.Execute;
TThread.Synchronize(nil, M); TThread.Synchronize(nil, M);
@@ -3483,7 +3235,7 @@ begin
end else end else
SWRV := 1.0; SWRV := 1.0;
if not IsTx then FwdW := 0; if not IsTx then FwdW := 0;
Sync := TStatusUISync.Create(Self, FwdW, SWRV, SupplyV, SupplyA, Sync := TStatusUISync.Create(DoUpdateStatus, FwdW, SWRV, SupplyV, SupplyA,
(Status.StatusBits and HPS_PLL_LOCKED) <> 0, (Status.StatusBits and HPS_PLL_LOCKED) <> 0,
(Status.StatusBits and HPS_PTT) <> 0, (Status.StatusBits and HPS_PTT) <> 0,
Status.ADCOverload); Status.ADCOverload);
@@ -3886,7 +3638,7 @@ begin
if Length(Devs) = 0 then if Length(Devs) = 0 then
begin begin
// DDCIdx = -1 is the sentinel for "no device found" // DDCIdx = -1 is the sentinel for "no device found"
Sync := TDDCSeqSync.Create(FForm, -1, 0); Sync := TDDCSeqSync.Create(FForm.DoUpdateDDCSeqOrNoDevice, -1, 0);
try try
M := Sync.Execute; M := Sync.Execute;
TThread.Synchronize(nil, M); TThread.Synchronize(nil, M);
@@ -4393,30 +4145,6 @@ end;
// Idx=0 → VFO-A активен, Idx=1 → VFO-B активен. // Idx=0 → VFO-A активен, Idx=1 → VFO-B активен.
// Перестройка всегда происходит на частоту активного VFO (не на оффсет). // Перестройка всегда происходит на частоту активного VFO (не на оффсет).
// CTUN при этом сбрасывается чтобы не было путаницы с оффсетом. // CTUN при этом сбрасывается чтобы не было путаницы с оффсетом.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// FreqToBandIdx — возвращает индекс диапазона для частоты Hz, или -1
// ---------------------------------------------------------------------------
function FreqToBandIdx(Hz: Double): Integer;
const
// Границы диапазонов [Low, High] в Гц (приблизительные)
BAND_LO: array[0..10] of Double = (
1800000, 3500000, 5330000, 7000000, 10100000,
14000000, 18068000, 21000000, 24890000, 28000000, 50000000);
BAND_HI: array[0..10] of Double = (
2000000, 4000000, 5410000, 7300000, 10150000,
14350000, 18168000, 21450000, 24990000, 29700000, 54000000);
var
i: Integer;
begin
Result := -1;
for i := 0 to 10 do
if (Hz >= BAND_LO[i]) and (Hz <= BAND_HI[i]) then
begin
Result := i;
Exit;
end;
end;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// ActiveVfoFreq — частота активного VFO // ActiveVfoFreq — частота активного VFO
+23 -1
View File
@@ -11,11 +11,13 @@ unit PlatformUtils;
interface interface
function QtPlatformAllowsOpenGLControls: Boolean; function QtPlatformAllowsOpenGLControls: Boolean;
function HasOpenGLSpectrumSwitch: Boolean;
function CurrentScreenDPI: Integer;
implementation implementation
uses uses
SysUtils; SysUtils, Forms;
function QtPlatformAllowsOpenGLControls: Boolean; function QtPlatformAllowsOpenGLControls: Boolean;
var var
@@ -39,4 +41,24 @@ begin
Result := SessionType <> 'wayland'; Result := SessionType <> 'wayland';
end; end;
function HasOpenGLSpectrumSwitch: Boolean;
var
I: Integer;
S: string;
begin
Result := False;
for I := 1 to ParamCount do
begin
S := LowerCase(ParamStr(I));
if (S = '--opengl') or (S = '-opengl') or (S = '/opengl') then
Exit(True);
end;
end;
function CurrentScreenDPI: Integer;
begin
Result := Screen.PixelsPerInch;
if Result <= 0 then Result := 96;
end;
end. end.
+105
View File
@@ -0,0 +1,105 @@
unit UISync;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
uses
Classes, HPSDRNetwork;
type
TAddDeviceProc = procedure(const Dev: THPSDRDevice; const Entry: string) of object;
TUpdateStatusProc = procedure(FwdW, SWRV, SupplyV, SupplyA: Double;
PLLLock, HWPTT: Boolean; ADCOverload: Byte) of object;
TUpdateDDCSeqOrNoDeviceProc = procedure(DDCIdx: Integer; Seq: LongWord) of object;
TDeviceFoundSync = class
private
FCallback: TAddDeviceProc;
FDev: THPSDRDevice;
FEntry: string;
public
constructor Create(ACallback: TAddDeviceProc; const D: THPSDRDevice;
const E: string);
procedure Execute;
end;
TStatusUISync = class
private
FCallback: TUpdateStatusProc;
FFwdW: Double;
FSWRV: Double;
FSupplyV: Double;
FSupplyA: Double;
FPLLLock: Boolean;
FHWPTT: Boolean;
FADCOverload: Byte;
public
constructor Create(ACallback: TUpdateStatusProc;
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean; ADCOverload: Byte);
procedure Execute;
end;
TDDCSeqSync = class
private
FCallback: TUpdateDDCSeqOrNoDeviceProc;
FDDCIdx: Integer;
FSeq: LongWord;
public
constructor Create(ACallback: TUpdateDDCSeqOrNoDeviceProc;
Idx: Integer; Seq: LongWord);
procedure Execute;
end;
implementation
constructor TDeviceFoundSync.Create(ACallback: TAddDeviceProc;
const D: THPSDRDevice; const E: string);
begin
inherited Create;
FCallback := ACallback;
FDev := D;
FEntry := E;
end;
procedure TDeviceFoundSync.Execute;
begin
FCallback(FDev, FEntry);
end;
constructor TStatusUISync.Create(ACallback: TUpdateStatusProc;
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean; ADCOverload: Byte);
begin
inherited Create;
FCallback := ACallback;
FFwdW := FW;
FSWRV := SW;
FSupplyV := SV;
FSupplyA := SA;
FPLLLock := PLL;
FHWPTT := HWPTT;
FADCOverload := ADCOverload;
end;
procedure TStatusUISync.Execute;
begin
FCallback(FFwdW, FSWRV, FSupplyV, FSupplyA, FPLLLock, FHWPTT, FADCOverload);
end;
constructor TDDCSeqSync.Create(ACallback: TUpdateDDCSeqOrNoDeviceProc;
Idx: Integer; Seq: LongWord);
begin
inherited Create;
FCallback := ACallback;
FDDCIdx := Idx;
FSeq := Seq;
end;
procedure TDDCSeqSync.Execute;
begin
FCallback(FDDCIdx, FSeq);
end;
end.
+129
View File
@@ -0,0 +1,129 @@
unit WisdomBuilder;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
uses
Classes, SysUtils, Forms, Controls, ExtCtrls, StdCtrls,
WDSP, AppTheme, FlatProgressBar;
type
TWisdomBuildThread = class(TThread)
private
FDirectory: string;
FError: string;
protected
procedure Execute; override;
public
constructor Create(const ADirectory: string);
property ErrorText: string read FError;
end;
TWisdomProgressDialog = class(TForm)
private
FInfoLabel: TLabel;
FProgress: TFlatProgressBar;
FTimer: TTimer;
FThread: TWisdomBuildThread;
FPhase: Integer;
procedure TimerTick(Sender: TObject);
public
constructor Create(AOwner: TComponent; AThread: TWisdomBuildThread;
const ATheme: TAppTheme); reintroduce;
end;
implementation
constructor TWisdomBuildThread.Create(const ADirectory: string);
begin
inherited Create(False);
FreeOnTerminate := False;
FDirectory := ADirectory;
FError := '';
end;
procedure TWisdomBuildThread.Execute;
var
DirA: AnsiString;
begin
try
if not Assigned(@WDSPwisdom) then Exit;
DirA := AnsiString(FDirectory);
WDSPwisdom(PAnsiChar(DirA));
except
on E: Exception do
FError := E.ClassName + ': ' + E.Message;
end;
end;
constructor TWisdomProgressDialog.Create(AOwner: TComponent;
AThread: TWisdomBuildThread; const ATheme: TAppTheme);
begin
inherited CreateNew(AOwner);
FThread := AThread;
FPhase := 0;
Caption := 'WDSP Wisdom';
Width := 520;
Height := 140;
Position := poScreenCenter;
BorderStyle := bsDialog;
BorderIcons := [];
Color := ATheme.BG;
Font.Name := 'Courier New';
Font.Size := 9;
Font.Color := ATheme.Text;
FInfoLabel := TLabel.Create(Self);
FInfoLabel.Parent := Self;
FInfoLabel.SetBounds(16, 16, 480, 40);
FInfoLabel.AutoSize := False;
FInfoLabel.WordWrap := True;
FInfoLabel.Font.Color := ATheme.Text;
FInfoLabel.Caption :=
'Creating FFTW wisdom for WDSP. This is done once and may take a while on the first run.';
FProgress := TFlatProgressBar.Create(Self);
FProgress.Parent := Self;
FProgress.SetBounds(16, 72, 480, 22);
FProgress.Min := 0;
FProgress.Max := 100;
FProgress.Position := 0;
FProgress.SetAppTheme(ATheme);
FTimer := TTimer.Create(Self);
FTimer.Interval := 250;
FTimer.OnTimer := TimerTick;
FTimer.Enabled := True;
end;
procedure TWisdomProgressDialog.TimerTick(Sender: TObject);
var
P: PAnsiChar;
S: string;
begin
FPhase := (FPhase + 7) mod 101;
FProgress.Position := FPhase;
if Assigned(@wisdom_get_status) then
begin
P := wisdom_get_status;
if P <> nil then
begin
S := Trim(string(AnsiString(P)));
if S <> '' then
FInfoLabel.Caption := S;
end;
end;
if Assigned(FThread) and FThread.Finished then
begin
FTimer.Enabled := False;
ModalResult := mrOk;
end;
end;
end.
+12
View File
@@ -214,6 +214,18 @@
<Filename Value="PlatformUtils.pas"/> <Filename Value="PlatformUtils.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
</Unit> </Unit>
<Unit>
<Filename Value="BoardUtils.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="WisdomBuilder.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="UISync.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit> <Unit>
<Filename Value="SpectrumViewOpengl.pas"/> <Filename Value="SpectrumViewOpengl.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>