using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Platform.Storage; using Nonemm.App.Configuration; namespace Nonemm.App.Dialogs; /// What the operator dialog closed with: the operator to change to, or the one /// to drop from the list. public sealed record OperatorChoice(StoredOperator Operator, bool IsRemoval); /// N1MM's Ctrl+O: who is at the radio now. It closes with the operator to /// change to, or with null when nothing is to change. An operator whose /// callsign is not in the list yet is made by typing it. public sealed partial class OperatorDialog : Window { private readonly IReadOnlyList known; public OperatorDialog(Settings settings) { known = settings.Operators; InitializeComponent(); KnownBox.ItemsSource = known.Select(o => o.Callsign).ToList(); CallBox.Text = settings.CurrentOperator; WavBox.Text = Find(settings.CurrentOperator)?.WavPath ?? ""; ShowWhatIsKept(); // the callsign is all most operators type here, so the cursor starts in // it and Enter closes the dialog Opened += (_, _) => { CallBox.Focus(); // the operator taking over types his own callsign over the one // leaving rather than clearing the box first CallBox.SelectAll(); }; } /// The operator as the dialog leaves him: the callsign typed, keeping /// whatever was stored for him before. private StoredOperator Picked { get { string callsign = (CallBox.Text ?? "").Trim().ToUpperInvariant(); StoredOperator stored = Find(callsign) ?? new StoredOperator(); return stored with { Callsign = callsign, WavPath = (WavBox.Text ?? "").Trim() }; } } private StoredOperator? Find(string callsign) => known.FirstOrDefault(o => string.Equals(o.Callsign, callsign.Trim(), StringComparison.OrdinalIgnoreCase)); private void OnPickedKnown(object? sender, SelectionChangedEventArgs e) { if (KnownBox.SelectedItem is not string callsign) { return; } CallBox.Text = callsign; WavBox.Text = Find(callsign)?.WavPath ?? ""; ShowWhatIsKept(); } private void ShowWhatIsKept() { StoredOperator? stored = Find(CallBox.Text ?? ""); AboutText.Text = stored is null ? "A new operator: the windows and colours on the screen now become his." : $"{stored.Windows.Count} window positions kept" + (stored.Theme.Length > 0 ? $", {stored.Theme} colours" : ", the colours as they are"); } private async void OnBrowseWav(object? sender, RoutedEventArgs e) { IReadOnlyList picked = await StorageProvider.OpenFolderPickerAsync( new FolderPickerOpenOptions { Title = "The operator's recordings", AllowMultiple = false }); if (picked.Count > 0) { WavBox.Text = picked[0].Path.LocalPath; } } private void OnOk(object? sender, RoutedEventArgs e) { if (Picked.Callsign.Length > 0) { Close(new OperatorChoice(Picked, IsRemoval: false)); } } /// Drops the operator from the list. The contacts he logged keep his /// callsign: they are in the log, not in the settings. private void OnRemove(object? sender, RoutedEventArgs e) { if (Find(CallBox.Text ?? "") is { } stored) { Close(new OperatorChoice(stored, IsRemoval: true)); } } private void OnCancel(object? sender, RoutedEventArgs e) => Close(null); }