Commit Graph
2206 Commits
Author SHA1 Message Date
Elias 4e7eafa82d Effects: CC Particle World / Systems II replace their layer with the particles
The particles were composited with the original layer by the Transfer Mode, so the solid an
artist applies them to stayed visible. After Effects 2026 frames show no trace of it:
SceneYard "Burnout matchstick" (a red rectangle around the flame), "Documentary Man Falling"
(a black block over the light), "Task Preparation UI" (black solids under fireworks). The
Transfer Mode now only sets how the particles meet each other.

Mean abs error vs AE: Burnout matchstick 0.0191 -> 0.0130, Documentary Man Falling
0.1177 -> 0.0937 (Task Preparation also needs the next commit).

(cherry picked from commit 3eb3b9958f9cd929dcf060865e604d42cc0f9337)

(cherry picked from commit 729638710e63f4da10711fc5e6a1f7ddc42c37aa)
(cherry picked from commit 083332116c936f1b4863f0bb390d0647f2b567a1)

(cherry picked from commit 338421de36)
2026-10-12 19:18:52 +01:00
Claude bb540559d8 G5: cargo xtask bench --fail-over PCT fails on resource regressions
With --compare, exits 1 when a matched run got more than PCT % worse in CPU time, peak memory, max RSS
or instructions retired (wall time follows the load and is never gated).

Checks: xtask fail_over test (1 passed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TEytG1Qum4TJrMTLKjgwDa

(cherry picked from commit c34be4d12f3a61f4e386256ae54d75c6bc7f875d)

(cherry picked from commit 6e3eab96493726c551ec1e66174ac08b5591e4c2)
(cherry picked from commit 2e066f4073b300d8bace04419a7d4af3f3242b2e)

(cherry picked from commit 351a4b96c0)
2026-10-12 19:18:33 +01:00
Elias e23b926efc G5: cargo xtask bench: render benchmark of generated scenarios (peak memory, CPU, wall) with results.jsonl and --compare
(cherry picked from commit 40b232d02069925e9c72677f52ee6f356495a736)

(cherry picked from commit a2d89bda11b7217c83c98ab681b8f9b4a334786d)
(cherry picked from commit 63951595222207b6bfd0ecde72f991628c6f12d9)

(cherry picked from commit 20c2bb0dcb)
2026-10-12 19:18:32 +01:00
Claude 2cb5d199ea G4: relink footage that moved
footage.relink {item, path} relinks one item and every other missing item that moved with it (one undo
step); Replace Footage on a missing item does the same, as in After Effects. File > Dependencies >
Relink Missing Footage in Folder... (footage.relinkFolder) finds missing files by name in a folder;
footage.missing lists them. The footage check after open finds files that moved along with the
project's folder, without marking the project modified. Paths compare by parts, so Windows and macOS
projects relink either way.

Checks: engine relink:: / footage_check:: (13 passed with replay::), host relink:: (1 passed),
clippy -D warnings (engine, host, ui-egui, script, cli, xtask). Not run: ui-egui i18n tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TEytG1Qum4TJrMTLKjgwDa

Upstream port: the folder search (footage.relinkFolder) is left out, since upstream's file.relinkFootage already scans a folder; the module is relink_moved.rs next to upstream's relink.rs.

(cherry picked from commit ea7923535fb81693ed95aa0fe768b850b347b2a9)

(cherry picked from commit d15e853a720304c1032e21974d84e1501c6edfc3)
(cherry picked from commit 0b8a328dda1fb727488e912a13f94a2ef4147d03)

(cherry picked from commit 9d85bfde72)
2026-10-12 19:17:35 +01:00
webdevtodayjason 85a269b609 SVG: non-finite viewBox and nested sizes no longer panic the importer 2026-10-12 13:12:51 -05:00
webdevtodayjason ecc131fc86 SVG: percentages in the root <svg> resolve against its own width and height 2026-10-12 12:54:17 -05:00
vangel76andClaude Sonnet 5.5 42c7a7141e #1061: Enter renames the selected effect, text animator, mask or shape group
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 19:40:37 +02:00
Kristian MyramandClaude Haiku 5.5 2ef3d977a6 #808: sourcePointToComp and compPointToSource follow the layer's transform
Both returned their input unchanged. They now go through the layer's transform and its parents'
at comp time, and the inverse.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-12 19:19:13 +02:00
Kristian MyramandClaude Haiku 5.5 4d105f02d4 #809: layer.source and a Layer Control's layer work in expressions
layer.source was undefined in expressions, and a layer from a Layer Control had no transform.
Both now work.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-12 19:19:11 +02:00
Kristian MyramandClaude Haiku 5.5 0852511c3f #551: Shift+Spacebar plays every frame by default
Shift+Spacebar set Skip to 1, so it played every other frame out of the box. It now plays every
frame, like Spacebar. Skip still works when it is set.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-12 19:19:00 +02:00
zitann2020 9375cc3406 i18n(ja): finish the Japanese panel, dialog and tooltip catalog
The menus have been complete in Japanese since the menu catalog landed, but the panel
catalog below the menu bar stopped at 410 of the 506 source strings the Chinese catalogs
define. Settings, the Home screen, the viewer tools and the Fast Previews and channel
popups therefore still drew in English for a Japanese interface.

This adds the 96 missing rows. Existing rows are untouched and keep their order; the new
ones follow the canonical (Simplified Chinese) order, which the catalog tests require, and
no row changes the number of `{}` values its English source carries.

Terms follow the Japanese already in the catalog and, wherever a control exists in both,
the wording After Effects 2026 (26.5) itself shows in Japanese: 平面 (Solid), 関心領域
(Region of Interest), フル画質 / 1/2 画質 / 1/3 画質 / 1/4 画質 (viewer resolution),
ドラフト 3D (Fast Previews), 透明グリッド (Transparency Grid), マスクとシェイプのパスを表示
(Toggle Mask and Shape Path Visibility), チャンネルとカラーマネジメント設定を表示 (Show
Channel and Color Management Settings).

The crate's `i18n` unit tests pass (10/10) and rustfmt is clean.
2026-10-13 02:13:51 +09:00
vangel76andClaude Sonnet 5.5 925760c9c8 Web disk cache: handle the Matte kind (mattes/ folder)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 19:08:21 +02:00
vangel76andClaude Sonnet 5.5 4acea86d4f Merge upstream/main into gap-object-matte
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 19:03:42 +02:00
Marco Arnulfo 7304f4c672 Project panel: Composition Settings… in a comp's right-click menu (fixes #1058)
First in the menu, as in After Effects, and for the right-clicked comp rather than the one in the viewer: the dialog keeps the comp it edits and OK passes it to comp.settings. comp.settings with only {"comp": id} opens the dialog on that comp.
2026-10-12 18:54:56 +02:00
Brandon ThomasandClaude Opus 5.5 470ea7a3af Release 0.9.2: install the wasm-bindgen CLI for the web release build
The shared release workflow installs trunk, but EffectCraft's web build
runs the wasm-bindgen CLI directly (cargo xtask web), so the Web job
fails with "wasm-bindgen CLI not found". In CI, package.sh now installs
the CLI at xtask's WASM_BINDGEN version, as the per-app release.yml did
before the move to craft-common-actions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.9.2
2026-10-12 12:37:47 -04:00
pravdomilandClaude Opus 5.5 0eda174706 Shift+; again zooms the Timeline back in
Zoom to Fit Comp remembers the span it left and goes back to it when pressed
again from the whole comp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:49:55 +02:00
pravdomilandClaude Opus 5.5 498dbc0c71 Show Channel: grayscale and colorized of one channel replace each other
Alt+1 after Alt+Shift+1 shows the red channel in grayscale instead of going back
to RGB (and the other way round). The same key again is still RGB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:49:55 +02:00
pravdomilandClaude Opus 5.5 dfff9ba2dc Alt+B / Alt+Shift+B toggle layer sampling
layer.sampling takes `toggle`: layers that all have the sampling already get the
other one. The Bilinear and Bicubic menu entries, which carry the keys, pass it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:49:55 +02:00
pravdomilandClaude Opus 5.5 eec84a8095 Second default keys, also in menu lines
F2 Deselect All, Cmd+Shift+T Effect Controls, Cmd+Alt+Left / Right Go to Start /
End, Cmd+Shift+/ Add to Render Queue.

Effect Controls is a menu entry with bound parameters, which could hold one key:
a menu line can now give further default keys after a comma
(F3, Cmd+Shift+T); the menus show the first. MenuEntry gains alt_shortcuts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:37:18 +02:00
dotCooCoo 4ee7e03584 Contributors: add dotCooCoo (Robert Lee) 2026-10-12 08:35:30 -07:00
pravdomilandClaude Opus 5.5 6f5bd0c272 Default keys for ten commands that had none
Title/Action Safe ('), Zoom to Fit Comp (Shift+;), Custom resolution
(Cmd+Alt+J), Purge Snapshot (Cmd+Shift+F5), Bilinear / Bicubic sampling (Alt+B,
Alt+Shift+B), Set Proxy (Cmd+Alt+P), most recent project (Cmd+Alt+Shift+P), last
animation preset (Cmd+Alt+Shift+F) and Paste Reversed Keyframes (Cmd+Shift+V).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:35:27 +02:00
dotCooCoo 767120f6ca EPS: arc and arcn with huge angles no longer hang the import
arc added 2π to its sweep in a loop until the sweep was no longer
negative, and arcn subtracted 2π the same way. For an angle of 10^18
degrees the loop took about 3e15 passes, and from 2^56 radians (about
4.1e18 degrees) up, adding 2π left the sweep unchanged and the loop
never ended. A sweep that needed no loop, as in 0 10^18 arc, was passed
unchanged to kurbo, which divides it into more than 1e16 curves (about
four per turn at a radius of 10), and arc appended each curve to the
path. Importing an EPS file probes it with effectcraft_pdf::parse,
which has no time limit, so importing such a file did not finish.

As in storytold/vectorcraft#1062, every arc now starts at the first
angle's remainder after whole turns, and when the second angle is below
the first (arc) or above it (arcn), the sweep is worked out from the
two angles' remainders. A sweep of up to 1,024 turns is drawn whole.
For a longer one, the import records a skip note
("arc (too many turns)") and leaves out whole pairs of turns, so that
between 1,022 and 1,024 turns remain. The arc still ends at the second
angle, and an even-odd fill covers the same area as the full sweep.

Arcs of up to 1,024 turns whose angles are within about 10^6 degrees
are unchanged apart from rounding, except some whose angles are a whole
number of turns apart or within rounding of that. For larger angles,
the old conversion to radians lost precision: at 10^15 degrees, a
quarter-turn arc swept 1.5723 radians instead of 1.5708.

When raising (arc) or lowering (arcn) the second angle by whole turns
makes it equal to the first, as in 7 -353 arc or 2 362 arcn, rounding
sometimes made the old loop add a turn and draw a full circle. Those
arcs are now empty, as the PostScript Language Reference defines them.
When the raised or lowered angle falls just short of the first
instead, the reference defines a full circle, and each version leaves
some of these arcs empty: the old code drew nothing for
125.00000000000001 125 arc, which the new code draws as a full circle,
and the new code draws nothing for 1.0000000000000002 -719 arc, which
the old code drew as a full circle.

arcs_with_huge_angles_end_at_their_second_angle parses each program on
a thread of its own and fails when no result arrives within 20 seconds.
2026-10-12 08:35:18 -07:00
pravdomilandClaude Opus 5.5 92e3939ca7 Fast Previews and Show Channel: one command per mode, with default keys
Both were a single command taking the mode as a parameter, with no menu entry,
so nothing could carry a default key. Each mode is now its own command:
view.fastPreviews.off / adaptive / draft / fastDraft / wireframe (Cmd+Alt+1-5)
and view.channel.red / green / blue / alpha (Alt+1-4), redColorized /
greenColorized / blueColorized (Alt+Shift+1-3) and rgbStraight (Alt+Shift+4).
A channel's key again returns to RGB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:34:56 +02:00
Marco Arnulfo a50e49df73 Interpret Footage: looped footage lasts its loops on new and re-timed layers (fixes #1045) 2026-10-12 17:13:33 +02:00
Brandon ThomasandClaude Opus 5.5 e2f314f753 Release 0.9.1: rebuild with the fixed shared release workflow
The previous release build failed in craft-common-actions, not in this
repo: riscv64 packaging got --formats deb,rpm,tar (fixed in
craft-common-actions#3), Linux jobs lacked the ALSA headers
(craft-common-actions#5), and Windows signing needed the AZURE_* secrets
listed in the caller.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:11:08 -04:00
pravdomilandClaude Opus 5.5 aa6c47395c Cmd/Alt-click twirls: Waveform row, Effect Controls, Project folders
Cmd-click (or Alt-click) a twirl arrow now takes the whole tree with it in
three more places: Audio's Waveform row in the Timeline, an effect or effect
group in Effect Controls, and a folder in the Project panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:52:10 +02:00
Matej Kozlovský 2669e1a1de Export: cap GPU renders only, for GPU-accelerated projects (#879 review)
- The cap applied whenever an accelerator was attached, so Software Only
  projects (which render on the CPU) rendered one frame at a time. It
  now needs the project's GPU acceleration too, as #898 gates it.
- Only the render is capped: each window of max(cap, threads) frames
  renders in chunks of the cap, then encodes in parallel, holding at
  most one window of images.
- An invalid EFFECTCRAFT_GPU_INFLIGHT (0, negative, not a number, too
  large) logs a warning before using the default.
- The default stays one frame: the GPU backend reports no free or total
  device memory portably, so it is not sized from VRAM.
2026-10-12 16:51:36 +02:00
Vikram Bhaskaran f9808423d6 Cover keyframe interpolation and ease on effect parameters (#994)
setInterpolationTypeAtKey and setTemporalEaseAtKey act on effect parameters
(a Slider Control's slider and a 3D Point Control), not just transform
properties. Verified on current main; lock it in with a script regression
test driving the per-key methods through the property object.
2026-10-13 01:49:06 +11:00
Vikram Bhaskaran 3e900db974 Create Shapes/Masks from Text in the layer context menu (#872)
The engine's layer.create has shapesFromText and masksFromText, but the
timeline and Composition context menus only offered Create Shapes from Vector
Layer, so text could not be converted to editable outlines from the UI. Gate
the two text conversions on a text layer (LayerMenuCaps replaces the lone
vector flag), beside the vector one.
2026-10-13 01:47:19 +11:00
pravdomilandClaude Opus 5.5 f96663b1f5 Timeline: Cmd/Alt-click a group twirl opens its whole tree
Cmd-click (or Alt-click) the arrow of Effects, Contents, Masks or any other
group in the Timeline twirls every group under it open, or closed, with it,
as the layer's own arrow already did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:40:35 +02:00
Vikram Bhaskaran de26297c36 Sample footage pixels in script expressions (#1000)
A script reading an expression that calls sampleImage on a footage layer got
[0,0,0,0]: the script evaluator built its EvalCtx with EvalCtx::new, which
has no footage source, so the renderer substituted transparent frames (solids
and shapes stayed correct because they are procedural). Pass the session's
footage source, as the app's renderer and diagnostics already do.
2026-10-13 01:34:58 +11:00
pravdomilandClaude Opus 5.5 41071f0bbf Timeline: a one-line expression row is as tall as a normal row
Drop the 6 px added to expression editor rows (and the matching offset in
the drag-to-resize maths), so the row is a whole number of row heights.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:30:04 +02:00
Moein Saharkhiz 55ef2d05db #989: align pasted effect keyframes with the playhead 2026-10-12 10:26:35 -04:00
Matej Kozlovský 9d63ec19fc Export: one GPU frame in flight by default (#879)
Three frames at once still filled an 8 GB card on the #879 project at
1080p (7.9 GB, the same as no cap); one frame peaked at 6.3 GB and two at
7.0 to 7.8 GB. One matches how the export scheduler in #898 renders image
sequences (one GPU worker, synchronous readback). EFFECTCRAFT_GPU_INFLIGHT
still raises it.
2026-10-12 16:23:12 +02:00
pravdomilandClaude Opus 5.5 a96c85b0e5 Timeline: expression row takes its property row's background
Rows stripe by their index among the non-expression rows, so adding or
removing an expression leaves every other row's stripe unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:17:31 +02:00
Vikram Bhaskaran db6e3c5cc6 Compensate cameras and lights when parenting, preserving the world frame (#1010, #1020)
setParent re-expressed Position for 3D layers but skipped cameras and lights
entirely, so parenting a camera to a (default) null moved its eye by the
null's world transform and the framing jumped. Cameras and lights now get the
same parent-space Position fix, plus Point of Interest for two-node rigs
(values, keys, spatial tangents and ease speeds). They have no Scale, so
Orientation stays as authored.
2026-10-13 01:15:58 +11:00
Vikram Bhaskaran d33e82a571 Cover mask vertex multi-select: Shift-click toggle and marquee (#1004)
Shift-click adds a vertex to the selection and removes it again, a plain
click collapses to one, and a marquee from empty viewer area selects the
enclosed vertices (additive with Shift) without moving the layer. These
behaviors regressed or were never covered; the tests drive them through the
Composition viewer like a user.
2026-10-13 01:01:11 +11:00
Matej Kozlovský 742472440e Export: cap GPU frames rendering at once (#879)
With a GPU accelerator every frame of a batch rendered in parallel, each
holding its own working textures, so a 30-frame 1080p batch could take
the whole card (20+ GB on an RTX 3090) and run shared-memory GPUs out of
memory. Cx::frames now renders GPU frames in consecutive chunks of 3
(EFFECTCRAFT_GPU_INFLIGHT overrides it), the same cap as the export
scheduler in #898; output order and the CPU path are unchanged.

Fixes #879
2026-10-12 16:00:05 +02:00
FeiLiuEM 35124cc924 text: the Traditional list drops a Simplified face and adds the macOS Traditional ones
WenQuanYi Micro Hei is a Simplified-oriented face, so keeping it in the Traditional list - even as a
last resort - could still draw Simplified forms, which is the one thing the split is for. Heiti TC
and Hiragino Sans CNS are the macOS Traditional faces the family's own lists use (photocraft's
`CjkScript::TraditionalChinese`). Dropping the entry does not lose the face: the generic scan behind
the script lists still finds it when nothing Traditional is installed.

The test now walks the `FallbackScript::Han` arm as well, so a list wired to the wrong script fails
it, and it refuses a WenQuanYi entry in the Traditional list.
2026-10-12 21:57:49 +08:00
Vikram Bhaskaran f5c6487cf1 Reveal enabled Time Remap on U even with no keys left (#990)
anim.reveal keyframes/animation only matched keyframed top-level properties,
so Time Remap vanished from U once its keys were deleted even though enabling
remapping is itself the modification (and freshly enabled remaps, which get
two keys, kept showing). Match the bare timeRemap prop for both kinds, as
modified already did.
2026-10-13 00:50:56 +11:00
pravdomilandClaude Opus 5.5 0c343212ae Timeline: a group twirled open by hand under a reveal shows all its properties
Collapsing and expanding an effect that shows only its revealed parameters
(U, UU) now lists every parameter. The next reveal on the layer filters it
again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:48:13 +02:00
Vikram Bhaskaran 66a6b99d12 Share the Scale Constrain Proportions link between Properties and Timeline (#956)
The Properties panel kept its own ephemeral per-layer link toggle, so
unlinking Scale there left the Timeline linked and vice versa, and its edit
math differed from the Timeline's. Use the shared per-property unlinked set
and widgets::constrained, with the stable match id instead of the display
name, plus Alt-edits-one-axis like the Timeline.
2026-10-13 00:42:54 +11:00
Vikram Bhaskaran 341076359a Nudge selected layers with the arrow keys from any panel but Project (#961)
The viewer.nudge shortcuts bailed out unless Composition, Viewer or Timeline
had focus, so with any other panel focused the arrows silently did nothing.
After Effects nudges from almost anywhere; only the Project panel owns the
arrows for its own keyboard navigation. Typing, dialogs, menus and selected
mask vertices still keep the keys.

Tests: arrow nudge from Effect Controls, no nudge from Project, Shift+arrow
10x, time untouched, click-row path.
2026-10-13 00:39:37 +11:00
Vikram Bhaskaran cbc1ce26e2 Cover timeline right-click Pre-compose grouping the whole selection (#985, #1003)
Right-clicking selected layers and choosing Pre-compose grouped only the
right-clicked layer in 0.8.0 while Layer > Pre-compose grouped all of them.
The menu plumbing was fixed since; add a regression test driving the dialog
from both the outline row and the layer bar and asserting both selected
layers end up nested in the new composition.
2026-10-13 00:35:59 +11:00
FeiLiuEM c99012a77a theme: the symbol test asks the definitions, not epaint's replacement-face check
`interface_symbols_have_a_glyph_in_every_family` (01400f0) is red on main: it asks
`Fonts::has_glyph` per symbol, which answers "does this family resolve `c` to a face other than the
family's replacement face" - and the replacement face is the first in the chain carrying epaint's
PRIMARY_REPLACEMENT_CHAR ('◻'). Inter has neither a replacement glyph nor triangles, so in the
`medium` and `semibold` families that face is the weight face itself: everything it owns (the whole
Latin set, `•`, `›`, `·`, `▶`, `◀`, `●`, `○`, `⚠`, `…`, `×`) came back as "no glyph" and only the
characters it leaves to JetBrains Mono (`▸`) answered true. Rendering is not affected - the atlas
resolves through the same chain and does find the weight face - so the assertion was wrong, not the
fonts: the bundled Inter faces carry ten of the eleven symbols and JetBrains Mono carries all eleven.

The test now asserts what the wiring promises, from the definitions that were installed: each family
draws with its own first face and its chain reaches the symbol fallback.

Verified on Linux (the test is red before and green after) with cargo fmt --all --check and
cargo test -p effectcraft-ui-egui --lib theme::tests.
2026-10-12 21:27:12 +08:00
ThemolxandClaude Opus 5.5 fcf56415dc Project panel: Replace with Precomposition (used N times)
Right-clicking a footage item or solid in the Project panel offers
"Replace with Precomposition (used N times)": the item goes into a new
composition of its size, pixel aspect and frame rate, in the same folder, and
every layer in every composition that used it switches to that composition,
keeping timing, transforms, effects and masks. One undo step. Agents run it as
`file.replaceWithPrecomp`.

The Project panel's details header also shows how often the selected item is
used ("Name ▾, used 3 times"); the ▾ lists and opens the comps that use it.
`Project::item_users` and the `project.usedIn` query back both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:14:43 +02:00
pravdomilandClaude Opus 5.5 63cfcfbb90 Timeline: UU reveals an effect's changed parameters only
The modified reveal showed every effect in full. It now compares each effect
with a new instance and reveals the parameters whose value differs, plus the
groups a new instance lacks (puppet meshes and pins, paint strokes). An effect
whose plug-in is missing still shows in full.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:13:18 +02:00
pravdomilandClaude Opus 5.5 b0ea0e787b UI: confirm before deleting a user template or a shortcut preset
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:08:06 +02:00
pravdomilandClaude Opus 5.5 fbb74339da GPU Information: Enter presses OK
The message box's only button is OK, the default; Enter now dismisses it
(back to Settings when opened from there), as Escape already does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:07:05 +02:00
FeiLiuEM dc1b048f8a text: the Chinese fallback families follow the script the locale asks for
The Han fallback list carried a Simplified and a Traditional face for every platform (Microsoft YaHei
next to Microsoft JhengHei, PingFang SC next to PingFang TC), Simplified first. The fallback search
keeps the first family whose face covers the character, and the two scripts share their code points -
only the glyph forms differ - so a zh-hant interface was drawn with Simplified forms, and a
Traditional face could not win on a machine that also had a Simplified one.

The list is now two, picked by the script the locale in force asks for: Hant, or a Taiwan, Hong Kong
or Macao region. A bare zh stays Simplified, as the interface's own locale mapping resolves it.
`asks_traditional_chinese` normalises case and separators, and `chinese_families_for` is pure, so the
choice is testable without installed fonts. The Han order and the Japanese and Korean lists are
untouched.

Verified: cargo fmt --all --check clean, cargo clippy -p effectcraft-text --all-targets -- -D warnings
clean, cargo test -p effectcraft-text 54 tests pass.
2026-10-12 20:49:02 +08:00