Keeping OK and Cancel in view took away the outer scroll area that also
scrolled the dialog sideways, and the controls only scrolled up and
down. In a narrow window (960x600 at 200 % UI Scale leaves the controls
about 190 points next to the 200-point list) they ran past the dialog's
right edge with no way to reach them.
The controls now scroll both ways in the room left under their heading,
with no minimum scrolled size, so a small budget can't hide the end of
them; the list scrolls in its height the same way. Each control also
registers dialog.layerStyle.value.<style>/<path> next to its label's id.
Tests:
- layer_style_controls_stay_reachable_in_a_small_window: in a 960x600
window at 200 %, and opened large then narrowed, Noise is scrolled to,
painted whole and dragged; fails before (it lies past the window).
- layer_style_buttons_stay_in_view now checks both buttons at 100 % and
200 %, each case in a fresh app with a real edit: OK keeps it, Cancel
puts the project and its undo history back as before the dialog.
epaint's has_glyph compares face keys, so a glyph drawn by the replacement
face reads as missing. With no face in the stack covering egui's `◻`, Inter's
`?` becomes the replacement and Inter's `•` fails the check, which happens
once another test (the #1141 one) has loaded a system face without `◻`: the
fallback tries loaded faces first. Compare the drawn glyph with the
replacement glyph instead, as assert_drawn already does.
The Layer Style dialog's OK and Cancel came after the style list and
the style's controls in one scroll area, and at its usual size they
were laid out past the dialog's bottom edge: clipped, and a click on
them did nothing until the dialog was scrolled.
The dialog now uses above_footer: OK and Cancel sit at its bottom right
and the list and the controls scroll above them, also at 200 % UI
Scale.
Test: layer_style_buttons_stay_in_view (both buttons painted whole and
clicked, at 100 % and 200 %; fails before: Cancel isn't painted).
Settings keeps its buttons in view by laying them out first, at the
bottom of its body, and giving its pages the height left above them,
clipped to it. That layout is now dialogs::above_footer, so other
dialogs can keep their buttons in view the same way. Settings looks and
works as before.
Adding a marker replaced the comp, so every cached frame stopped matching and the preview had to
re-render before its audio could carry on. Plain markers change no pixels; protected time markers
with a duration still do (Responsive Design). Markers count in full again when a project uses
expressions, which can read them.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
The layer bar Quick Offset was followed and ended in its row's code, and
rows out of view aren't drawn. Released with its row scrolled away, it
stayed active: the next drag of that bar, even a plain one, ran as a
Quick Offset from the old origin, into the old undo step.
Like the key drag, it now follows the pointer below the rows and ends
when the button is released, wherever the bar's row is.
Test: a_quick_offset_released_off_screen_ends (release with the row
scrolled away; a plain drag after it moves both layers together as its
own undo step; fails before).
The Chinese UI fallback was chosen by probing 文, which Japanese faces
cover too. Fallback takes a face already loaded first, so after the
English interface had loaded a Japanese face for kana, switching to
Simplified Chinese reused it, and the simplified-only hanzi (选, 删,
层, 设, 页 ...) drew as boxes. A Simplified Chinese interface now probes
页, as wordcraft does for its interface font (storytold/wordcraft#248).
Ctrl/Cmd+Alt dragging a selected layer bar or a selected key now runs a
Quick Offset (layer.quickOffset / keys.quickOffset with fromStart, one
undo step). The mode is chosen when the drag starts and needs at least
two unlocked layers; the last selected layer moves by whole frames with
the pointer. A readout by the pointer shows the Total Offset and the
offset Per Layer, translated.
A plain drag still moves the selection together, Alt alone still scales
a key group in time (it now leaves Ctrl/Cmd+Alt to Quick Offset), and
Ctrl/Cmd+Alt+click still toggles Hold. The key drag's readout is drawn
by a shared drag_tip. Keys also register timeline.keyAt.<uid>.<ticks>,
exact where keys on subframes can share a frame.
Tests (ui_quick_offset): staggering layer bars in selection order and
keys per layer, one undo each; plain drags and Alt scaling unchanged; the
readout while dragging.
The layer context menu gains an Effects submenu between Blending Mode and Arrange, mirroring the After Effects layer menu: the effect registry grouped by category (sorted), synced with the Effect menu; picking one applies it to the selected layers.
The handle was filled with the colour of its own track (both the field
background), so it only showed while hovered or dragged. It now takes the text
colour, in every scroll area.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Enter closes the editor like its OK button, also while the search field has
focus. It stays with the shortcut recorder (Enter can be recorded), the preset
rename field and an open preset menu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The floating group's title strip used the same id as its Area's own
background widget, and the Area was shifted back into the window while
the group's rect kept moving, so the two no longer overlapped and egui
painted "Double use of widget ID" over the panel. The strip has its own
id and the group is drawn where its rect says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The editor's content was a little taller than its dialog, so the outer scroll
area clipped the OK button and its scrollbar covered the right edge. The dialog
now has no outer scroll area: the command list takes whatever height is left,
so the button row always fits, in small windows too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Undoes the 800 px Project Settings width from #980: the form is back at the
shared 480 px.
A form's choice popup keeps its 240 px column and ends a long choice (a GPU
adapter's name) in an ellipsis instead of widening the grid past the dialog.
Only the fields scroll, and only vertically; OK and Cancel sit under the
scroll area, so they stay in view.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
window.toggleCompTimeline (\) switches between the Composition viewer
and the Timeline. window.previousPanel / nextPanel (Alt+Shift+, / .)
step through the tabs of the focused panel's frame. window.closeAll
(Cmd+Shift+W) closes every open composition when a viewer or the
Timeline is active, otherwise the focused panel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Guides can store a percent of the comp so they follow comp-size changes
(View > Add Percentage Guide, Convert Guides to Percentage / Pixels); an
effect instance has an optional colour label (effect.setLabel, Effect Controls
header bar and Label menu). Both are serde-defaulted, so old projects load.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>