Add the button row and the title bar N1MM has
The title bar said Nonemm. It now says what N1MM's says: the frequency, the mode, whether the frequency came from a radio or was typed, and which radio the window belongs to when there are two. Reading it off the taskbar is the point. Under the function keys is N1MM's second row: Esc: Stop, Wipe, Log It, Edit, Spot It and QRZ. Each one does what its key already did, so the keys and the buttons cannot disagree. QRZ opens the callsign's page in a browser, and says so in the status line when there is no browser to open. Mark and Store are left out. They stack callsigns, and call stacking is not here, so a button that did nothing would be worse than no button. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -90,7 +90,17 @@
|
||||
|
||||
<Border DockPanel.Dock="Bottom" Padding="6,4" BorderThickness="0,1,0,0"
|
||||
BorderBrush="#33808080">
|
||||
<WrapPanel Name="FunctionKeys" />
|
||||
<StackPanel Spacing="4">
|
||||
<WrapPanel Name="FunctionKeys" />
|
||||
<WrapPanel>
|
||||
<Button Classes="fkey" Content="Esc: Stop" Click="OnStopSending" />
|
||||
<Button Classes="fkey" Content="Wipe" Click="OnWipe" />
|
||||
<Button Classes="fkey" Content="Log It" Click="OnLogIt" />
|
||||
<Button Classes="fkey" Content="Edit" Click="OnEditLastContact" />
|
||||
<Button Classes="fkey" Content="Spot It" Click="OnSpotIt" />
|
||||
<Button Classes="fkey" Content="QRZ" Click="OnLookUpCall" />
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border DockPanel.Dock="Left" Padding="6,6,4,6" BorderThickness="0,0,1,0"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
@@ -45,7 +46,6 @@ public sealed partial class EntryWindow : Window
|
||||
Opened += (_, _) => Reopen();
|
||||
if (radioNumber > 1)
|
||||
{
|
||||
Title = "Nonemm — radio 2";
|
||||
MainMenu.IsVisible = false;
|
||||
}
|
||||
AddHandler(KeyDownEvent, OnWindowKeyDown, RoutingStrategies.Tunnel);
|
||||
@@ -97,7 +97,6 @@ public sealed partial class EntryWindow : Window
|
||||
bool wanted = session.Positions.Count > 1;
|
||||
if (wanted && secondRadio is null)
|
||||
{
|
||||
Title = "Nonemm — radio 1";
|
||||
secondRadio = new EntryWindow(session, 2);
|
||||
secondRadio.Closed += (_, _) => secondRadio = null;
|
||||
secondRadio.Show(this);
|
||||
@@ -370,6 +369,51 @@ public sealed partial class EntryWindow : Window
|
||||
|
||||
private bool FocusedIsEntryBox() => boxes.Any(b => b.IsFocused);
|
||||
|
||||
/// The buttons N1MM puts under its function keys. Each one does what its
|
||||
/// key does, so there is one place deciding what happens.
|
||||
private void OnStopSending(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
session.Alternating?.Stop();
|
||||
_ = session.Keyer?.AbortAsync();
|
||||
Status("stopped sending");
|
||||
}
|
||||
|
||||
private void OnWipe(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Logging is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Logging.Wipe();
|
||||
ResetEsm();
|
||||
SyncBoxes();
|
||||
boxes[0].Focus();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void OnLogIt(object? sender, RoutedEventArgs e) => LogContact();
|
||||
|
||||
/// Opens the callsign's page in a browser, as N1MM's QRZ button does.
|
||||
private void OnLookUpCall(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Logging is null || Logging.Entry.Call.Trim() is not { Length: > 0 } call)
|
||||
{
|
||||
Status("no callsign to look up");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo($"https://www.qrz.com/db/{call}")
|
||||
{
|
||||
UseShellExecute = true,
|
||||
});
|
||||
}
|
||||
catch (Exception error) when (error is System.ComponentModel.Win32Exception or IOException)
|
||||
{
|
||||
Status($"could not open a browser: {error.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleRun()
|
||||
{
|
||||
if (Logging is null)
|
||||
@@ -411,6 +455,7 @@ public sealed partial class EntryWindow : Window
|
||||
RunBorder.Background = Logging.IsRunning ? Verdicts.Worth : new SolidColorBrush(Color.FromArgb(0x22, 0x80, 0x80, 0x80));
|
||||
ContestText.Text = ContestLine();
|
||||
|
||||
Title = TitleLine();
|
||||
PathText.Text = PathLine();
|
||||
|
||||
Verdict? verdict = Logging.Verdict();
|
||||
@@ -438,6 +483,22 @@ public sealed partial class EntryWindow : Window
|
||||
$"{Logging.Log.Tally.Points} pts · {mults} · {Logging.Log.TotalScore:N0}{radio}";
|
||||
}
|
||||
|
||||
/// What N1MM writes in its title bar: the frequency, the mode, whether the
|
||||
/// frequency came from a radio or was typed, and which radio this window
|
||||
/// is.
|
||||
private string TitleLine()
|
||||
{
|
||||
if (Logging is null)
|
||||
{
|
||||
return "Nonemm";
|
||||
}
|
||||
string source = session.Radios.Any(r => r.Number == radioNumber && r.IsConnected)
|
||||
? "rigctld"
|
||||
: "manual";
|
||||
string radio = session.Positions.Count > 1 ? $" — radio {radioNumber}" : "";
|
||||
return $"{Logging.Frequency.Kilohertz:0.00} {Logging.Mode.Name} {source}{radio}";
|
||||
}
|
||||
|
||||
/// Where the station being worked is: the beam heading, the heading the
|
||||
/// long way round, the distance, and the sun there. N1MM writes the same
|
||||
/// line under its entry window.
|
||||
|
||||
Reference in New Issue
Block a user