Commit Graph
571 Commits
Author SHA1 Message Date
Brandon Thomas f41fdf0680 Merge pull request #857 from pravdomil/claude/u-uu-shortcuts-time-remap-5dd91b
Timeline: U and UU reveal Time Remap
2026-10-12 03:23:30 -04:00
Brandon Thomas 6304956628 Merge pull request #835 from pravdomil/claude/cmd-arrow-frame-nav-3a2fc1
Shortcuts: Cmd+Left / Cmd+Right Arrow step a frame
2026-10-12 03:23:12 -04:00
Brandon Thomas 30f7ce8ae5 Merge pull request #826 from luniiya/feat/theme-favorites
UI: favorite themes and appearance shortcuts
2026-10-12 03:23:06 -04:00
Brandon Thomas d1e88ee52b Merge pull request #807 from cdinhoo/fix/nonblocking-expression-diagnostics
Performance: reduce UI stalls while dragging layers
2026-10-12 03:23:02 -04:00
Brandon Thomas e8e896e1d6 Merge pull request #799 from MarekSpodBiedry/issue-749
Automation: a layer or comp id sent as a string resolves as an id (#749)
2026-10-12 03:23:00 -04:00
Brandon Thomas 2cf28e5e24 Merge pull request #798 from MarekSpodBiedry/issue-795
Keep footage dropped on the timeline at its full length (#795)

# Conflicts:
#	crates/engine/src/tests_timeline.rs
2026-10-12 03:22:58 -04:00
Brandon Thomas 58b09391bd Merge pull request #789 from vangel76/gap-project-size-limits
#788: hold opened projects and size commands to the 30,000 px limits

# Conflicts:
#	crates/engine/src/commands/layer.rs
2026-10-12 03:22:54 -04:00
Brandon Thomas 909572dffd Merge pull request #785 from vangel76/gap-fuzz-project-open
#779: fuzz File > Open; refuse deeply nested XML projects
2026-10-12 03:22:51 -04:00
Brandon Thomas 24f98a0242 Merge pull request #778 from vangel76/gap-uncompressed-mov
#372: uncompressed QuickTime (raw RGB / ARGB) output module format

# Conflicts:
#	docs/gaps.md
2026-10-12 03:20:53 -04:00
Brandon Thomas 9ebabccbec Merge pull request #775 from vangel76/script-766-mouse-events
#766: ScriptUI mouse events reach script listeners

# Conflicts:
#	crates/engine/src/scriptui.rs
#	crates/script/src/lib.rs
#	docs/scripting-parity.md
2026-10-12 03:20:52 -04:00
Brandon Thomas be1d9928e0 Merge pull request #774 from vangel76/gap-proportional-scrubbing
#770: Proportional Scrubbing of Timeline values (Ctrl+Alt / Cmd+Opt)

# Conflicts:
#	docs/ui-parity.md
2026-10-12 03:20:51 -04:00
Brandon Thomas 3d02e65f2b Merge pull request #765 from vangel76/gap-dpx-import
#756: import DPX and Cineon stills and sequences

# Conflicts:
#	crates/media/tests/footage.rs
#	crates/ui-egui/src/menus.rs
#	docs/file-format-parity.md
#	docs/gaps.md
2026-10-12 03:20:04 -04:00
Brandon Thomas 261a5b125b Merge pull request #754 from vangel76/gap-surface-colors
#315: Front / Bevel / Side / Back Color for extruded shapes and text

# Conflicts:
#	docs/gaps.md
2026-10-12 03:20:01 -04:00
Brandon Thomas d57459a7d0 Merge pull request #742 from vangel76/gap-fbx-import
#736: import FBX 3D models (binary and ASCII)

# Conflicts:
#	crates/engine/src/commands/app_more.rs
#	crates/engine/src/commands/model3d.rs
#	crates/engine/src/media_browser.rs
#	crates/media/src/lib.rs
#	crates/media/src/probe.rs
#	crates/model/Cargo.toml
#	crates/model/src/lib.rs
#	crates/ui-egui/src/menus.rs
#	docs/file-format-parity.md
#	docs/gaps.md
2026-10-12 03:20:00 -04:00
LosminekandClaude Opus 5.5 50ab738f62 Merge upstream/main into cs-ui
Keep every entry in contributors/people.toml, and translate the new menu
item (Copy Frame to Clipboard) and the five gradient-editor strings into
Czech.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:19:44 +02:00
LosminekandClaude Opus 5.5 2a8ecfb822 i18n: add Czech (cs) interface language
Czech for all 618 fixed menu entries and the 496 panel, tooltip and dialog
strings of the most complete catalog; settings accept and persist `cs`, Match
System recognises cs, cs-CZ and cs_CZ.UTF-8; native menu, Undo/Redo and
file-manager labels. Czech may lag the Chinese catalogs like Japanese and
Ukrainian (a missing row falls back to English); menu rows use "..." like
the other catalogs. AI-assisted, independently reviewed, not yet proofread
by a native speaker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:18:17 +02:00
Brandon Thomas d9dddb90b7 Merge pull request #781 from vangel76/script-773-repeating-tasks
#773: run repeating app.scheduleTask tasks until cancelTask
2026-10-12 03:03:45 -04:00
Brandon Thomas bcb9ee1fa5 Merge pull request #764 from vangel76/gap-transition-presets
#757: Transitions animation presets in Effects & Presets
2026-10-12 03:03:31 -04:00
Brandon Thomas c72e47b7dc Merge pull request #761 from vangel76/gap-variable-font-filter
#741: font menu filters to variable fonts
2026-10-12 03:03:28 -04:00
Brandon Thomas b14096c335 Merge pull request #744 from vangel76/fix-732-toolbar-fill-type
#732: toolbar Fill/Stroke Options change the selected shape layers' kind
2026-10-12 03:03:20 -04:00
Brandon Thomas 8176c86043 Merge pull request #739 from vangel76
# Conflicts:
#	docs/gaps.md
2026-10-12 03:03:10 -04:00
Brandon Thomas e98788690c Merge pull request #737 from vangel76/gap-copy-frame-clipboard
#730: Composition ▸ Copy Frame to Clipboard
2026-10-12 03:02:59 -04:00
Brandon Thomas e5ff011296 Merge pull request #735 from vangel76/gap-stl-import
#729: import STL 3D models (binary and ASCII)
2026-10-12 03:02:58 -04:00
Brandon Thomas d7fe6d2e56 Merge pull request #705 from tylerjenningsw/enhance/custom-ui-scale
Settings: allow custom UI scale percentages (#682)
2026-10-12 03:02:46 -04:00
Brandon Thomas 4482ad9634 Merge pull request #703 from didpublishing/fix/windows-path-tests
Tests: six engine tests no longer assume the working directory's drive on Windows
2026-10-12 03:02:44 -04:00
Brandon Thomas 162a2e2e01 Merge pull request #699 from didpublishing/fix/596-gpu-information
#596: GPU Information names the adapter, or why the GPU compositor is off
2026-10-12 03:02:43 -04:00
MarekSpodBiedry 5df37babc3 Keep Footage panel overlay/insert edits at full length past the comp end (#795) 2026-10-12 08:05:22 +02:00
SteamSmithandClaude Opus 5.5 011e242b74 engine: build well-formed file:// URLs for Edit Original, Reveal and File.execute
Three places built file URLs by string concatenation: Edit Original
(`file://{path}`), the Reveal commands via folder_url (`file://{dir}`) and
File.execute (`file://` with only spaces replaced by %20). On Windows that
produced `file://C:\Users\...`, and any path containing `#`, `%`, `?` or
non-ASCII characters named the wrong file (or none).

Add layer_menu::file_url: backslashes become `/`, drive paths get the third
slash (`file:///C:/...`), and bytes outside the plain path characters are
percent-encoded (UTF-8 for non-ASCII). folder_url, edit_original and
execute_file use it.

Tests: file_urls_are_well_formed, folder_url_names_the_containing_folder,
edit_original_opens_an_encoded_file_url, execute_file_opens_an_encoded_file_url.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:38:35 -04:00
ThemolxandClaude Opus 5.5 91b078777e Timeline: trim all selected layers together
Dragging the in or out edge of a selected layer's bar now trims every
selected layer by the same delta from its own in/out point, as in After
Effects. layer.timing gains relative inDelta/outDelta params (seconds,
frame-snapped), clamped to the comp start/end and to one frame of layer;
the drag stays one undo step via the merge key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 03:16:06 +02:00
Anton IliashenkoandClaude Opus 5.5 14b6b9c242 Composition Settings: save and delete your own presets
As in After Effects, the Preset menu in Composition Settings / New Composition gets a Save
button (asks for the name in a Choose Name window; an existing name of yours is replaced) and a
Delete button for the selected preset of yours. Your presets keep frame size, pixel aspect and
frame rate, are listed above the built-in ones and live in the settings (`compPresets`), so they
survive restarts and Reset All. Commands: `comp.savePreset`, `comp.deletePreset`, `comp.presets`.
A hand-edited settings file loses only its invalid presets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:16:52 +02:00
Kristian Myram 1888f0aaf3 Fix full-screen shortcut shown on Windows 2026-10-12 01:15:23 +02:00
pravdomilandClaude Opus 5.5 c8968cee1f fix: View > Go to Time accepts the dialog's float frame [skip ci]
The Go to Time dialog's Frame field sends a float (5.0); time.set read
`frame` with as_i64, got None and failed with "need time, frame or
timecode". Read it as any JSON number and round.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:55:11 +02:00
MarekSpodBiedry 189dec0644 Interpret Footage: apply the Loop (times) value sent as a float (#909) 2026-10-11 23:38:07 +02:00
pravdomilandClaude Opus 5.5 4c5d775761 Timeline: Alt-click an A/V feature switches the other layers
Alt-click on a layer's Video, Audio, Solo or Lock switch sets that layer
apart: the other layers go off (or locked), and the next Alt-click brings
them back. Backed by layer.setSwitch {others: true}, one undo step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:14:39 +02:00
Fabio LussiandClaude Opus 5.5 16d9d7d30b Desktop: write log records to standard error and a rotating log file
A launch from the Dock, the Start menu or a launcher has no terminal, and
without RUST_LOG nothing reached standard error anyway, so start-up and
GPU warnings were lost unless Help > Enable Logging was already on.

The logger now writes EffectCraft's info records and everyone's warnings
to standard error and to Logs/effectcraft.log in the settings folder.
Each launch keeps the previous two runs' logs; the file is capped at
16 MiB. RUST_LOG still overrides the filter. Help > Reveal Logging File
shows this run's log unless Enable Logging is on.

Ported from storytold/pdfcraft#239.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:37:27 +02:00
vangel76andClaude Sonnet 5.5 fa7ffb6d09 #670: each pane of a 2- or 4-view layout chooses its own view
Problem: the extra panes of View > Switch View Layout were fixed to Top, Front and Right, and the 3D View menu only changed the main view.

Fix: every extra pane has a view selector (Active Camera, Default, Front, Left, Top, Back, Right, Bottom, Custom View 1-3). The choice is kept per comp in Views3D::panes (serde default, so older editor states load with Top/Front/Right) and set by the new command view.setPaneView {pane 0-3, view}. The Active Camera pane renders through the comp camera.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 19:46:47 +02:00
MarekSpodBiedry 55f4d163f8 Scripting: text range selectors resolve by match name and limit the animator (#837) 2026-10-11 19:13:39 +02:00
vangel76andClaude Sonnet 5.5 51501bbd21 #890: the Timeline time field reads its displayed timecode back as the same frame at 29.97/59.94 fps
Problem: the Timeline shows non-drop timecode, but time.set (the current-time field) parsed
typed text as drop-frame at 29.97/59.94 fps, so committing the displayed time, or typing a
time, landed on another frame from minute 1 on (frame 1800 "0:01:00:00" -> 1798).

Fix: typed text is read as drop-frame only when it uses ';' fields; ':' and '.' follow the
displayed non-drop style. Regression test round-trips the display at both rates.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 19:00:25 +02:00
vangel76andClaude Sonnet 5.5 74b95b0a9d #886: say why footage the decoders can't read shows no picture
Problem: a movie whose profile the software decoders lack (H.264 High 4:2:2 / 10-bit)
probes fine, then every frame read fails; MediaPool logged the error per frame and returned
None, so the layer rendered black with no sign why in the viewer, Project panel or for agents.

Fix: MediaPool records the reason once per file (codec from the probe plus the decoder's text
without error wrappers; I/O errors stay with missing-footage handling), logs it once, and
exposes it through the new FootageSource::problem. The Composition viewer shows it on the
affected layer, the Project panel marks the item with a warning whose tooltip is the reason,
and project.summary / footage.info carry a "problem" field. Cleared when the file is
forgotten; only set when decoding really failed, so a hardware decoder that handles the file
shows nothing.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 18:49:54 +02:00
sanches 826d82007d i18n: add Russian, French and German menu catalogs
Three new 618-entry menu catalogs (ru, fr, de) with the same
(command, English label) keys as the existing six, registered in
CATALOG_CODES and the Settings language registry. Following the
Spanish/Portuguese precedent these are menu-only catalogs: panels keep
English for now.
2026-10-11 19:06:04 +03:00
pravdomilandClaude Opus 5.5 ba2770a258 Timeline: UU reveals modified options, layer styles and fixes false positives
The modified reveal compares each layer with a fresh layer of the same kind:
Audio, Material, Geometry, Camera and Light Options and a text layer's Path
and More Options now count when changed. Layer styles count in full, and
overridden Essential Properties are revealed.

Cameras and lights compare their Transform with their own defaults, and
separated X/Y Position with the comp centre, so untouched layers reveal
nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:41:30 +02:00
Fabio LussiandClaude Opus 5.5 b0c0c61aa0 Save the active comp and open comp tabs in project files
Project files now record activeComp and openComps next to savedBy, and
file.open restores them, so a project reopens on the comp it was saved
on (desktop app, CLI and MCP all open through file.open). Older files
and ids that no longer name a comp fall back to the first comp; older
versions ignore the new keys.

Fixes #748

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:27:01 +02:00
pravdomilandClaude Opus 5.5 c81a9f1061 Timeline: U and UU reveal Time Remap
anim.reveal only walked the layer's top-level groups, so Time Remap, which
sits at the root of the layer's property tree, was never revealed. Enabled
time remapping counts as a modification in itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:02:10 +02:00
pravdomilandClaude Opus 5.5 88bf89ea5d Shortcuts: Cmd+Left / Cmd+Right Arrow step a frame
Previous / Next Frame also answer to Cmd+Left / Cmd+Right Arrow, and Back / Forward
10 Frames to Cmd+Shift+Left / Right, next to the Page keys (After Effects' second
default keys). A command spec can now list several default shortcuts
(`alt_shortcuts`, `cmd!(…, ["PageDown", "Cmd+ArrowRight"], …)`); menus and tooltips
keep showing the first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:26:27 +02:00
Luniiya e1bcaab0a0 UI: favorite themes and appearance shortcuts
Port of storytold/photocraft#2445. Each theme in the appearance picker gets a
star at the right edge of its row. Starred themes are saved with the
preferences and listed in a right-click menu on the header's appearance button,
next to Appearance Settings, so switching between favorites takes one click.
2026-10-11 15:46:18 +02:00
cdinhoo be6134e8ad Performance: reduce UI stalls while dragging layers 2026-10-11 15:49:21 +03:00
vangel76andClaude Opus 5.5 3466538d0e #783: Object Matte mattes persist in the disk cache
Problem: computed Object Matte segmentations lived only in the in-memory
cache, so every restart or memory eviction segmented the shot again (After
Effects 26.5 keeps Object Matte results in its disk cache).

Fix: the persistent disk cache gets a third entry kind, Matte (folder
`mattes`, LZ4-compressed FrameSeg bytes, same checksum, atomic writes, LRU
eviction under the one size limit, purged with the rest). Entries are keyed by
the segmentation's chain key and scale; chain keys already hash the Input Key
(the layer's source, timing, masks and effects above), the prompt, the mode and
the model, so any change simply misses. The effects crate gets a SegStore
trait behind its memory cache: Chain::ensure reads from it on a memory miss
and writes what it computes. The engine installs the session's DiskCache as
the store (held weakly, so switching the disk cache off drops it). Roto Brush
segmentations go through the same chain and are persisted too. Frozen mattes
already persist in the project (the Frozen parameter).

Tests: engine tests_roto::object_matte_mattes_persist_in_the_disk_cache (a
second session on the same folder and project gets all tracked frames back
without being able to read a single input frame, renders identically, and a
moved prompt finds nothing); render disk_cache
segmentations_round_trip_and_reopen (round trip, reopen, damaged file is a
miss, size limit evicts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:06:33 +02:00
vangel76andClaude Opus 5.5 560767dfe7 #783: Object Matte tracks in the background and freezes
Problem: Object Matte computed its frames only on demand while rendering, so
playing a shot stalled on every untracked frame, there was no progress or way
to stop, and nothing kept the mattes once computed.

Fix: Object Matte runs through Roto Brush's job machinery (one job slot,
cancellable with roto.cancel, a worker thread on the desktop, a Web Worker in
the browser, never the UI thread). objectMatte.propagate computes the frames
around the reference frame (clipped to the layer) outward, filling the same
content-keyed segmentation cache the renderer reads; the engine's sync now
queues an instance for background tracking when its frames or prompt change.
objectMatte.freeze stores the final mattes in a new hidden Frozen parameter
(Roto Brush's FrozenCache format) under a key of the input, prompt, span,
model and matte settings; renders use them without segmenting while the key
matches; a frozen prompt is refused until objectMatte.unfreeze. Freeze is one
undo step and is dropped if the prompt changed meanwhile.
objectMatte.status reports progress, frozen state and computed frames. Effect
Controls shows Freeze / Unfreeze and Track / Stop with a status line (progress
banner). The frontend now polls Roto Brush / Object Matte jobs on their own:
before, a finished job (and so a Freeze result) was only picked up while a
Warp Stabilizer job was active. Job progress is set before the worker starts.

Tests: engine tests_roto::object_matte_background_job_cancel_and_freeze
(queued by the edit, returns at once with progress, cancel keeps a partial
result, completion computes all 25 frames, frozen renders recompute nothing,
unfreeze recomputes, undo restores); effects object_matte job_frames and
frozen-matte tests (stored pattern used, key mismatch and damaged data
ignored); ui-egui ui_object_matte Effect Controls Freeze end to end.
docs/agents.md: Object Matte section; docs/effects.md regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:02:50 +02:00
MarekSpodBiedry bee798c190 Automation: a layer or comp id sent as a string resolves as an id (#749) 2026-10-11 13:54:43 +02:00
MarekSpodBiedry db11dffa18 Keep footage dropped on the timeline at its full length (#795) 2026-10-11 13:53:52 +02:00