Dragging an integer setting applied every step, so UI Scale resized the
interface under the pointer mid-drag. A dragged value now shows in its
field and applies when the button is released (a typed one already
waited for Enter).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test opened its project before the window existed, so its 'GPU' frames could be the ones the CPU composited while the compositor was built. It now waits for the compositor (ui_gpu::wait_for_compositor, made pub(crate)) and then opens the project, as the PR does for ui_gpu.rs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A docked ScriptUI panel only ever saw its preferredSize: the host drew
it in a scroll area at max(dock, preferred) and the script's window never
learned the dock. scriptui.resize now gives a window a size: the script's
window takes it, lays itself out again and runs onResizing / onResize.
The dock host sends it whenever the panel's dock size changes, so
window.size is the dock's, as in After Effects.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clicking an effect, Layer Style, mask or shape item row in the Timeline
always replaced the selection, so one animation preset couldn't hold
several effects and styles. Shift or Cmd/Ctrl now adds the group to the
selection, or takes a selected one out, as property rows and Effect
Controls headers already do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add Per-Corner Roundness to Rectangle Path: a checkbox (off by default) and four Pixels properties (top-left, top-right, bottom-right, bottom-left). New rectangles initialise the four values from their Roundness, so ticking the box keeps the shape; the radii are animatable and expression-driven.\n\nrect_radii() builds the path clockwise from the top-left with kappa quarter-circle arcs. Overlapping radii scale down like CSS border-radius; negative and non-finite radii are square; rect() delegates to it, so uniform roundness clamps to half the shorter side as before.\n\nLottie rc has one r: four equal static radii export as that value; mixed or animated radii export roundness 0 with a warning. Import puts r into the four per-corner values so ticking the box on an imported rectangle keeps the shape.\n\nTests: path geometry and clamping, rendered per-corner pixels, Lottie equal/mixed/checkbox-off export.
#2054's own merge of main re-added zh-hans/zh-hant rows that main already
had, so catalogs_are_unique_and_keep_the_english_shape failed on main.
The catalog is the batch-tested one, with ('ka', GEORGIAN_PANELS) back in
ROWS (the batch's merge helper had folded it into the first 'ka' entry).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A drag that started on a script control stopped at the window edge:
moves outside were dropped and a release outside never reached the
control. While a button is held, the control it was pressed on now gets
the moves (with screen and control-relative coordinates) and the
release, wherever the pointer is, as in After Effects. Every MouseEvent
also carries buttons (held: 1 left, 2 right, 4 middle), so a handler can
tell a drag from a hover; scriptui.mouse accepts it too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolve the two conflicts the panel catalogs and the Composition Settings
rewrite left:
- i18n/ui.rs: keep both sides' rows in the Simplified and Traditional Chinese
catalogs, which grew at the same anchor (the PR's 301 panel/dialog rows, then
main's 43 tool and Preview-panel rows). The tables are grouped by feature, not
sorted by key, so the two blocks sit one after the other. Both sides also added
"Frame Rate" once: keep one row per catalog, main's 影格速率 in Traditional
(matching the table's existing 影格速率:) and 帧速率 in Simplified.
- comp_settings.rs: take main's rewritten tab_body (it returns () and matches on
the tab, and show() measures the tabs) and re-apply the wrapping the old layout
had: the three tab labels go through tr(), as Basic, Advanced and 3D Renderer
already have rows. The old horizontal layout and its out accumulator are gone.
cargo test -p effectcraft-ui-egui --lib: 336 passed, 0 failed, 3 ignored.
The job reports its times when a frame finishes, so with slow frames the
Current Render strip held the same Est. Remain long enough to look
stalled, then jumped. Between reports both times now count on from the
last one, as a clock does (remaining never below zero, a finished job
stands still), and the panel repaints twice a second while rendering.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the compositor built on a worker thread, the parity test's first
frame could be composited on the CPU while the build ran. Frame keys
don't name the compositor (by design: the disk cache serves frames from
either), so after the hand-over the viewer could keep showing that CPU
frame, and the GPU-vs-CPU comparison would pass comparing the CPU with
itself. The test now waits for the compositor, then opens the project
and sets the time, so every frame it compares was requested with the
compositor attached.
(`viewer_on_gpu()` can't tell here: on the desktop GPU frames are read
back into CPU images, and only the browser draws them from their texture.)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The status line is the toast that clears itself after 5 s, so the
preparing notice went blank while the viewer was still on the CPU for the
rest of a cold-cache build (tens of seconds), though `init_gpu` says the
status bar tells the user so. draw_toast now leaves that one status up
while `gpu_initializing()`; `finish_gpu_build` clears it when the
compositor lands, and the worker's repaint brings that frame, so the
toast doesn't tick meanwhile. A click still dismisses it; every other
status clears as before.
Test: with the build held on its gate, 30 more steps (7.5 s) leave the
status as it was; before this change it was empty by then.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>