The Effects panel drew a folder's name from the last `/`-separated part of
its key (`<top>/<folder>`), so Audio Effects ▸ Noise Reduction/Restoration
showed as "Restoration" — truncated in English and untranslated in every
other language, since the catalogs translate the full name. Split once,
after the top folder, instead.
Test: effects_panel_lists_the_premiere_transition_folders checks the label.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013XWUReif4gqcjU5GsjYioc
With a colour parameter's eyedropper armed (Color Key, Ultra Key, …), a
click on the Program picture did nothing: the selected clip's on-monitor
transform handles (#639) are drawn over the picture and took the click.
The clip is always selected while its effect shows in Effect Controls, so
the eyedropper never fired. While an eyedropper is armed the picture
overlays (transform handles, masks, graphics) are not drawn, so the click
reaches it; they come back once the colour is picked or Esc disarms it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Apply Video / Audio Transition worked only at an edit point under the
playhead. As in Premiere, with clips selected they now add the transition
at the selected clips' free edges (video or audio side only), and with an
edit point selected at that edge only, wherever the playhead is. Edges
that already have a transition keep it; one undo step per press; the
call's effect / frames / params / reverse apply to every edge. With
nothing of that kind selected, the playhead behaviour is unchanged.
Shares the edge collection of Apply Default Transitions to Selection (⇧D).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brazilian Portuguese (#176) moves to the catalog system as i18n/pt-br.tsv (the
menu entries unchanged) and joins the general.interfaceLanguage preference. The
new UI text from main is wrapped and translated into Spanish: the credits
window, Text Properties, H.265 export rows, Clip Speed / Duration, Color Matte
dialogs, the voice-over discard button, the time-left suffix and the audio
output status messages.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Translations move from Rust tables to one catalog per language
(crates/ui-egui/src/i18n/<code>.tsv), looked up through HashMaps. UI code
wraps its strings in tl!("…") and tlf!("…{name}", name); names from
registries (effects and parameters, settings, commands, panels, workspaces,
export and effect presets) are translated where they are drawn, so command
ids, automation ids and preference values stay English.
Spanish now covers menus, panels, dialogs, the Settings pages, the Effects and
Effect Controls registry, the Keyboard Shortcuts dialog and status messages
(about 3,350 entries). Tests fail when a tl!/tlf! literal, a menu label or a
registry name has no Spanish entry, and check catalog syntax, duplicates,
placeholders and ellipses. Searches match the Spanish label as well as the
English source. Window titles keep their English egui ids.
The language is stored in the general.interfaceLanguage preference (also in
Settings > General) and restored on startup; a failed preferences write still
switches the interface and says it could not be saved. Template values are
inserted literally, so a file name containing braces is not re-substituted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
egui 0.36 reports pressing Shift, Ctrl, Alt or the Windows / Cmd key as a
key event of its own, before the key they modify. The Keyboard Shortcuts
recorder took that first press and refused it ("AltLeft can't be used as a
shortcut"), so no chord with a modifier could be recorded. Modifier keys on
their own are now skipped; the chord is recorded with the key they modify.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- project: vtransition.rs registry. Animation, Dissolve, Grunge & Distort,
Immersive Video, Lights & Blurs, Slide, Smart Tools, Text, Transformers
and Wipe folders, plus Legacy > Video Transitions. Old ids are kept:
modern versions reuse push/slide/split/whip/clock_wipe/radial_wipe/
cross_zoom/page_peel, the old behaviour lives under *_legacy ids, and
removed transitions move to a hidden Obsolete folder. Parameters are
not animatable; find_transition looks up by kind (Mosaic/Mirror/
Directional Blur names are shared with video effects).
- render: transitions/ module with procedural CPU implementations, a
field-wipe engine (feather, border width/colour, anti-aliasing, centre),
a 3D card renderer (flips, cube, folds, spins), page curl, blur/light/
grunge families and flat VR approximations. Endpoints are exact,
pixel params scale with the render resolution, and Reverse now plays
B->A backwards. There is no GPU transition path, so the plan keeps
only the symmetric dissolves on the GPU.
- engine: applyVideoTransition takes params/reverse; new
sequence.setTransition; effects.list adds folder/kind filters,
badges and detail paramInfo; sequence.inspect shows transition params.
- ui: the Effects panel shows the Legacy top folder and all badges;
ui.set effectsSearch.
- tests: per-transition endpoint, continuity, midpoint, determinism,
NaN, parameter-wiring and direction properties; golden fingerprints;
tree counts; apply-every-transition via command; UI panel test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Waveform peaks were cached by item id and never cleared, and item ids repeat across
projects: after opening a project the timeline drew the previous project's waveforms
(a 7-minute mission-audio clip showed as silent). The cache is now reset with the media
pool, and an item whose source is not available is no longer left pending forever.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Engine shortcut set (crates/engine/src/shortcuts.rs): bindings as data
(command, canonical chord, optional panel), panel shortcuts override app ones
while the panel has focus; per-OS modifiers (Cmd = Cmd/Ctrl, Ctrl = macOS
Control, folded into Ctrl elsewhere and reported as conflicts); conflict
detection, reassignment, undo/redo, Cancel restores; frontend commands
registered so tools/transport/panels are bindable too.
- Presets: FilmCraft Default, Premiere Pro / Final Cut Pro / Avid Media
Composer Compatible (key tables mapped onto FilmCraft command ids); custom
presets as JSON in <data dir>/Keyboard Shortcuts/, active set persisted,
Save As / Delete / Export / Import (Windows-notation files converted).
- shortcuts.* commands for agents/MCP (list/get/set/clear/undo/redo/conflicts/
forKey/resolve/presets/loadPreset/savePreset/deletePreset/export/import/audit).
- Premiere-default audit: commands without a shortcut get Premiere's key when
free (Shift+D Apply Default Transitions, Shift+J/L slow shuttle, Shift+K Play
Around, Project > Shift+O Open in Source Monitor); Audio Clip/Track Mixer
window shortcuts corrected (Shift+9 / Shift+6).
- Edit > Keyboard Shortcuts... (Cmd+Alt+K): keyboard drawn in code with
app/panel/both colouring and modifier filter, searchable command list with a
record-on-click Shortcut column and +, Key: detail list, conflict warnings,
Undo/Redo/Clear/Cancel/OK; automation ids shortcuts.*.
- Menus (in-app and native macOS key equivalents), command.list and the input
loop follow the active bindings live.
- Tests: 7 engine tests; scripted kittest test (record keys, live menu update,
reassignment, undo/redo, cancel, OK, panel-specific Left in History).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Trim Monitor: with edit points selected the Program monitor shows the
outgoing/incoming frames, Out/In timecodes and shift counters, -N/-1/+1/+N
buttons (N = Preferences > Trim > Large Trim Offset), Apply Default
Transitions, play-around loop and exit; drag in a picture trims that side,
between them rolls. Automation ids trimMonitor.*.
- Dynamic trimming in the engine (trim.shuttle / trim.tick / trim.shuttleStop /
trim.cancelDynamic), driven by a caller-supplied clock: L forward, J back,
again = 2x..8x, Shift = slow, K commits as ONE undo step, Esc cancels; holds
at limits; any other command commits first. Live updates re-apply the offset
to the pre-trim project without touching history or the journal.
- trim.playAround: loop/once from preroll to postroll (new Preferences >
Playback preroll/postroll, Trim > playhead determines loop).
- trim.monitor query, trim.applyDefaultTransition (Shift+D); timeline draws
selected edit points (red ripple / yellow roll-trim brackets) and clicking an
edge with Selection/Ripple/Rolling selects it; selecting clips leaves trim mode.
- J/K/L/Space/Shift+K route to trim mode in the UI; new Shuttle Slow L/R and
Play Around commands.
- Tests: 6 engine tests on an exact simulated clock; scripted kittest test
(buttons, L/K/J, one undo step, Space loop, exit); ignored wgpu screenshot test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
crates/ui-egui/tests/scripted.rs runs the real FilmcraftApp under
egui_kittest's eframe harness (no window/GPU) and drives it through
ControlRequests, stepping frames until each reply arrives; synthetic
ui.click input is fed through the app's raw_input_hook. Tests: demo
project + widget registry, razor/undo/redo with timeline locate,
source insert, apply Gaussian Blur and see it in Effect Controls,
playback toggle/stop, click a tool button by automation id, error
replies. docs/testing.md documents coverage and limits.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>