Lay the digital window out the way N1MM does

The window now carries what N1MM's does. Across the top: the TX indicator, the
Letters/Figs box showing the word under the pointer in the other Baudot case,
and the MouseOver box showing the word itself. Down the left of the receive
pane is the pause bar, green while text prints and yellow while it is held.
Under the panes are the message buttons and the row of engine controls, in
N1MM's order.

Both of N1MM's window scroll types are here. The scrolling pane adds lines at
the bottom; the non-scrolling pane keeps text where it was printed, underlines
the line being printed to and walks it down the window, so a call does not move
as the pointer reaches it.

A callsign is checked before it is coloured: anything shaped like a call under
the generic routine, only calls in the files that are ticked under the
resources routine, and under the combination everything, with a call the files
do not hold marked in yellow. The garbage text search finds a Master.scp call
inside a run of noise.

The mouse and the keys are N1MM's. Shift+click converts the case before the
word is transferred, Ctrl+click puts it in the box the cursor is in, Alt+click
puts a call on the stack, a double click replaces the call in the box. The
receive pane and the grab list have their right click menus. Alt+T and Ctrl+K
turn the transmitter on with the cursor in the transmit pane, Alt+G grabs, Esc
aborts.

New from the menus: hover mode, the callsign pause routines, sending a text
file, a date-stamped copy of the receive pane in ExportFiles, clearing the grab
list on a CQ or a QSY, the ham default and AFC off on a run to S&P change, AFC
on with CQ, and raising the window with the entry window it belongs to. The
grab list holds ten calls, as N1MM's does.

The setup window is N1MM's dialog: a General / MMTTY Setup tab, an Engine tab
for the Wine and bridge paths, and a Message Setup tab with the buttons laid
out as they sit in the window, a caption and text box for the one being edited,
the macro list, the count of buttons to show, and import and save of a .mc
file. Right-clicking a message button opens that tab, so the free-form macro
dialog is gone.

The title carries the dial frequency with the mark tone added to it, or the
dial frequency alone when the radio already reads out what it transmits.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
This commit is contained in:
2026-09-01 00:03:30 +00:00
parent 1da35e6c45
commit f3908840b3
9 changed files with 1154 additions and 248 deletions

View File

@@ -21,73 +21,116 @@
<Setter Property="Opacity" Value="0.7" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style Selector="TextBlock.caption">
<Setter Property="FontSize" Value="11" />
<Setter Property="Opacity" Value="0.7" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="6,0,4,0" />
</Style>
<Style Selector="TextBlock.readout">
<Setter Property="FontFamily" Value="monospace" />
<Setter Property="FontSize" Value="12" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="4,2" />
</Style>
</Window.Styles>
<DockPanel>
<Menu DockPanel.Dock="Top" Name="MenuBar">
<MenuItem Header="_Engine">
<MenuItem Header="Start" Click="OnStartEngine" />
<MenuItem Header="Stop" Click="OnStopEngine" />
<Separator />
<MenuItem Header="MMTTY setup window" Click="OnEngineSetup" />
<MenuItem Header="Ham default profile" Click="OnHamDefault" />
<MenuItem Header="Align to mark tone" Click="OnAlign" />
<Separator />
<MenuItem Header="Settings…" Click="OnEngineSettings" />
</MenuItem>
<MenuItem Header="_Setup">
<MenuItem Header="Macros…" Click="OnEditMacros" />
<MenuItem Header="Settings…" Click="OnEngineSettings" />
<MenuItem Name="ForegroundItem" Header="Bring to foreground when made active"
ToggleType="CheckBox" Click="OnToggleForeground" />
<Separator />
<MenuItem Header="Start the engine" Click="OnStartEngine" />
<MenuItem Header="Stop the engine" Click="OnStopEngine" />
<MenuItem Header="Setup MMTTY" Click="OnEngineSetup" />
<Separator />
<MenuItem Name="AfcWithCqItem" Header="AFC on/off with CQ"
ToggleType="CheckBox" Click="OnToggleAfcWithCq" />
<MenuItem Name="HamOnSearchItem" Header="Send ham default on run to S&amp;P change"
ToggleType="CheckBox" Click="OnToggleHamOnSearch" />
<MenuItem Name="AfcOnSearchItem" Header="Turn AFC off on run to S&amp;P change"
ToggleType="CheckBox" Click="OnToggleAfcOnSearch" />
<Separator />
<MenuItem Name="HoverModeItem" Header="Turn hover mode on/off"
ToggleType="CheckBox" Click="OnToggleHoverMode" />
<MenuItem Name="RightClickEnterItem" Header="Rt click = Return NOT menu"
ToggleType="CheckBox" Click="OnToggleRightClick" />
<MenuItem Name="RightClickKeepsCallItem"
Header="With Rt click enabled don't drop on-deck call"
ToggleType="CheckBox" Click="OnToggleRightClickKeepsCall" />
<Separator />
<MenuItem Header="Send text file…" Click="OnSendTextFile" />
<MenuItem Name="TextOutputItem" Header="Output RX window to text file"
ToggleType="CheckBox" Click="OnToggleTextOutput" />
<Separator />
<MenuItem Header="Digital call stacking">
<MenuItem Name="StackFirstInItem" Header="Enable using first in first out"
ToggleType="Radio" GroupName="stack" Click="OnStackFirstIn" />
<MenuItem Name="StackLastInItem" Header="Enable using last in first out"
ToggleType="Radio" GroupName="stack" Click="OnStackLastIn" />
<MenuItem Name="StackMultipliersItem" Header="Enable using FIFO mults first"
ToggleType="Radio" GroupName="stack" Click="OnStackMultipliers" />
<MenuItem Name="StackDisabledItem" Header="Disabled"
ToggleType="Radio" GroupName="stack" Click="OnStackDisabled" />
</MenuItem>
<MenuItem Name="PauseOnCallItem" Header="Use RX window callsign pause routines"
ToggleType="CheckBox" Click="OnTogglePauseOnCall" />
</MenuItem>
<MenuItem Header="_View">
<MenuItem Header="Clear RX" Click="OnClearReceive" />
<MenuItem Header="Clear TX" Click="OnClearTransmit" />
<Separator />
<MenuItem Header="Larger font" Click="OnLargerFont" />
<MenuItem Header="Smaller font" Click="OnSmallerFont" />
<Separator />
<MenuItem Header="Clear receive pane" Click="OnClearReceive" />
<MenuItem Header="Clear transmit pane" Click="OnClearTransmit" />
<MenuItem Name="ScrollingItem" Header="Scrolling window"
ToggleType="Radio" GroupName="scroll" Click="OnScrolling" />
<MenuItem Name="NonScrollingItem" Header="Non-scrolling window"
ToggleType="Radio" GroupName="scroll" Click="OnNonScrolling" />
</MenuItem>
<MenuItem Header="_Options">
<MenuItem Name="HighlightBackgroundItem" Header="Highlight the background"
ToggleType="CheckBox" Click="OnToggleHighlight" />
<MenuItem Name="GrabSpaceItem" Header="A grabbed call is followed by a space"
ToggleType="CheckBox" Click="OnToggleGrabSpace" />
<MenuItem Header="_Grab">
<MenuItem Name="GrabEverythingItem" Header="Everything heard"
ToggleType="Radio" GroupName="grab" Click="OnGrabEverything" />
<MenuItem Name="GrabNotDupesItem" Header="Do not add dupes"
ToggleType="Radio" GroupName="grab" Click="OnGrabNotDupes" />
<MenuItem Name="GrabKnownItem" Header="Only Master.scp and worked calls"
ToggleType="Radio" GroupName="grab" Click="OnGrabKnown" />
<Separator />
<MenuItem Name="RightClickEnterItem" Header="Right click presses Enter"
ToggleType="CheckBox" Click="OnToggleRightClick" />
<MenuItem Name="RightClickKeepsCallItem" Header="Right click keeps the call"
ToggleType="CheckBox" Click="OnToggleRightClickKeepsCall" />
<Separator />
<MenuItem Header="Grab list">
<MenuItem Name="GrabEverythingItem" Header="Everything heard"
ToggleType="Radio" GroupName="grab" Click="OnGrabEverything" />
<MenuItem Name="GrabNotDupesItem" Header="Not dupes"
ToggleType="Radio" GroupName="grab" Click="OnGrabNotDupes" />
<MenuItem Name="GrabKnownItem" Header="Known calls only"
ToggleType="Radio" GroupName="grab" Click="OnGrabKnown" />
<Separator />
<MenuItem Name="GrabNewestFirstItem" Header="Newest first"
ToggleType="CheckBox" Click="OnToggleGrabOrder" />
<MenuItem Header="Clear the list" Click="OnClearGrabList" />
<MenuItem Header="Sort order">
<MenuItem Name="GrabNewestFirstItem" Header="Last in, first out"
ToggleType="Radio" GroupName="grabsort" Click="OnGrabNewestFirst" />
<MenuItem Name="GrabOldestFirstItem" Header="First in, first out"
ToggleType="Radio" GroupName="grabsort" Click="OnGrabOldestFirst" />
</MenuItem>
</MenuItem>
<MenuItem Header="Call _stacking">
<MenuItem Name="StackMultipliersItem" Header="Multipliers first"
ToggleType="Radio" GroupName="stack" Click="OnStackMultipliers" />
<MenuItem Name="StackFirstInItem" Header="First in, first out"
ToggleType="Radio" GroupName="stack" Click="OnStackFirstIn" />
<MenuItem Name="StackLastInItem" Header="Last in, first out"
ToggleType="Radio" GroupName="stack" Click="OnStackLastIn" />
<MenuItem Name="StackDisabledItem" Header="Off"
ToggleType="Radio" GroupName="stack" Click="OnStackDisabled" />
<MenuItem Name="GrabSpaceItem" Header="Send space on using grab"
ToggleType="CheckBox" Click="OnToggleGrabSpace" />
<MenuItem Name="ClickSpaceItem" Header="Send space on callsign mouse click"
ToggleType="CheckBox" Click="OnToggleClickSpace" />
<Separator />
<MenuItem Header="Clear list" Click="OnClearGrabList" />
</MenuItem>
</Menu>
<Grid DockPanel.Dock="Bottom" ColumnDefinitions="Auto,*,Auto,Auto" Margin="6,2,6,4">
<TextBlock Classes="status" Name="MouseOverText" MinWidth="120" />
<TextBlock Grid.Column="1" Classes="status" Name="StateText" HorizontalAlignment="Center" />
<TextBlock Grid.Column="2" Classes="status" Name="FigsText" Text="Letters" Margin="0,0,10,0" />
<Border Grid.Column="3" Name="TransmitDot" CornerRadius="7" Width="30" Height="16"
Background="Transparent" BorderThickness="1">
<Grid DockPanel.Dock="Top" ColumnDefinitions="Auto,Auto,*,Auto,*" Margin="6,3,6,1">
<Border Name="TransmitDot" CornerRadius="7" Width="30" Height="16"
Background="Transparent" BorderThickness="1" BorderBrush="#40808080">
<TextBlock Text="TX" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<TextBlock Grid.Column="1" Classes="caption" Text="Letters/Figs" />
<Border Grid.Column="2" BorderThickness="1" BorderBrush="#40808080" Name="FigsBorder">
<TextBlock Classes="readout" Name="FigsText" />
</Border>
<TextBlock Grid.Column="3" Classes="caption" Text="MouseOver" />
<Border Grid.Column="4" BorderThickness="1" BorderBrush="#40808080" Name="MouseOverBorder">
<TextBlock Classes="readout" Name="MouseOverText" />
</Border>
</Grid>
<Grid DockPanel.Dock="Bottom" ColumnDefinitions="*,Auto" Margin="6,2,6,4">
<TextBlock Classes="status" Name="StateText" />
<TextBlock Grid.Column="1" Classes="status" Name="PauseText" />
</Grid>
<StackPanel DockPanel.Dock="Bottom" Margin="4,0,4,2">
@@ -96,23 +139,27 @@
<Button Classes="control" Content="Clr RX" Click="OnClearReceive" />
<Button Classes="control" Content="Align" Click="OnAlign" />
<Button Classes="control" Name="TransmitButton" Content="TX" Click="OnTransmit" />
<Button Classes="control" Content="RX" Click="OnReceive" />
<Button Classes="control" Name="ReceiveButton" Content="RX" Click="OnReceive" />
<Button Classes="control" Content="Ham" Click="OnHamDefault" />
<Button Classes="control" Name="LockButton" Content="Lock" Click="OnToggleLock" />
<Button Classes="control" Name="AfcButton" Content="AFC" Click="OnToggleAfc" />
<Button Classes="control" Name="NetButton" Content="Net" Click="OnToggleNet" />
<Button Classes="control" Name="ReverseButton" Content="Rev" Click="OnToggleReverse" />
<Button Classes="control" Content="CLR" Click="OnClearTransmit" />
<Button Classes="control" Content="Grab" Click="OnGrabNext" />
</WrapPanel>
</StackPanel>
<Grid RowDefinitions="3*,Auto,*" Margin="4,2">
<Border BorderThickness="1" BorderBrush="#40808080">
<ScrollViewer Name="ReceiveScroller" HorizontalScrollBarVisibility="Disabled">
<StackPanel Name="ReceiveLines" Margin="4,2"
PointerMoved="OnReceivePointerMoved"
PointerPressed="OnReceivePointerPressed"
PointerExited="OnReceivePointerExited" />
</ScrollViewer>
<DockPanel>
<Border Name="PauseBar" DockPanel.Dock="Left" Width="10" Background="#2E8B57"
Cursor="Hand" PointerPressed="OnPauseBarPressed"
ToolTip.Tip="Click to hold the pane still; click again to let it run" />
<ScrollViewer Name="ReceiveScroller" HorizontalScrollBarVisibility="Disabled">
<StackPanel Name="ReceiveLines" Margin="4,2"
PointerMoved="OnReceivePointerMoved"
PointerPressed="OnReceivePointerPressed"
PointerExited="OnReceivePointerExited" />
</ScrollViewer>
</DockPanel>
</Border>
<GridSplitter Grid.Row="1" Height="4" ResizeDirection="Rows" Background="Transparent" />
@@ -123,11 +170,17 @@
FontFamily="monospace" BorderThickness="0"
KeyDown="OnTransmitKeyDown" />
</Border>
<Border Grid.Column="2" BorderThickness="1" BorderBrush="#40808080">
<ScrollViewer Name="GrabScroller">
<StackPanel Name="GrabCalls" Margin="3,2" />
</ScrollViewer>
</Border>
<Grid Grid.Column="2" RowDefinitions="*,Auto">
<Border BorderThickness="1" BorderBrush="#40808080">
<ScrollViewer Name="GrabScroller">
<StackPanel Name="GrabCalls" Margin="3,2" PointerPressed="OnGrabListPressed" />
</ScrollViewer>
</Border>
<WrapPanel Grid.Row="1">
<Button Classes="control" Content="Grab" Click="OnGrabNext" />
<Button Classes="control" Content="CLR" Click="OnClearGrabList" />
</WrapPanel>
</Grid>
</Grid>
</Grid>
</DockPanel>