Make the run switch a switch, and split the tuning tolerance by mode
Three things you could not see or could not set. Run and S&P were a label saying which one you were in. They are two buttons now, the one you are in marked, either one clickable, which is what N1MM has. Ctrl+? and F1 still work. The tuning tolerance is one number per mode, as N1MM keeps it: CW, phone and digital, 300 Hz each, which are its defaults. A phone signal is wide and a CW one is not, so one number for both was wrong. The bearing line went blank whenever it could not be worked out, which looks exactly like a missing feature. It now says which end could not be placed and what to do — no country file, no position for your own station, or a callsign the country file does not place. It also gives miles beside the kilometres, as N1MM does. While clicking it: a marked button lost its mark under the pointer, because the theme paints its own background there. The band buttons had the same fault. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,8 +20,12 @@ public sealed partial class EntryWindow
|
||||
/// one, and neither is nothing.
|
||||
private string framedCall = "";
|
||||
|
||||
/// How close counts as sitting on a spot, which is a different number for
|
||||
/// each mode: a phone signal is wide and a CW one is not.
|
||||
private Frequency TuningTolerance =>
|
||||
Frequency.FromHertz(Math.Max(0, session.Settings.TuningToleranceHertz));
|
||||
Frequency.FromHertz(Math.Max(
|
||||
0,
|
||||
session.Settings.TuningToleranceFor(Logging?.Mode.Category ?? ModeCategory.Cw)));
|
||||
|
||||
private void ShowCallFrame()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,21 @@
|
||||
<Setter Property="Padding" Value="6,2" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
<Style Selector="Button.mode">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="Padding" Value="8,1" />
|
||||
<Setter Property="MinWidth" Value="44" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
<Style Selector="Button.mode.here">
|
||||
<Setter Property="Background" Value="#2980B9" />
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
</Style>
|
||||
<!-- the theme paints its own background under the pointer, which would
|
||||
hide the mark on the button that is on -->
|
||||
<Style Selector="Button.mode.here:pointerover /template/ ContentPresenter">
|
||||
<Setter Property="Background" Value="#3498DB" />
|
||||
</Style>
|
||||
<Style Selector="Button.band">
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
<Setter Property="Padding" Value="4,1" />
|
||||
@@ -28,6 +43,9 @@
|
||||
<Setter Property="Background" Value="#2980B9" />
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
</Style>
|
||||
<Style Selector="Button.band.here:pointerover /template/ ContentPresenter">
|
||||
<Setter Property="Background" Value="#3498DB" />
|
||||
</Style>
|
||||
<Style Selector="Button.fkey">
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
<Setter Property="Padding" Value="6,3" />
|
||||
@@ -119,10 +137,8 @@
|
||||
VerticalAlignment="Center" />
|
||||
<Ellipse Name="TransmitLight" Width="9" Height="9" Fill="#33808080"
|
||||
VerticalAlignment="Center" />
|
||||
<Border Name="RunBorder" Padding="6,1" CornerRadius="3" Background="#22808080"
|
||||
Margin="4,0,0,0">
|
||||
<TextBlock Name="RunText" FontSize="12" Text="S&P" />
|
||||
</Border>
|
||||
<Button Name="RunButton" Classes="mode" Content="Run" Click="OnRun" Margin="4,0,0,0" />
|
||||
<Button Name="SearchButton" Classes="mode" Content="S&P" Click="OnSearch" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="3" Name="ContestText" FontSize="12" Opacity="0.75"
|
||||
VerticalAlignment="Center" Margin="12,0,12,0" Text="no contest"
|
||||
|
||||
@@ -20,6 +20,8 @@ public sealed partial class EntryWindow : Window
|
||||
private EntryWindow? secondRadio;
|
||||
private readonly List<TextBox> boxes = [];
|
||||
private readonly List<Button> functionButtons = [];
|
||||
private const double MilesPerKilometre = 0.621371;
|
||||
|
||||
private static readonly IBrush Dark = new SolidColorBrush(Color.FromArgb(0x33, 0x80, 0x80, 0x80));
|
||||
|
||||
private bool sending;
|
||||
@@ -527,6 +529,21 @@ public sealed partial class EntryWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRun(object? sender, RoutedEventArgs e) => SetRunning(true);
|
||||
|
||||
private void OnSearch(object? sender, RoutedEventArgs e) => SetRunning(false);
|
||||
|
||||
private void SetRunning(bool running)
|
||||
{
|
||||
if (Logging is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Logging.IsRunning = running;
|
||||
boxes[Logging.Entry.Focus].Focus();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void ToggleRun()
|
||||
{
|
||||
if (Logging is null)
|
||||
@@ -572,8 +589,8 @@ public sealed partial class EntryWindow : Window
|
||||
? $"{Logging.Frequency.Kilohertz:0.00} ▸ {Logging.TransmitFrequency.Kilohertz:0.0}"
|
||||
: Logging.Frequency.Kilohertz.ToString("0.00");
|
||||
ModeText.Text = Logging.Mode.Name;
|
||||
RunText.Text = Logging.IsRunning ? "RUN" : "S&P";
|
||||
RunBorder.Background = Logging.IsRunning ? Verdicts.Worth : new SolidColorBrush(Color.FromArgb(0x22, 0x80, 0x80, 0x80));
|
||||
RunButton.Classes.Set("here", Logging.IsRunning);
|
||||
SearchButton.Classes.Set("here", !Logging.IsRunning);
|
||||
ContestText.Text = ContestLine();
|
||||
|
||||
Title = TitleLine();
|
||||
@@ -637,14 +654,33 @@ public sealed partial class EntryWindow : Window
|
||||
/// line under its entry window.
|
||||
private string PathLine()
|
||||
{
|
||||
if (Logging is null || StationPath.For(Logging, DateTime.UtcNow) is not { } path)
|
||||
if (Logging is null || Logging.Entry.Call.Trim().Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if (StationPath.For(Logging, DateTime.UtcNow) is not { } path)
|
||||
{
|
||||
return WhyNoPath();
|
||||
}
|
||||
string sun = path.Sunrise is { } rise && path.Sunset is { } set
|
||||
? $" · SR {rise:HH:mm}Z SS {set:HH:mm}Z"
|
||||
: " · no sunrise or sunset today";
|
||||
return $"Hdg {path.Heading:0}° · LP {path.LongPath:0}° · {path.DistanceKm:N0} km{sun}";
|
||||
return $"Hdg {path.Heading:0}° · LP {path.LongPath:0}° · "
|
||||
+ $"{path.DistanceKm:N0} km · {path.DistanceKm * MilesPerKilometre:N0} mi{sun}";
|
||||
}
|
||||
|
||||
/// A blank line where a bearing should be is a puzzle. This says which of
|
||||
/// the two ends could not be placed and what to do about it.
|
||||
private string WhyNoPath()
|
||||
{
|
||||
if (session.Countries is null)
|
||||
{
|
||||
return "no bearing — download the country file, in Config ▸ Download Country File";
|
||||
}
|
||||
return Logging?.Me.GridSquare.Trim().Length == 0
|
||||
&& session.Countries.Find(Logging.Me.Callsign) is null
|
||||
? "no bearing — your own station has no position, so set your grid in Config ▸ Station"
|
||||
: "no bearing — the country file does not place this callsign";
|
||||
}
|
||||
|
||||
private string VerdictLine(Verdict? verdict)
|
||||
|
||||
Reference in New Issue
Block a user