The sidebar grew crowded as the chain got longer. The chain and the params
of the selected stage now share a Chain tab through a vertical split the
user drags, and the sources, canvas and seed move to a Setup tab. Stage
rows are compact, with their move and remove buttons shown only on the
hovered, selected or focused row.
Add effect had stopped opening: its menu of fifteen effects no longer fit
below the button, and GTK does not show a popover that does not fit. The
menu now scrolls past 480 pixels, and the button sits beside the chain
heading, where the split cannot push it down the screen.
The window code becomes an effector_gui library so a new GUI test binary
can drive the real window under Xvfb; ctest skips it when xvfb-run is
missing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A canvas side was cast to int with no range check, so a number that did
not fit came back as one that did: `-s 4294968296x600` rendered a
perfectly plausible 1000x600, and a hand-edited project file could ask
for a width the reader turned into something else (or, for a double out
of range, into undefined behaviour).
Both front-ends now check the side before the cast, against one shared
bound in chain.hpp — the 1..20000 the GUI spin buttons already offered,
so the help text, the CLI error, the project reader and the interface
all move together.
The tests gain a `canvas size` section covering the round trip at both
ends of the range and the refusals on either side of it, through the
project reader and through `-s`; the test binary picks up the CLI parser
to do it, which stays GUI-free.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Port of the Python prototype to C++20 with a CMake build:
- effector_core: GUI-free static library (effects, image IO via gdk-pixbuf,
declarative param specs, registry, portable seeded RNG, thread helper)
- scanlines effect: plans strips from the seeded RNG, then copies pixels in
parallel with memcpy and doubling horizontal tiling
- gtkmm 4 interface: native file dialogs, widgets generated from the param
specs, coalesced background renders, preview as a GDK memory texture
- CLI: flags generated from the effect registry, headless rendering with no
display required
- ctest suite covering the RNG, registry, effect geometry and image round trip
The Python prototype is kept under python-reference/.