Commit Graph

469 Commits

Author SHA1 Message Date
Brandon Thomas 6ace9f7b0e Merge pull request #923 from itrycodinganditsbad/rotating-log
Desktop: write log records to standard error and a rotating log file
2026-10-12 04:20:56 -04:00
Brandon Thomas e0b770a9ea Merge pull request #907 from tylerjenningsw/enhance/toolbar-gradient-swatch
Shapes: the toolbar's gradient swatches open the Gradient Editor (#612)

# Conflicts:
#	docs/gaps.md
2026-10-12 04:20:51 -04:00
Brandon Thomas efa023f693 Merge pull request #876 from vangel76/fix-874-linux-font-dirs
#874: scan Flatpak host, XDG and fontconfig font folders on Linux
2026-10-12 04:20:39 -04:00
Brandon Thomas 3f8af1a3b6 Merge pull request #863 from itrycodinganditsbad/fix-748
Save the active comp and open comp tabs in project files (#748)
2026-10-12 04:20:33 -04:00
Brandon Thomas ac1aca7225 Merge pull request #862 from tylerjenningsw/enhance/gradient-viewer-handles
Shapes: drag gradient start and end points in the Composition viewer (#612)
2026-10-12 04:20:32 -04:00
Brandon Thomas 0b2d85b811 Fix tests after the community merges: GPU Pixel Motion Blur without a host, timeline footage kind, effects doc
- GPU Pixel Motion Blur (#695) declined without a host; it now averages the shutter's
  frames like the CPU effect (tests_fx_time::without_a_host).
- add_item_keeps_footage_longer_than_the_comp_at_full_length (#798) built footage with
  the default kind (Still), which adds at comp length; it is a movie.
- docs/effects.md regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 04:18:51 -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 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 225bbad013 Merge pull request #787 from vangel76/gap-floating-panel-windows
#486: move a panel into its own native window (multiple monitors)

# Conflicts:
#	crates/ui-egui/src/i18n/ui.rs
#	docs/gaps.md
2026-10-12 03:22:53 -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 5be3b8f9b2 Merge pull request #782 from MishynMykhailo/uk-panel-catalog-20261011
Translate the 95 panel rows Ukrainian was missing
2026-10-12 03:22:49 -04:00
Brandon Thomas 1210ba91f4 Merge pull request #768 from vangel76/fix-762-animated-webp
#762: import animated WebP as footage with its frames

# Conflicts:
#	docs/file-format-parity.md
2026-10-12 03:22:30 -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 dfd6e9300f Merge pull request #772 from vangel76/script-760-evalfile-bridgetalk
#760: $.evalFile and a minimal BridgeTalk host identification

# Conflicts:
#	crates/script/src/runtime.rs
#	docs/scripting-parity.md
2026-10-12 03:20:49 -04:00
Brandon Thomas b2ce1240c6 Merge follow-up: model description and gaps row 17 after the import PRs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 03:20:48 -04:00
Brandon Thomas 78b32b61d4 Merge pull request #769 from vangel76/gap-mxf-import
#767: import MXF (OP1a / OP-Atom) footage

# Conflicts:
#	crates/ui-egui/src/menus.rs
#	docs/gaps.md
2026-10-12 03:20:05 -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 05f0d9ec62 Merge pull request #755 from vangel76/gap-tga-hdr-import
#745: import Targa (.tga) and Radiance HDR (.hdr) stills and sequences

# Conflicts:
#	crates/ui-egui/src/menus.rs
2026-10-12 03:20:03 -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
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 15387619ee Merge pull request #780 from vangel76/gap-project-panel-a11y
#776: Project panel arrow-key navigation and accessible names
2026-10-12 03:03:44 -04:00
Brandon Thomas 3e9aa820d1 Merge pull request #771 from vangel76/script-759-include
#759: #include / //@include / #includepath in scripts
2026-10-12 03:03:36 -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 fef320e9dd Merge pull request #763 from vangel76/script-758-callable-props
#758: layers, property groups and properties are callable
2026-10-12 03:03:29 -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 4c9a9a9cfa Merge pull request #752 from vangel76/gap-float-working-gamma
#750: float footage follows Working Gamma and is encoded once
2026-10-12 03:03:23 -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 686280cc5f Merge pull request #711 from Ni-zav/fix/704-cylinder-axis-rotation-s20261011T035800Z-cf39
fix(effects): add XYZ rotation to CC Cylinder on CPU and GPU
2026-10-12 03:02:48 -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
Fabio Lussi 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
tylerjenningsw a47995aabb Docs: gaps.md records the toolbar gradient-swatch tests 2026-10-11 14:46:55 -04:00
vangel76 b58197ff82 #874: scan Flatpak host, XDG and fontconfig font folders on Linux
Problem: on Linux the font list only scanned /usr/share/fonts,
/usr/local/share/fonts, ~/.local/share/fonts and ~/.fonts. The ArtCraft
Launcher installs EffectCraft as a Flatpak, where those folders hold only
the runtime's fonts and the host's fonts live under /run/host, so installed
fonts were missing (25 families instead of 320 on the reporter's setup).
$XDG_DATA_HOME/fonts, $XDG_DATA_DIRS/*/fonts and fontconfig <dir> entries
were never scanned either.

Fix: a new font_dirs module lists the usual folders, the Flatpak host
folders (/run/host/fonts, local-fonts, user-fonts), the XDG data folders
and the <dir>/<remap-dir> entries of the fontconfig configuration
(FONTCONFIG_FILE or /etc/fonts/fonts.conf, /usr/local/etc/fonts/fonts.conf,
and ~/.config/fontconfig), following <include>s with prefix="xdg",
"relative" and ~ expansion. It uses a small tag scanner (no new dependency),
bounds the include depth, the number and size of files read, and reads each
file once. Folders are deduplicated before the walk, and the walk depth
goes from 4 to 8. docs/agents.md lists the folders and how to grant the
Flatpak an extra one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:21:20 +02:00
Fabio Lussi 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
tylerjenningsw f45f57da7d Docs: gaps.md records the #612 viewer gradient-handle tests 2026-10-11 11:12:15 -04: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
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
vangel76 765ba157be #788: hold opened projects and size commands to the 30,000 px limits
Problem: comp.new/comp.settings clamp sizes to 30,000 px, frame rates to
0.001-1000 fps and motion-blur samples to 2-64, but reading a project
(.ecproj and .ecprojx, templates, recovery, offload) accepted any value:
a 4-billion-px comp, solid or footage frame, a 0 or 10^18 fps rate
(zero-length frames), a negative duration or 4 billion blur samples all
reached the renderer. New Solid, Layer Settings, Import Solid/Placeholder,
Crop Comp and PSD import set sizes without the upper bound, and comp
sizes past 2^32 wrapped.

Fix: one set of limits in effectcraft_project::limits. Project::from_json
brings every item (and proxy) within them; from_json_repaired also says
what it changed, which file.open returns as `repaired` and shows in a
toast, so the project still opens. Project::add_item applies the same
limits to every new item, and the size-setting commands clamp with the
shared helpers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:22:59 +02:00
vangel76 e7ada5bd16 #486: move a panel into its own native window (multiple monitors)
Problem: floating panels lived inside the main window only, so on a
two-screen setup no panel could go onto the second monitor (#486).

Fix: panel menu > Move Panel to New Window (and the agent/control command
`window.panelWindow {panel, window?}`) undocks the panel if needed and shows
its floating group in a native egui viewport the user can drag to any screen;
Move Panel to Main Window or closing the window brings it back. The window's
place and size are kept in the workspace (sanitised against hostile values)
and restored on the next start. Browser and test builds, which embed
viewports, show it as an in-app window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:10:12 +02:00
vangel76 b747ffc986 #779: fuzz File > Open; refuse deeply nested XML projects
Problem: nothing fuzzed project files. The hand-written .ecprojx XML reader
recursed once per nested <arr>/<obj> with no limit, so a deeply nested file
overflowed the stack and aborted the app instead of failing to open.

Fix: a dependency-free, deterministic, seeded mutation fuzzer for File > Open
(JSON and XML seeds from the demo, byte and JSON-structure mutations, the real
file.open path, first queries and a thumbnail render; each input under
catch_unwind with a deadline; bounded for cargo test, longer runs via env
vars). The XML reader now stops at the JSON reader's 128-level limit, with a
regression test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:02:40 +02:00
vangel76 7085816c98 #773: run repeating app.scheduleTask tasks until cancelTask
Problem: app.scheduleTask(code, delay, true) queued the task and then
skipped it (eval_with_tasks: `if repeat { continue; }`), so repeating
tasks - what ScriptUI panels use for polling and refreshing - never ran.
One-shot tasks scheduled by handlers or in the Script Console never ran
either.

Fix: tasks live per script context (crates/script/src/tasks.rs) with a
due time. Frontends run the due ones every frame through the new
ScriptUi::run_tasks hook (the egui app does; agents and headless hosts
use the `script.runTasks` command). Script-host threads get a Tick
message, inline hosts (Script Console, web) run in their kept context.
A repeating task runs every `delay` ms until app.cancelTask, until it
throws (reported once, then cancelled), or until its owner goes: the
script's last window closing, or - for scripts without windows and the
console - the project being closed or replaced (ScriptUi::project_epoch).
Bounds: at least 50 ms between runs, at most 64 pending tasks per
script, one run per pass (no catch-up bursts), task code nested too
deeply is refused, the engine's loop and recursion limits apply. Ticks
only reach the hosts of the session that scheduled them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:56:09 +02:00
vangel76 132bd21078 #776: Project panel arrow-key navigation and accessible names
Problem: with the Project panel focused the arrow keys did nothing (After
Effects selects the previous / next item, extends with Shift and opens /
closes folders with Right / Left). The custom-drawn rows, sort headers,
twirls, label swatches, proxy switches and footer buttons reached
AccessKit with no name or role, the empty list area and each row's name
cell were unnamed extra Tab stops, a Tab-focused row showed no focus
ring, and the arrows then moved egui's spatial focus instead.

Fix: Up / Down select the previous / next row (Shift extends from the
anchor), Right opens and Left closes the selected folder or selects the
parent; the moved-to row scrolls into view. A row with keyboard focus
keeps the arrows, focus follows the selection and the panel takes focus.
Rows are AccessKit tree items named "<name>, <type>" with selected,
level and expanded state; headers and row / footer buttons are named
buttons; one Tab stop per row and a focus ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:53:48 +02:00
MishynMykhailo 8763fc0138 Translate the 95 panel rows Ukrainian was missing
The panel catalog (crates/ui-egui/src/i18n/ui.rs) has grown to 496 rows since
Ukrainian last matched it on 9 October, so `uk` fell back to English for the Home
screen, the viewer's toolbar tooltips and popups, the Appearance settings, the
solid dialog and the project, import, export and colour-management forms.

Add those rows, in the Chinese catalogs' order and under their section comments,
so the catalogs stay parallel. `uk` now carries 495 of the 496 rows: `RGB` reads
the same in Ukrainian, so it keeps no row and falls back to the English source,
which is what the catalog's own rule asks for.

Terminology follows the Ukrainian menu catalog in i18n.rs so the two agree:
Full/Half/Third/Quarter as Повна/Половина/Третина/Чверть, Draft as Чорнова,
Wireframe as Каркас, Custom... as Власна..., Region of Interest as Область
інтересу, footage as матеріал, solid as суцільний колір, Default as Стандартний.
Dark and Light take the neuter form the catalog's existing Darker/Lighter rows
(Темніше/Світліше) already use, so one row reads correctly both as an Appearance
Mode and as a theme card option.

`format_ago` picks between one and many, while Ukrainian declines the noun for 1,
for 2–4 and for 5 and up, so the relative times use the invariant unit
abbreviations (хв, год, дн.), which read correctly for every count. A per-language
plural rule would be the fuller fix and is left for its own change.

ROADMAP.md and docs/localization-parity.md carry the new count.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-11 13:46:05 +03:00