Colour the callsign the way N1MM colours it, and mark the call
The colours are N1MM's own defaults, read out of ApplicationStyles: blue for a station worth working, red for one new multiplier, green for more than one, grey for a dupe, and red on the CQ frequency line. A call under three characters stays blue, as N1MM leaves it. The mark at the right-hand end of the callsign box is N1MM's OKCall: a tick when the call is in MASTER.SCP, a question mark while it is not, in the colour of the call. Like N1MM it only shows while the check window is open, for three characters or more, and only while the call is short enough to leave room for it. The band under the boxes takes N1MM's background colours instead of white on the text colours. The two lights, the telnet window and the message editor were borrowing the verdict brushes for things that are not verdicts; they have their own colours now. The callsign and the exchange boxes uppercase what is typed. Name and comment do not, which is what N1MM does. Scored contest 63 of om5m.s3db (CQ WW SSB, 3775 QSOs) against the points and multiplier flags N1MM stored: points identical, multipliers 601 against 602. The difference is B1Z on 10m, which N1MM logged with an empty country prefix and counted as a country of its own though BY was already worked on that band. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,10 +24,15 @@ public sealed partial class EntryWindow : Window
|
||||
|
||||
private static readonly IBrush Dark = new SolidColorBrush(Color.FromArgb(0x33, 0x80, 0x80, 0x80));
|
||||
|
||||
private static readonly IBrush GreenLight = new SolidColorBrush(Color.FromRgb(0x0D, 0x9D, 0x0D));
|
||||
|
||||
private static readonly IBrush RedLight = new SolidColorBrush(Color.FromRgb(0xFF, 0x00, 0x00));
|
||||
|
||||
/// The pale yellow N1MM paints the entry boxes while quick editing.
|
||||
private static readonly IBrush QuickEditBackground = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xC0));
|
||||
|
||||
private bool sending;
|
||||
private TextBlock? callMark;
|
||||
private TextBox? nameBox;
|
||||
private TextBox? commentBox;
|
||||
private readonly DispatcherTimer clock = new() { Interval = TimeSpan.FromSeconds(1) };
|
||||
@@ -176,6 +181,7 @@ public sealed partial class EntryWindow : Window
|
||||
EntryGrid.Children.Clear();
|
||||
EntryGrid.ColumnDefinitions.Clear();
|
||||
boxes.Clear();
|
||||
callMark = null;
|
||||
if (Logging is null)
|
||||
{
|
||||
ContestText.Text = "no contest — File ▸ New Contest";
|
||||
@@ -260,6 +266,29 @@ public sealed partial class EntryWindow : Window
|
||||
Grid.SetRow(box, 1);
|
||||
EntryGrid.Children.Add(box);
|
||||
boxes.Add(box);
|
||||
if (index == 0)
|
||||
{
|
||||
AddCallMark(index);
|
||||
}
|
||||
}
|
||||
|
||||
/// The mark N1MM puts at the right-hand end of the callsign box: a tick
|
||||
/// when the call is in the check partial file, a question mark while it is
|
||||
/// not. It sits over the box, in the same colour as the call.
|
||||
private void AddCallMark(int index)
|
||||
{
|
||||
callMark = new TextBlock
|
||||
{
|
||||
FontSize = 21,
|
||||
FontWeight = FontWeight.Bold,
|
||||
Margin = new Avalonia.Thickness(0, 0, 12, 0),
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
IsHitTestVisible = false,
|
||||
};
|
||||
Grid.SetColumn(callMark, index);
|
||||
Grid.SetRow(callMark, 1);
|
||||
EntryGrid.Children.Add(callMark);
|
||||
}
|
||||
|
||||
private void OnBoxChanged(int index, TextBox box)
|
||||
@@ -268,7 +297,19 @@ public sealed partial class EntryWindow : Window
|
||||
{
|
||||
return;
|
||||
}
|
||||
Logging.Entry[index] = box.Text ?? "";
|
||||
// the callsign and the exchange go out in upper case, and N1MM puts
|
||||
// them in the box that way as they are typed
|
||||
string typed = box.Text ?? "";
|
||||
string upper = typed.ToUpperInvariant();
|
||||
if (upper != typed)
|
||||
{
|
||||
int caret = box.CaretIndex;
|
||||
updating = true;
|
||||
box.Text = upper;
|
||||
box.CaretIndex = caret;
|
||||
updating = false;
|
||||
}
|
||||
Logging.Entry[index] = upper;
|
||||
if (index == 0 && Logging.Entry.Call.Trim().Length == 0)
|
||||
{
|
||||
ResetEsm();
|
||||
@@ -675,15 +716,51 @@ public sealed partial class EntryWindow : Window
|
||||
ShowLights();
|
||||
|
||||
Verdict? verdict = Logging.Verdict();
|
||||
VerdictBorder.Background = Verdicts.Colour(verdict);
|
||||
ShowCallColour(verdict);
|
||||
VerdictBorder.Background = Verdicts.Background(verdict);
|
||||
VerdictText.Text = VerdictLine(verdict);
|
||||
VerdictText.Foreground = Brushes.White;
|
||||
VerdictText.Foreground = Brushes.Black;
|
||||
foreach (Window window in openWindows.Values)
|
||||
{
|
||||
(window as RefreshableWindow)?.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// N1MM colours the callsign itself rather than the box: blue for a station
|
||||
/// worth working, red for one multiplier, green for more than one, grey for
|
||||
/// a dupe. A call too short to judge stays blue.
|
||||
private void ShowCallColour(Verdict? verdict)
|
||||
{
|
||||
if (Logging is null || boxes.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
string call = Logging.Entry.Call.Trim();
|
||||
IBrush colour = call.Length < 3 || call.All(char.IsAsciiDigit)
|
||||
? Verdicts.Worth
|
||||
: Verdicts.Colour(verdict);
|
||||
boxes[0].Foreground = colour;
|
||||
ShowCallMark(call, colour);
|
||||
}
|
||||
|
||||
/// The tick and the question mark, which N1MM only shows while the check
|
||||
/// window is open, and only while the call is short enough to leave room
|
||||
/// for them.
|
||||
private void ShowCallMark(string call, IBrush colour)
|
||||
{
|
||||
if (callMark is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool known = call.Length > 0 && session.Calls.Holds(call);
|
||||
callMark.Text = known ? "✓" : "?";
|
||||
callMark.Foreground = colour;
|
||||
callMark.IsVisible = Logging?.Editing is null
|
||||
&& openWindows.ContainsKey(typeof(CheckWindow))
|
||||
&& call.Length is >= 3 and <= 9
|
||||
&& !call.All(char.IsAsciiDigit);
|
||||
}
|
||||
|
||||
private string ContestLine()
|
||||
{
|
||||
if (Logging is null)
|
||||
@@ -704,8 +781,8 @@ public sealed partial class EntryWindow : Window
|
||||
private void ShowLights()
|
||||
{
|
||||
bool radio = session.Radios.Any(r => r.Number == radioNumber && r.IsConnected);
|
||||
RadioLight.Fill = radio ? Verdicts.NewMultiplier : Dark;
|
||||
TransmitLight.Fill = sending ? Verdicts.Dupe : Dark;
|
||||
RadioLight.Fill = radio ? GreenLight : Dark;
|
||||
TransmitLight.Fill = sending ? RedLight : Dark;
|
||||
}
|
||||
|
||||
/// What N1MM writes in its title bar: the frequency, the mode, whether the
|
||||
|
||||
Reference in New Issue
Block a user