Commit Graph

466 Commits

Author SHA1 Message Date
vangel76 f8b37e1463 #831: cargo xtask parity measures effects and transitions (--area)
Problem: `cargo xtask parity` (#781, #782) measured only the menu bar; the
Effects panel's effects and transitions had no measured parity figure
(docs/gaps.md G7).

Fix: `--area effects|transitions` compares the catalogue the engine's
effect definitions list in the Effects panel (new `effect_catalog`
example in filmcraft-project, the panel's own top-folder filter) with a
reference of folder paths or bare names (default the local, never
committed plan/premiere/<area>.json). Same report, caps and `--min` as
menus; placement by folder; Presets / Lumetri Presets and the other
area's items are out of scope, so one panel snapshot serves both areas.
`--area menus` (default) is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 01:15:53 +02:00
Brandon Thomas c47e883c27 Merge pull request #826 from vangel76/gap-tga-dpx-import
#821: import Targa and DPX stills and image sequences
2026-10-10 19:15:39 -04:00
Brandon Thomas 55b07f29ff Merge pull request #818 from vangel76/gap-mask-rounded-corners
#813: masks round their corners (rounded rectangle masks)
2026-10-10 19:15:33 -04:00
Brandon Thomas 4ecdb6ea71 Merge pull request #824 from ReReddo/feat/monitor-wheel-zoom
monitors: the wheel zooms about the pointer, the middle button pans
2026-10-10 19:10:45 -04:00
vangel76 f8f16b6eca Merge remote-tracking branch 'upstream/main' into gap-aac-audio
# Conflicts:
#	crates/engine/src/commands.rs
#	docs/gaps.md
2026-10-11 01:09:25 +02:00
vangel76 bad190d234 Merge remote-tracking branch 'upstream/main' into gap-mp2-decoder
# Conflicts:
#	docs/codec-parity.md
#	docs/gaps.md
2026-10-11 01:07:54 +02:00
Brandon Thomas f114b5f10c Revert #783 (Linux H.265 through NVENC): intermittent heap corruption in the CLI
With NVENC registered on Linux, `filmcraft-cli --test cli` aborts in 2 of 45 runs on an RTX 3090
(`malloc(): mismatching next->prev_size`, `malloc(): unaligned fastbin chunk detected`) right
after an export finishes; 0 of 30 runs fail with this reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:01:15 -04:00
vangel76 2ca656684e Merge remote-tracking branch 'upstream/main' into gap-mask-rounded-corners
# Conflicts:
#	docs/gaps.md
2026-10-11 01:00:22 +02:00
vangel76 116364cf08 #820: fall back to DX12, then a software adapter, when the graphics start fails
Problem: a graphics driver that crashes inside wgpu instance or device
creation (Intel Vulkan igvk64.dll #512 #413 #793, AMD atio6axx.dll #477)
killed every launch the same way until the user set WGPU_BACKEND by hand;
a start-up error wgpu did report ended in an error dialog.

Fix: each start leaves a marker in the data folder (graphics-start.json),
cleared once the window has painted two frames. A marker still pending at
the next launch moves on along the platform's ladder (Windows: Vulkan+DX12,
DX12 only, software/WARP; Linux: default, software/lavapipe or llvmpipe)
and keeps the mode that works. A wgpu start-up error moves on within the
same process (eframe reuses its event loop). Fallback modes don't register
the GPU export renderer, whose own instance would load the failed driver.
An explicit WGPU_BACKEND leaves the marker alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:58:45 +02:00
vangel76 fe52bc0b2c #821: import Targa and DPX stills and image sequences
Problem: Premiere imports Targa and DPX as stills and numbered sequences.
FilmCraft exports both (#779) but could not read either: the extensions
were not importable and the image crate has no DPX reader, so even our
own Targa / DPX renders could not come back in.

Fix: clean-room decoders in filmcraft-media. Targa from the TGA 2.0 spec:
image types 1/2/3 and RLE 9/10/11, colour maps, 15/16/24/32-bit, 8/16-bit
grayscale, any origin. DPX from SMPTE ST 268: first element, luma / RGB /
RGBA / ABGR, 8/16-bit, filled 10/12-bit (methods A and B), either byte
order, padded lines, orientations 0-3. Both bound allocations by the
data present and reject hostile headers with errors. Stills and image
sequences share one decode_raster entry point; "tga" and "dpx" join the
importable still extensions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:58:15 +02:00
vangel76 b9f60842bb #814: AAC Audio export (audio-only .m4a, or ADTS .aac)
Problem: Premiere's "AAC Audio" format has no FilmCraft equivalent. AAC
was only written inside H.264 / H.265 / AV1 movies; the only audio-only
exports were Waveform Audio and AIFF.

Fix: a new `aac` export format ("AAC Audio") that encodes the sequence
mix with the existing AAC-LC encoder into an MPEG-4 audio file (.m4a,
encoder delay in an edit list), or a raw ADTS stream when the path ends
in .aac. Bitrate, sample rate, channels and loudness normalisation follow
the audio settings. Adds an "AAC Audio 48 kHz 320 kbps" Audio Only
preset, CLI extension guessing (.m4a / .aac), es/fr/ja/zh-cn strings, and
updates G13 (also noting ProRes 4444 / XQ is already in the export UI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:56:35 +02:00
ReReddo 5f9908905c monitors: the wheel zooms about the pointer, the middle button pans (#807)
Zooming a monitor took the zoom dropdown, which zooms about the middle
of the picture, and then scrolling or the Hand tool to bring the part
you wanted into view; at Fit the wheel did nothing.

Now, on the Program and Source monitors:

- The mouse wheel (or a pinch) zooms about the pointer, from Fit too,
  between the dropdown's 10% and 1600%: the point under the pointer
  stays under it. It zooms as fast as the Timeline's wheel zoom, through
  the same wheel_input.
- A middle-button drag that starts over the picture pans it, whatever
  the tool; the Hand tool still pans with the left button.
- Fit resets zoom and pan, and each monitor keeps its own, as before.
  Comparison View, which always fits both frames, ignores the wheel.

Tests: view_ui (wheel zoom about the pointer, middle-button pan, the 10%
floor, Fit, Source untouched).
2026-10-11 01:55:26 +03:00
vangel76 39afd2f6c3 #809: own MPEG audio Layer I / II decoder plays MP2 at ffmpeg's default bit rates
Problem: symphonia rejects every Layer II frame whose bit rate / mode
combination ISO/IEC 11172-3 does not allow (mono above 192 kbit/s, stereo
below 64 kbit/s). ffmpeg writes mono MP2 at 384 kbit/s by default, so such
tracks played as silence in MPEG-TS / PS, Matroska and raw .mp2 files.

Fix: new L0 crate filmcraft-mpa, a clean-room Layer I / II decoder written
from ISO/IEC 11172-3 and 13818-3 (all modes incl. joint stereo, MPEG-1/2/2.5
rates, the disallowed combinations decoded with the allocation table their
bit rate per channel selects). PacketDecoder::mpeg_audio uses it for layers
I and II (packets of several frames too); raw .mp2 files decode with it,
resyncing after damage. Oracle tests vs ffmpeg: 73-84 dB SNR on ffmpeg /
twolame streams and synthetic Layer I / joint stereo frames; fuzzed damaged
frames never panic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:48:45 +02:00
vangel76 16493a7f70 #813: masks round their corners (rounded rectangle masks)
Problem: Premiere 26's redesigned mask tools give rectangle masks
rounded corners; FilmCraft masks only had sharp corners.

Fix: MaskPath::with_rounded_corners replaces each sharp corner between
straight edges by a circular fillet (two vertices joined by a cubic arc,
handles 4/3·tan(φ/4)·r, shrunk to fit half of each edge; hostile radii
and indices are clamped or ignored). masks.add takes `cornerRadius` for
a rounded rectangle, and the new masks.roundCorners command rounds an
existing mask's corners (or the listed vertices) in one undo step, on
every Mask Path keyframe so animated paths keep interpolating.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:47:09 +02:00
Brandon Thomas 9efe8f3112 Merge pull request #812 from vangel76/gap-exr-sequences
#806: export OpenEXR image sequences
2026-10-10 18:44:25 -04:00
Brandon Thomas 2bbc9fdb35 Merge pull request #811 from vangel76/gap-morph-cut
#805: Morph Cut morphs along optical flow instead of cross-dissolving
2026-10-10 18:44:19 -04:00
Brandon Thomas b42b80b529 Merge pull request #808 from vangel76/gap-mp2-priming
#800: MP2 audio in MP4 and MOV decodes instead of playing silent
2026-10-10 18:44:13 -04:00
Brandon Thomas 4a81aa1742 Merge pull request #804 from vangel76/gap-french-localization
#498: French (fr) interface translation
2026-10-10 18:35:20 -04:00
vangel76 fb5863bc8a #806: export OpenEXR image sequences
Problem: Premiere offers OpenEXR as an image-sequence export format;
FilmCraft could not write EXR at all (docs/gaps.md G13).

Fix: a new export format (id exr, "OpenEXR") writing numbered .exr stills,
with a preset, the Include Alpha Channel option, the file.exportMedia format
list and es/ja/zh-cn strings. The writer in crates/export/src/raster.rs
follows the public OpenEXR file layout: version 2 single-part scan-line
file, half-float B/G/R(/A) channels, no compression, one scan line per
chunk, Rec.709 chromaticities; values are scene-linear (the pipeline's
transfer undone) with premultiplied alpha, as EXR defines. No new
dependency. ZIP / PIZ / DWA compression stays open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:34:28 +02:00
vangel76 50ce8b090c #805: Morph Cut morphs along optical flow instead of cross-dissolving
Problem: Morph Cut rendered as a plain Cross Dissolve, so a jump cut in a
talking-head shot showed the subject twice at half opacity during the
transition, and the GPU plan mixed it as a dissolve too.

Fix: Morph Cut warps both frames along the dense optical flow between them
(the Lucas-Kanade flow of #780, crates/render/src/flow.rs) and blends, so the
subject moves from its place in the outgoing shot to its place in the incoming
one; where the frames do not correspond it stays the cross dissolve. Frames
inside a Morph Cut are planned whole on the CPU (no longer a GPU-mixable
"simple" transition) and cost as a complex transition in the preview estimate.
Morph Cut goldens re-blessed. No face tracking yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:32:08 +02:00
vangel76 c9b9bf3aae #800: MP2 audio in MP4 and MOV decodes instead of playing silent
Problem: MP4 and QuickTime name MPEG audio without its layer (ffmpeg
stores MP2 as `mp4a` + esds object type 0x6B), and we always made the
layer III decoder for it. symphonia's decoder reads only the layer it
was made for, so every MP2 frame was rejected and the track played as
silence; MOV's `.mp2` sample entry was not recognised at all.

Fix: the MPEG audio decoder for MP4 / MOV is made on the first packet,
for the layer its frame header names (ISO/IEC 11172-3 2.4.2.3);
`.mp2` maps to the MPEG audio codec like `.mp3`; the track is labelled
"MPEG Audio" for layers I/II, as Matroska's is. Decoded tracks now match
ffmpeg sample-exactly (edit list trims the 481-sample encoder delay).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:26:39 +02:00
vangel76 73f9982c0c #498: French (fr) interface translation
Problem: French, one of Premiere's interface languages and one of the
12 key languages in docs/gaps.md G14, had no catalog; #498 asked for it.

Fix: a new fr.tsv catalog with every entry Spanish has (menus, panels,
dialogs, Settings pages, the Effects / Effect Controls registry, the
Keyboard Shortcuts dialog, status messages) plus the native macOS
Settings item, written from the plain meaning of the English text with
ordinary French editing vocabulary (infinitive commands, "vous", French
sentence case and spacing). Language::Fr is persisted as `fr`;
app.language.french joins Edit > Language (checkmark, native macOS menu),
Settings > General offers Français, and System Language picks French for
any fr-* locale. Like Japanese, tests require only the core menus, so
later strings show in English until translated; a French entry without
a Spanish one fails. A new test checks the bundled fonts cover every
French letter (the glyph check is shared with Ukrainian). Docs: G14,
localization-parity, ROADMAP language row, ui-egui README.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:22:08 +02:00
Brandon Thomas 9f6d75350c Merge pull request #795 from vangel76/gap-ec-transition-timeline
#577: Effect Controls shows a selected transition's own timeline
2026-10-10 18:15:32 -04:00
Brandon Thomas bf7ef0e894 Merge pull request #794 from impostazioni/fix/alt-drag-duplicate
Timeline: Option-drag copies clips instead of moving them
2026-10-10 18:15:25 -04:00
Brandon Thomas de6dcc8ebf Merge pull request #789 from vangel76/gap-optical-flow
#780: Optical Flow time interpolation synthesises motion-compensated frames
2026-10-10 18:09:14 -04:00
Brandon Thomas 257d7af4ab Merge pull request #791 from vangel76/gap-image-sequences
#779: export JPEG, Targa and DPX image sequences
2026-10-10 18:09:10 -04:00
vangel76 0b62ebb9ad #577: Effect Controls shows a selected transition's own timeline
Problem: with a transition selected, Effect Controls showed only its
settings. Premiere puts the transition's own timeline beside them (clip
A, clip B and the transition over their cut), where it can be slid
over the cut or resized by dragging; FilmCraft could do that only in the
Timeline.

Fix: right of the settings (the clip view's divider and width), a time
ruler over the cut, clip A above, the transition between, clip B below,
the cut and the playhead. Dragging the transition's middle slides it,
dragging an end changes its duration from that end (the Timeline's
rules, transitions::drag_span), measured against the view the drag began
in; each drag is one undoable sequence.setTransition. The ruler moves the
playhead. Every part has an automation id; no new UI strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:08:40 +02:00
vangel76 3b1fa29663 #790: Matroska AAC / MP3 / AC-3 trims the exact CodecDelay
Problem: ffmpeg stores the encoder priming as CodecDelay in ns (1024 AAC
samples at 48 kHz = 21.333 ms, 256 AC-3 samples at 44.1 kHz = 5.805 ms)
and block timestamps in ms. The demuxer subtracts the delay rounded to
1 ms, and fixed-length packets were anchored on that rounded stamp, so
the whole track played up to 16 samples late against ffmpeg's decode.
Only Opus undid the rounding.

Fix: one stamp-to-samples conversion for every Matroska audio codec
that undoes the demuxer's rounding and removes the exact CodecDelay
(rounded to the nearest sample; the element holds whole ns), with
checked math against hostile timebases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:59:15 +02:00
Brandon Thomas ab7318e788 Merge pull request #788 from vangel76/gap-eac3
#647: decode E-AC-3 (Dolby Digital Plus) audio
2026-10-10 17:52:57 -04:00
vangel76 c673ee85b9 #779: export JPEG, Targa and DPX image sequences
Problem: Premiere offers JPEG, Targa and DPX as image-sequence export
formats; FilmCraft only wrote PNG, TIFF and BMP sequences (docs/gaps.md G13).

Fix: three new export formats (ids jpg, tga, dpx), numbered like the other
sequences, with presets, the export UI (JPEG quality slider, Targa alpha)
and es/ja/zh-cn strings. JPEG uses the image crate at the export quality;
Targa (TGA 2.0, uncompressed 24/32-bit) and DPX (SMPTE ST 268, 10-bit RGB
method A, BT.709) are written by a small hostile-input-safe writer in
crates/export/src/raster.rs. Format::is_image_sequence replaces the
hand-kept format lists. OpenEXR stays open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:51:41 +02:00
vangel76 e56ddd0e36 #780: Optical Flow time interpolation synthesises motion-compensated frames
Problem: a speed-changed clip set to Time Interpolation > Optical Flow
rendered exactly like Frame Blending, a cross-fade of the two neighbouring
source frames, so moving objects showed double images.

Fix: new filmcraft_render::flow. It computes dense coarse-to-fine
Lucas-Kanade flow both ways on a luma pyramid at most 640 px wide, drops
motion wherever standing still explains the window as well (flicker on
static content), forward-splats both flows to the in-between time
(Baker et al. 2011), and warps both frames there. Each fetch is weighted
by how well its own flow agrees, so uncovered background comes from the
frame that shows it. Pixels that look the same in both frames, or where
neither fetch agrees, fade to the plain cross-fade. media_image uses it
for OpticalFlow clips. docs/gaps.md G18 and target-app-parity updated
(also drops the #415 / #458 items, already fixed on main).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:50:15 +02:00
Brandon Thomas f346da650f Merge pull request #784 from vangel76/gap-render-in-out-range
#424: Render In to Out renders only the frames between In and Out
2026-10-10 17:49:34 -04:00
Brandon Thomas 8ae2c641a3 Merge pull request #782 from vangel76/gap-parity-menus
#781: cargo xtask parity measures menu coverage
2026-10-10 17:49:28 -04:00
vangel76 be98b9d7f7 #647: decode E-AC-3 (Dolby Digital Plus) audio
Problem: files with E-AC-3 audio (MP4 ec-3, MOV, Matroska A_EAC3, MPEG-TS)
imported silent: filmcraft-ac3 refused bsid 11-16.

Fix: clean-room E-AC-3 decoding from ATSC A/52:2012 Annex E in filmcraft-ac3:
bsi and audfrm syntax, 1/2/3/6-block syncframes, reduced sample rates,
frame-based exponent strategies (exponents reused across short syncframes),
SNR offset strategies, default band structures, spectral extension
(translation, notch filter, noise blending). Independent substream 0 is
decoded; dependent substreams and other programs are skipped (7.1 plays as
its 5.1 core). AHT and enhanced coupling are refused as unsupported. The
audio blocks share the AC-3 path; AC-3 output is unchanged. filmcraft-codecs
routes E-AC-3 in MP4/MOV, Matroska and TS to the decoder; the TS splitter
joins dependent substream frames to their access unit.

Tests: ffmpeg oracle for raw E-AC-3 (64.8-91.0 dB SNR) and in MP4, MOV,
Matroska and TS (79.5-91.3 dB, random access identical), mutation fuzz,
synthetic frames for headers, substream skipping, refusals and exponent
reuse across 1-block syncframes, spectral extension unit tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:49:03 +02:00
vangel76 d676fdc720 #424: Render In to Out renders only the frames between In and Out
Problem: Render Effects In to Out and Render In to Out rendered every
render-bar segment that In/Out touched, in full. Segments run between
edit points, so In/Out inside one long clip rendered the whole clip
(often the whole timeline).

Fix: render only the marked frames of each segment as a partial preview,
`<hash>-<off>-<len>.mov`, frames counted from the segment start (so a
ripple keeps it, like whole `<hash>.mov` previews). The store indexes
parts per hash; the render bar is green over rendered frames only,
playback reads the part holding a frame, later renders fill only the
gaps, and Delete Render Files In to Out removes only files holding
marked frames.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:41:36 +02:00
SilentYeti c635d9af9e Linux: H.265 export through NVENC
The NVENC HEVC encoder (Main 8-bit SDR and Main 10 HDR PQ / HLG) was gated to
Windows. It now also runs on 64-bit Linux, on the CUDA device the H.264 encoder
already uses: the H.265 format and HDR probes are registered there and the
HEVC tests run on both systems.

NVENC registration on Linux now happens after the VA-API probe. Started beside
it, the background HEVC probe's first cuInit could deadlock with
libva-nvidia-driver, which calls cuInit from its library constructor under the
loader lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:41:04 -07:00
vangel76 6aca7c1798 #781: cargo xtask parity measures menu coverage
Problem: the menu parity figure in docs/target-app-parity.md came from an
ad hoc label-matching script over string literals; nothing repeatable
measured the real menu bar (docs/gaps.md G7).

Fix: `cargo xtask parity` dumps the shipped menu bar (new
`menus::default_menu_items`, deterministic: English, default prefs,
built-in workspaces; printed by `examples/menu_tree.rs`) and compares it
with a reference list of menu paths, by default the local, never-committed
`plan/premiere/menus.json` (any JSON of paths via --reference; parsing is
depth- and size-capped). Presence and placement are reported separately
(same path, elsewhere, missing); app/Help/recent/account/macOS items are
out of scope. Writes a markdown checklist (target/parity/ or --out) and
--min fails below a presence threshold. Without a reference it prints our
inventory only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:39:57 +02:00
Brandon Thomas b92fdde25b Merge pull request #765 from ReReddo/feat/rect-corner-handles
program monitor: drag a rectangle's corners round with on-canvas corner handles
2026-10-10 17:01:31 -04:00
Brandon Thomas c1c2f91cfc Merge pull request #758 from vangel76/fix-266-save-prompt-on-quit
#266: quitting with unsaved changes asks to save first
2026-10-10 17:00:55 -04:00
skylar taylor-barrick baadac2cf8 UI.9: integrate shared docking and preserve workspace behavior 2026-10-10 14:59:52 -06:00
impostazioni a8b3d7f703 Timeline: Option-drag copies clips instead of moving them
Holding Option (Alt) while dragging timeline clips now leaves the
originals in place and drops copies where the pointer lets go, as in
Premiere. The copies are selected; copies of linked clips are linked to
each other, and transitions that would travel with a move are copied.

- edit: copy_items (overwrite / insert, new ids, links and transitions)
- engine: timeline.move takes `copy: true`, returns `copied`
- ui: the drag remembers Option, shows the copy under the pointer while
  the originals stay, copy cursor
- tests: engine copy/link/locked-track test, headless Option-drag UI test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:52:28 +01:00
ReReddo 8f1b7c3494 program monitor: drag a rectangle's corners round (#744)
A rectangle's rounded corners could only be set by typing a Corner
Radius in Properties. As in Premiere, a selected rectangle now shows
four small circles just inside its corners: dragging one towards the
middle rounds all four corners (Corner Radius is one value), dragging it
back out squares them, and the radius stops at half the shorter side,
where the renderer caps it too.

The circles sit on each corner's diagonal at the radius, at least 12
points in, and show only on rectangles at least four times that across
on screen. While dragging, a white outline of the rounded rectangle
previews the result; the radius is set on release with graphics.set, one
undo step per drag. Automation ids: program.layer.<clip>.<layer>.corner.<n>.

Tests: graphics_handles_ui (the circles round all four corners, clamp
and undo; ellipses and tiny rectangles have none).
2026-10-10 22:46:27 +03:00
vangel76 1580ebb520 #266: quitting with unsaved changes asks to save first
Problem: Quit, Cmd+Q or the window's close button exited at once with
unsaved changes, leaving them to the recovery journal, so every launch
after an unsaved session offered a recovery (docs/project-files.md: no
"Save changes?" prompt on quit yet).

Fix: a close request with unsaved changes is cancelled and the existing
Save Project prompt asks Cancel / Don't Save / Save (automation ids
quit.*), as in Premiere. Don't Save discards the changes and their
recovery snapshot; Save on a never-saved project (here and in Close
Project) opens the Save dialog and returns to the prompt when cancelled.
The control channel's app.quit still quits without asking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:33:45 +02:00
vangel76 ae488523a9 Merge remote-tracking branch 'upstream/main' into fix-620-project-notes
# Conflicts:
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/zh-cn.tsv
2026-10-10 21:15:04 +02:00
vangel76 110c1783c3 #620: Project Notes panel, saved in the project
Problem: a project had nowhere to keep free text (to-dos, instructions
for whoever opens it next, frame numbers).

Fix: plain-text `Project::notes` (schema v15, no-op migration so older
builds refuse instead of dropping it), `project.notes` /
`project.setNotes {text, merge?}` engine commands (undoable, capped at
1 MiB; calls with one `merge` key share an undo step), and a
Window > Project Notes panel whose editor (`notes.text`) commits every
change, one typing session per undo step. Translations for es, ja,
zh-cn (and the panel title for pt-br, uk).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:09:13 +02:00
Brandon Thomas ef52c3834f Merge pull request #737 from ReReddo/fix/shape-handles-size
graphics: shape handles change the shape's Size, Shift keeps the ratio
2026-10-10 14:57:06 -04:00
Brandon Thomas 104355ae13 Merge pull request #701 from vangel76/fix-313-source-shuttle
#313: J/K/L shuttle the Source monitor both ways at up to 8x
2026-10-10 14:55:50 -04:00
Brandon Thomas 33115e9a8a Merge pull request #698 from vangel76/fix-614-continuous-thumbnails
#614: Head, Head and Tail and Continuous video thumbnails in the Timeline
2026-10-10 14:55:39 -04:00
Brandon Thomas b07df164fa Merge pull request #676 from vbasky/fix/592-import-replace
Add file.import replace mode for empty-project round-trips
2026-10-10 14:54:33 -04:00
Brandon Thomas 5f9b5e1234 Merge pull request #656 from vangel76/fix-412-single-keyframe-select
#412: select a single keyframe in Effect Controls
2026-10-10 14:53:45 -04:00