Interactive Tuner
Interactive tuner (tune.py)
Split out of README.md to keep it direct - see
README.md for setup, usage and the machine list.
Interactive tuner (tune.py)
python3 tune.py # machine picker first
python3 tune.py config/blickensderfer.yaml # skip the picker, load directly
A textual TUI for iterating on the config without hand-editing YAML or
re-running the CLI. Sections are listed down the left-hand side of the
form - Font & Alignment, Type Test, Resin, Gauge,
Build, Font Coverage, Layout, Quality, Logo,
Element (the last flagged as advanced - core geometry, not usually
touched), plus whichever of Character, Ticks, Calibration,
Label, Rib and Legend the loaded machine has. Click one, or
arrow through the list, to switch. Every section a machine has is visible
at once; the list is a vertical column rather than a row of tabs because
a machine can have up to 14 of them, and a horizontal bar showed about
five with no hint the rest existed.
A persistent RENDER TEST TEXT button (below the sections, always
visible) launches/raises f3d in orthographic Top View
(f3d_top_view_cmds.txt, set_camera top - reverse-engineered from
libf3d.so’s own command strings after a hand-derived
--camera-direction guess came out rotated 90°) to preview the flat
Type Test text.
Config tiers: the master YAML (config/blickensderfer.yaml) is never
written to by the TUI. All edits/saves go to a gitignored per-master
scratch copy, config/blickensderfer.running.yaml, created on first run
and auto-migrated (_migrate_running_config) to backfill any top-level or
nested keys that exist in master but not yet in a stale running copy,
without touching your own customizations. “Reset to Defaults” discards the
running copy and starts fresh from master. “Save” writes the running copy
to a location you choose (textual-fspicker’s file browser) - that’s how
a tuning session becomes a real, committable config.
Picking a font: every font path field (Font & Alignment’s font.path,
Logo’s logo.font_path, the per-machine label/legend font paths) has two
buttons. Installed opens a list of every font installed on this
machine, by name - fontconfig’s own list on Linux (so anything fc-list
knows about, including per-user directories added to fonts.conf),
%WINDIR%\Fonts plus the per-user
%LOCALAPPDATA%\Microsoft\Windows\Fonts on Windows; lib/system_fonts.py
does the enumeration. File is the original file browser, for a font
that isn’t installed anywhere. The config stores a plain path either way,
so nothing downstream changes.
The list is uncapped on purpose - browsing the whole library is a real
way to use it, so nothing is truncated and the last entry is always
reachable. Type to filter on family, style or filename (all typed words
must match, so alma bold and ocr otf both narrow the way you’d
expect), or just scroll: up/down and PageUp/PageDown move without leaving
the filter box, the mouse wheel works over the list, and Tab focuses the
list itself. Enter picks the highlighted font, Esc cancels. The
currently-selected font is pinned to the top and pre-highlighted, and the
full path of whatever’s highlighted shows below the list - two installed
files can carry the same family name.
Build tab: a 2-option dropdown (Element / Shaft Gauge) plus an
independent “Resin supports” checkbox. Element builds FullElement(), or
ResinPrint() (adds ResinSupport()’s rods/breakaway ring - see the
Resin tab) when the checkbox is on. Shaft Gauge builds GaugeTestSet()
(see the Gauge tab/section below) regardless of the checkbox - a gauge
print always carries its own resin supports since it can’t stand on its
own.
Quirks worth knowing: q alone doesn’t quit while any text field has
focus (Textual consumes it as literal input) - ctrl+q always works, and
either quit path saves the running config first. Quitting/closing the
terminal also kills any f3d process the tuner launched.