v0.4: persistent config in AppData, voices in LOCALAPPDATA, remove Speak button
This commit is contained in:
+55
-11
@@ -10,8 +10,9 @@ namespace Robovoice.App;
|
||||
|
||||
internal sealed partial class MainForm : Form
|
||||
{
|
||||
private readonly string _voicesDir = @"C:\data\opencode\robovoice-voices";
|
||||
private readonly string _voicesDir = AppConfig.VoicesDir;
|
||||
private readonly string _espeakDataPath;
|
||||
private readonly AppConfig _config;
|
||||
|
||||
private LibPiperTtsEngine? _tts;
|
||||
private AudioOutput? _audioOutput;
|
||||
@@ -25,21 +26,40 @@ internal sealed partial class MainForm : Form
|
||||
{
|
||||
InitializeComponent();
|
||||
_espeakDataPath = Path.Combine(AppContext.BaseDirectory, "espeak-ng-data");
|
||||
_config = AppConfig.Load();
|
||||
Directory.CreateDirectory(AppConfig.AppDataDir);
|
||||
Directory.CreateDirectory(_voicesDir);
|
||||
Load += OnLoad;
|
||||
FormClosing += OnFormClosing;
|
||||
}
|
||||
|
||||
private async void OnLoad(object? sender, EventArgs e)
|
||||
{
|
||||
ActiveControl = txtLog;
|
||||
PopulateVoices();
|
||||
PopulateOutputDevices();
|
||||
|
||||
_pttKey = Keys.F8;
|
||||
_pttKey = (Keys)_config.PttKey;
|
||||
if (_pttKey == Keys.None)
|
||||
_pttKey = Keys.F8;
|
||||
txtPttKey.Text = KeyToDisplayString(_pttKey);
|
||||
if (cmbVoice.Items.Count > 0)
|
||||
|
||||
if (!string.IsNullOrEmpty(_config.Voice) && cmbVoice.Items.Contains(_config.Voice))
|
||||
cmbVoice.SelectedItem = _config.Voice;
|
||||
else if (cmbVoice.Items.Count > 0)
|
||||
cmbVoice.SelectedIndex = 0;
|
||||
|
||||
AutoSelectCableOutput();
|
||||
if (!string.IsNullOrEmpty(_config.OutputDevice) && cmbOutput.Items.Contains(_config.OutputDevice))
|
||||
cmbOutput.SelectedItem = _config.OutputDevice;
|
||||
else
|
||||
AutoSelectCableOutput();
|
||||
|
||||
trkNoise.Value = _config.NoiseScale;
|
||||
trkSpeed.Value = _config.LengthScale;
|
||||
trkNoiseW.Value = _config.NoiseWScale;
|
||||
OnSliderScroll(null, EventArgs.Empty);
|
||||
|
||||
chkMinimizeToTray.Checked = _config.MinimizeToTray;
|
||||
|
||||
btnBrowseFile.Click += OnBrowseFile;
|
||||
btnTestVoice.Click += OnTestVoice;
|
||||
@@ -57,6 +77,10 @@ internal sealed partial class MainForm : Form
|
||||
trkSpeed.MouseUp += OnSliderReleased;
|
||||
trkNoiseW.MouseUp += OnSliderReleased;
|
||||
|
||||
chkMinimizeToTray.CheckedChanged += (_, _) => SaveConfig();
|
||||
|
||||
Resize += OnResize;
|
||||
|
||||
SetupTray();
|
||||
|
||||
await InitializeEngineAsync();
|
||||
@@ -98,6 +122,7 @@ internal sealed partial class MainForm : Form
|
||||
_captureHook?.Dispose();
|
||||
_captureHook = null;
|
||||
SetupHotkey();
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void CancelCapture()
|
||||
@@ -334,6 +359,7 @@ internal sealed partial class MainForm : Form
|
||||
cmbVoice.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
SaveConfig();
|
||||
_ = InitializeEngineAsync();
|
||||
}
|
||||
|
||||
@@ -344,6 +370,7 @@ internal sealed partial class MainForm : Form
|
||||
|
||||
if (cmbVoice.SelectedItem is string name)
|
||||
{
|
||||
SaveConfig();
|
||||
_ = ReinitializeEngineAsync(name);
|
||||
}
|
||||
}
|
||||
@@ -368,6 +395,7 @@ internal sealed partial class MainForm : Form
|
||||
|
||||
private void OnSliderReleased(object? sender, MouseEventArgs e)
|
||||
{
|
||||
SaveConfig();
|
||||
if (cmbVoice.SelectedItem is string name && VoiceCatalogue.IsVoiceInstalled(_voicesDir, name))
|
||||
{
|
||||
_ = InitializeEngineAsync();
|
||||
@@ -379,6 +407,7 @@ internal sealed partial class MainForm : Form
|
||||
if (_orchestrator is not null)
|
||||
_orchestrator.OutputDeviceName = cmbOutput.SelectedItem as string ?? string.Empty;
|
||||
Log($"Output device: {_orchestrator?.OutputDeviceName}");
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void UpdateLineStatus()
|
||||
@@ -415,6 +444,15 @@ internal sealed partial class MainForm : Form
|
||||
_trayIcon.DoubleClick += (_, _) => ShowWindow();
|
||||
}
|
||||
|
||||
private void OnResize(object? sender, EventArgs e)
|
||||
{
|
||||
if (WindowState == FormWindowState.Minimized && chkMinimizeToTray.Checked)
|
||||
{
|
||||
Hide();
|
||||
WindowState = FormWindowState.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowWindow()
|
||||
{
|
||||
Show();
|
||||
@@ -422,6 +460,18 @@ internal sealed partial class MainForm : Form
|
||||
Activate();
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
_config.Voice = cmbVoice.SelectedItem as string ?? string.Empty;
|
||||
_config.PttKey = (int)_pttKey;
|
||||
_config.OutputDevice = cmbOutput.SelectedItem as string ?? string.Empty;
|
||||
_config.NoiseScale = trkNoise.Value;
|
||||
_config.LengthScale = trkSpeed.Value;
|
||||
_config.NoiseWScale = trkNoiseW.Value;
|
||||
_config.MinimizeToTray = chkMinimizeToTray.Checked;
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
private void Log(string message)
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
@@ -438,15 +488,9 @@ internal sealed partial class MainForm : Form
|
||||
|
||||
private void OnFormClosing(object? sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (e.CloseReason == CloseReason.UserClosing && chkMinimizeToTray.Checked && _trayIcon?.Visible == true)
|
||||
{
|
||||
e.Cancel = true;
|
||||
Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
_pttHotkey?.Dispose();
|
||||
_trayIcon!.Visible = false;
|
||||
_orchestrator?.DisposeAsync().AsTask().Wait();
|
||||
SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user