Expand description
Timeline widget (custom painted). Header column (track name, M/S buttons, height drag handle at the bottom edge), ruler (ticks, in/out markers, click/drag scrubs), track lanes (video tracks top→bottom = Vn..V1, then A1..An), clips (name, waveform for audio via WaveformCache, keyframe diamonds, disabled = dimmed, selected = accent outline), playhead (drag by ruler or line).
Interaction: click select (Ctrl toggles), drag clip body = move (linked clips follow; Project::move_clips
all-or-nothing; up/down across tracks of the same kind), drag clip edges = trim (Clip::trim_start /
trim_end with Project::max_clip_duration), snapping (playhead, clip edges, in/out, 0; ~8 px) when
snap, right-click context menu (Split, Delete, Ripple Delete, Link/Unlink, Enable/Disable, Add
Video/Audio Track, Remove Track (on headers), Mute/Solo). Ctrl+Scroll = zoom around the cursor,
Shift+Scroll = horizontal pan, Alt+Scroll = height of the track under the cursor, plain scroll =
vertical pan. Accepts egui dnd payloads DragPayload (Asset → Project::insert_asset_clips at the drop
time/track; Path → returned in dropped_files; Effect / Transition → the clip under the pointer is
outlined while dragging and reported in dropped_other, so a card lands straight on that clip).
Every mutation calls c.undo(&project) with the project as
it was before the gesture (once per gesture, only if it changed something) and sets edited. While playing,
auto-scroll keeps the playhead visible unless the user panned away (resumes once the playhead re-enters the
view or playback pauses).
Round 2: horizontal/vertical scrollbars (thumb drag + click-to-page), edge auto-scroll during drags, linked selection (click = link group, Alt+click = single, linked clips get a thin outline), audio volume line (dB mapped, draggable) + fade handles, video track V/S headers, full-width track resize handles, draggable keyframe diamonds with an easing context menu, transition bands (edge drag = duration, right-click = remove), colour labels / sequence tint, speed badges, thumbnail filmstrips (ThumbCache), auto-cut keep-range shading and Sequence open-on-double-click.
Round 3: rubber-band select on empty lane space (Shift adds; dragging any selected clip moves the whole
selection as one undo step), drag past the top video / bottom audio row to drop onto a freshly created
track (gutter preview, Esc cancels the gesture), keyframe diamonds in a value lane on tall clips (y =
value, x = time, tooltip, one undo per gesture), project markers on the ruler and clip markers inside
clips (click selects, double-click seeks, drag moves, right-click = Rename / Delete / Set label),
clip colours from Project.labels, hatched Adjustment layers with an “adj” badge, and the Add Marker /
Copy & Paste Attributes / Add Mask / Nest / Convert to Adjustment Layer context-menu entries.
Structs§
Enums§
- Act 🔒
- Deferred project mutation (collected while the project is borrowed for drawing).
- Cap 🔒
- What a header toggle paints: a picture, or a plain character.
- Gesture 🔒
Constants§
- DB_BOT 🔒
- DB_TOP 🔒
- Volume line dB range: +12 dB at the top of the clip, -60 dB at the bottom, 0 dB at 70 % height.
- EDGE_W 🔒
- FLAG_W 🔒
- Marker flag size on the ruler / inside clips.
- GUTTER_
H 🔒 - Insertion gutter shown when clips are dragged past the first/last row.
- HANDLE_
H 🔒 - HBAR_H 🔒
- Scrollbar strip thickness (points).
- KEY_
LANE_ 🔒MIN - Clip height from which keyframe diamonds move into a value lane (y = value) instead of the bottom strip.
- KEY_PAD 🔒
- Inset of the value lane inside the clip rect (points), top and bottom.
- MAX_
TRACK_ 🔒H - MIN_
TRACK_ 🔒H - RULER_H 🔒
- SCROLL_
MARGIN 🔒 - Edge auto-scroll kicks in within this many points of the lanes edge.
- SNAP_PX 🔒
- SUB_
LANE_ 🔒H - Height of the subtitle lane pinned under the ruler (shown only when the project has cues).
- TICKS 🔒
- (major tick, minor tick) seconds; the first major that spans >= 80 px wins.
- VBAR_W 🔒
Functions§
- clip_
menu 🔒 - db_frac 🔒
- dB → fraction of the clip height measured from the bottom. Piecewise linear: -60 dB = 0, 0 dB = 0.7, +12 dB = 1 (so unity gain sits at 70 % height and the usable attenuation range gets most of the clip).
- diamond 🔒
- draw_
filmstrip 🔒 - Filmstrip of source-time thumbnails across a video/image clip. Non-blocking: misses are queued in the ThumbCache worker and painted on a later frame.
- draw_
waveform 🔒 - One vertical min..max line per point column over the visible part of an audio clip.
- drop_
on_ 🔒clip - The clip under a drop at screen
pos/ timeline timet, with its lane rect — what an effect or a transition dragged out of its panel is aimed at (app.rsresolves the same clip from the reported time + track when the drop actually happens). - flag 🔒
- Marker flag: a stem down from
topwith a pennant to the right. - frac_db 🔒
- gain_db 🔒
- has_
keys 🔒 - Does the clip have any keyframe at all? Cheap (no allocation), unlike
Clip::key_times, so the 1000-clip case never touches the keyframe path. - hatch 🔒
- Diagonal hatching (adjustment layers read as “applies to everything below”).
- key_
range 🔒 - Value range the diamonds of
propare mapped through: the live auto-range, or the one frozen at the start of the drag so the dragged key does not push its own scale around. - label_
color 🔒 - label_
menu 🔒 - Colour submenu: the project’s own labels (name + colour), not the built-in defaults.
- marker_
hit 🔒 - Shared marker interaction (ruler flags and clip flags): click selects, double-click seeks, drag moves, right-click = Rename / Delete / Set label.
- nearest 🔒
- Nearest candidate within
throft. - paste_
clips - paste_
menu 🔒 - Paste a copied group (relative times, the way
presets::capture_templatestores one) atat, with fresh clip / link / marker ids.Project::place_clipspicks the first track of each kind with room (adding one when nothing is free);targetthen pulls the group onto the row the user last clicked, if the whole group fits there. The paste flavours, shared by every timeline context menu. The app decides whether the clipboard actually holds anything — a menu that hid itself when empty would just look broken. - prop_
range 🔒 - The range the rest of the UI enforces for property
i(inspector sliders for the base props,ParamSpecfor effect params), so a value-lane drag cannot write past what aDragValueallows.Nonewhere nothing enforces one: Position X/Y and Rotation are unbounded everywhere, and Volume is a gain behind a nonlinear dB slider. ponytail: same property order as curves.rs — move it next toprop_refif a second caller shows up. - row_
order 🔒 - Display order: video tracks reversed (Vn on top, V1 just above audio), then A1..An.
- row_top 🔒
- Top y of track
tiin display order (absolute points). - show
- snap_
playhead 🔒 - Frame-quantise a pointer time and pull it onto the nearest snap candidate. Every tool that turns a pointer x into a time goes through here, so the razor, the marker tool, marker drags and media drops land on the same edges that moves and trims already snap to. Where the playhead lands when snapping is on: clip edges, in/out and 0, but NOT the playhead itself, which would always be the nearest candidate and pin it where it already is.
- snap_
target 🔒 - Snap target for
t: 0, playhead, in/out, edges of clips not inexclude— withinthrseconds. - snap_
time 🔒 - tick_
label 🔒 - tick_
step 🔒 - (major, minor) tick spacing in seconds for a zoom (px/s).
- toggle_
button 🔒 - wave_
color 🔒 - Wave colour of an audio clip: the plain palette green while it has no label, otherwise its own (already computed) body colour pushed to the opposite end of the brightness scale — the body is painted in that colour, so an unshifted wave would be invisible on it.