The call frame. Above the callsign box, N1MM writes which spotted station the radio is sitting on, coloured like the bandmap colours it, or CQ-Frequency when this is the frequency the last CQ went out on. Space with an empty callsign box takes the call out of the frame and into the box, but only while searching: TabPressed does that when the run box is unchecked, because a running station is answering callers rather than chasing the one under its VFO. How close counts as sitting on it is N1MM's tuning tolerance, 300 Hz, now a setting. Sh/dx while unassisted. TelnetClient.Output refuses any command holding SH/DX when the entry is not assisted, and the telnet window does the same now. Whether an entry is assisted follows N1MM's own rule: assisted, multi-operator or checklog may use spots, a single operator who did not say assisted may not. The node's flavour. Click_LogonButton reads DXSpider, AR-Cluster, CC Cluster or GoCluster out of the banner; ClusterClient reads the same words and the window shows what it found. It changes nothing yet — the commands it would change are ones this does not send — but the node says so and now we know. CQ WW RTTY's state box. NextTab only stops on SectionText when the station is US or Canadian, because nobody else sends a state, so a contest can now say a box is not for this station and the walk steps over it. The box is still there to type in. The telnet button editor shows as many buttons as are defined, with an empty row to write the next one in, rather than N1MM's twelve. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
72 lines
2.4 KiB
C#
72 lines
2.4 KiB
C#
using Avalonia.Controls;
|
|
using Avalonia.Interactivity;
|
|
using Nonemm.App.Configuration;
|
|
|
|
namespace Nonemm.App.Windows;
|
|
|
|
/// The Buttons tab: the twelve command buttons under the traffic, as N1MM's
|
|
/// telnet window has.
|
|
public sealed partial class TelnetWindow
|
|
{
|
|
/// N1MM stops at twelve buttons; this shows as many as are defined, and one
|
|
/// empty row to write the next one in.
|
|
private const int LeastButtonRows = 12;
|
|
|
|
private readonly List<(TextBox Label, TextBox Command)> buttonRows = [];
|
|
|
|
private void LoadButtonRows()
|
|
{
|
|
buttonRows.Clear();
|
|
ButtonRows.Children.Clear();
|
|
ButtonRows.RowDefinitions.Clear();
|
|
IReadOnlyList<StoredTelnetButton> stored = Buttons();
|
|
int rows = Math.Max(LeastButtonRows, stored.Count + 1);
|
|
for (int at = 0; at < rows; at++)
|
|
{
|
|
ButtonRows.RowDefinitions.Add(new RowDefinition(GridLength.Auto));
|
|
StoredTelnetButton button = at < stored.Count ? stored[at] : new StoredTelnetButton();
|
|
TextBox label = Box(at, 0, button.Label, "label");
|
|
TextBox command = Box(at, 2, button.Command, "sh/dx; sh/wwv");
|
|
buttonRows.Add((label, command));
|
|
}
|
|
}
|
|
|
|
private TextBox Box(int row, int column, string text, string placeholder)
|
|
{
|
|
TextBox box = new()
|
|
{
|
|
Text = text,
|
|
PlaceholderText = placeholder,
|
|
Margin = new Avalonia.Thickness(0, 0, 0, 4),
|
|
};
|
|
Grid.SetRow(box, row);
|
|
Grid.SetColumn(box, column);
|
|
ButtonRows.Children.Add(box);
|
|
return box;
|
|
}
|
|
|
|
private void OnSaveButtons(object? sender, RoutedEventArgs e)
|
|
{
|
|
session.Save(session.Settings with
|
|
{
|
|
TelnetButtons = [.. buttonRows
|
|
.Select(row => new StoredTelnetButton
|
|
{
|
|
Label = (row.Label.Text ?? "").Trim(),
|
|
Command = (row.Command.Text ?? "").Trim(),
|
|
})
|
|
.Where(button => button.Label.Length > 0 && button.Command.Length > 0)],
|
|
});
|
|
LoadButtons();
|
|
Show("*** buttons saved", NoticeColour);
|
|
}
|
|
|
|
private void OnResetButtons(object? sender, RoutedEventArgs e)
|
|
{
|
|
session.Save(session.Settings with { TelnetButtons = [] });
|
|
LoadButtons();
|
|
LoadButtonRows();
|
|
Show("*** buttons back to the defaults", NoticeColour);
|
|
}
|
|
}
|