, secs: &mut f64, r
r
}
+/// The temp-data id of the one-shot flag that makes the Save Preset name field take focus when
+/// it is next drawn.
fn name_focus_id() -> egui::Id {
egui::Id::unique("comp-preset-name-focus")
}
diff --git a/crates/ui-egui/src/panels/dialogs.rs b/crates/ui-egui/src/panels/dialogs.rs
index fd7d43f26..47de23d59 100644
--- a/crates/ui-egui/src/panels/dialogs.rs
+++ b/crates/ui-egui/src/panels/dialogs.rs
@@ -287,6 +287,10 @@ const ABOUT_TABS: [(&str, &str); 3] = [("About", "about"), ("Contributors", "con
/// Height of the Contributors / Models tab bodies (they scroll inside it).
const CREDITS_HEIGHT: f32 = 380.0;
+/// The About dialog: tabs for the name/version/blurb, the contributors and the models (the last
+/// two scroll in a fixed-height body), the licence and bundled-font line, and Close. The tab is
+/// kept in egui temp data. A command the About body asked for is run once the modal has been
+/// built; Close clears `app.dialog`.
fn about(app: &mut EffectcraftApp, ctx: &egui::Context, t: &Tokens) {
let mut close = false;
let mut cmd: Option<&str> = None;
diff --git a/crates/ui-egui/src/panels/effect_controls.rs b/crates/ui-egui/src/panels/effect_controls.rs
index fd905b191..04f0a53a0 100644
--- a/crates/ui-egui/src/panels/effect_controls.rs
+++ b/crates/ui-egui/src/panels/effect_controls.rs
@@ -670,6 +670,11 @@ fn toggle_closed(app: &mut EffectcraftApp, g: &PropGroup, open: bool, all: bool)
}
}
+/// Lays out one property group's rows below `*y` (which it advances), recursing into open
+/// subgroups: one row per visible property with its controls, plus the dial or slider row when its
+/// slider is open, and an inline editor for groups that have one. Rows scrolled out of `rect` are
+/// skipped without being drawn or registered, though their height is still counted. Pick-whip
+/// drops are registered for each visible property; edits go on `actions`.
#[allow(clippy::too_many_arguments)]
fn group_rows(
app: &mut EffectcraftApp,
@@ -1121,6 +1126,12 @@ pub fn start_rename(ctx: &egui::Context, uid: u64, name: &str) {
ctx.memory_mut(|m| m.request_focus(id.with("field")));
}
+/// The Effect Controls panel for the selected layer: a header with the comp and layer names, then
+/// one header per effect (Fx toggle, twirl, rename, Reset, About, label bar, reorder drag and its
+/// right-click menu) followed by that effect's custom editor and its property rows. Dragging
+/// effects or presets onto the panel applies them; a right-click on empty space opens the Effect
+/// menu. The rows read from a snapshot of the project, and every edit is queued and run through
+/// [`crate::menus::invoke`], with failures reported in `app.ui.status`.
pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
let t = app.tokens;
let p = ui.painter().with_clip_rect(rect);
diff --git a/crates/ui-egui/src/panels/effects_presets.rs b/crates/ui-egui/src/panels/effects_presets.rs
index 3e4bd9275..fa7d2ac40 100644
--- a/crates/ui-egui/src/panels/effects_presets.rs
+++ b/crates/ui-egui/src/panels/effects_presets.rs
@@ -264,6 +264,13 @@ fn user_presets(ctx: &egui::Context, force: bool, scan: impl FnOnce() -> Vec (Actions, Actions) {
let t = app.tokens;
let ctx = ui.ctx().clone();
diff --git a/crates/ui-egui/src/panels/expr_bar.rs b/crates/ui-egui/src/panels/expr_bar.rs
index e40d0a2d0..ce098efa0 100644
--- a/crates/ui-egui/src/panels/expr_bar.rs
+++ b/crates/ui-egui/src/panels/expr_bar.rs
@@ -23,6 +23,8 @@ struct Cache {
current: usize,
}
+/// The `egui::Id` under which the error bar's cache for composition `cid` is kept: this pass's
+/// failing expressions and which one is shown.
fn cache_id(cid: ItemId) -> egui::Id {
egui::Id::unique(("expr-error-bar", cid.0))
}
@@ -46,6 +48,11 @@ pub fn height(app: &mut EffectcraftApp, ctx: &egui::Context, cid: ItemId) -> f32
if errors(app, ctx, cid).errors.is_empty() { 0.0 } else { HEIGHT }
}
+/// Draws the expression error strip for composition `cid` in `rect`: a warning, the shown error's
+/// description and ◀ n/m ▶ buttons to step through the failing expressions. Clicking the message
+/// selects that layer and property, reveals it in the Timeline and opens its expression. Does
+/// nothing when every expression evaluates. Stepping and clicking only change UI state (the
+/// cached index, selection and Timeline state), never the document.
pub fn draw(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect, cid: ItemId) {
let t = app.tokens;
let ctx = ui.ctx().clone();
diff --git a/crates/ui-egui/src/panels/footage_panel.rs b/crates/ui-egui/src/panels/footage_panel.rs
index 31d9beeda..64c2ced12 100644
--- a/crates/ui-egui/src/panels/footage_panel.rs
+++ b/crates/ui-egui/src/panels/footage_panel.rs
@@ -1,7 +1,8 @@
//! The Footage panel (double-click footage in the Project panel): the source on its own time
//! ruler, play / pause, In and Out marks, and the Edit Target buttons — Overlay Edit and Ripple
//! Insert Edit — that cut the marked range into the active composition at its current time.
-//! Everything runs `footage.*` commands (state in `EditorState::footage_panel`).
+//! Time, marks and edits run `footage.*` commands (state in `EditorState::footage_panel`);
+//! the Play/Pause flag is local egui state.
use crate::i18n::{tr, tr_args};
use effectcraft_engine::project::{FootageKind, ItemKind};
@@ -13,6 +14,11 @@ use super::panel_kit as kit;
use crate::EffectcraftApp;
use crate::theme::Tokens;
+/// The Footage panel for the item opened into it: the frame at the panel's current time (cached
+/// per item, time and session revision), a ruler with the in/out span and CTI that scrubs on click
+/// or drag, Play/Pause, set In/Out, and Ripple Insert / Overlay Edit into the active comp. A solid
+/// shows its colour, footage without video says so, and an empty panel explains how to open one.
+/// Time changes run `footage.*` commands; the panel's Play/Pause flag is local egui state.
pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
let t = app.tokens;
let ctx = ui.ctx().clone();
diff --git a/crates/ui-egui/src/panels/forms.rs b/crates/ui-egui/src/panels/forms.rs
index 942bd9fe0..15d9100f8 100644
--- a/crates/ui-egui/src/panels/forms.rs
+++ b/crates/ui-egui/src/panels/forms.rs
@@ -152,7 +152,7 @@ fn is_pdf(p: &Value) -> bool {
}
/// File ▸ Import ▸ File… picked numbered stills that import as image sequences: ask, as After
-/// Effects' " Sequence" checkbox in its Import dialog does (rfd's native dialog can't
+/// Effects' ` Sequence` checkbox in its Import dialog does (rfd's native dialog can't
/// carry a checkbox), with Force Alphabetical Order and the frame rate. `p`: the import's
/// parameters. Returns whether the dialog opened. The checkbox starts off, as in After Effects:
/// unticked, the picked files import as stills. Dropped files and agents' `file.import` don't
diff --git a/crates/ui-egui/src/panels/fx_editors.rs b/crates/ui-egui/src/panels/fx_editors.rs
index 9171349f8..b7b09dad4 100644
--- a/crates/ui-egui/src/panels/fx_editors.rs
+++ b/crates/ui-egui/src/panels/fx_editors.rs
@@ -111,6 +111,8 @@ fn tabs(
out
}
+/// A small "Reset" link centred in `r`, registered under the automation id `id`; returns whether
+/// it was clicked.
fn reset_link(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::Painter, r: Rect, id: &str) -> bool {
let t = app.tokens;
let resp = ui.interact(r, egui::Id::unique(id), Sense::click());
@@ -162,6 +164,10 @@ pub fn inline_editor(
const RGB_CURVES: [(&str, &str); 4] = [("master", "Master"), ("red", "Red"), ("green", "Green"), ("blue", "Blue")];
+/// The Lumetri RGB Curves editor for effect group `g`: channel tabs (Master, Red, Green, Blue),
+/// the selected channel's curve graph with its Reset, and the point positions registered for
+/// automation. A curve edit or Reset is queued on `actions` as a `prop.set` of that channel's
+/// curve string; the visible channel is remembered in `app.ui.fx_curve_channel` per group.
#[allow(clippy::too_many_arguments)]
fn rgb_curves(
app: &mut EffectcraftApp,
@@ -269,6 +275,11 @@ fn hue_color(h: f32) -> Color32 {
Color32::from(c)
}
+/// The Lumetri Hue/Saturation Curves editor for effect group `g`: tabs for the Hue vs Sat,
+/// Hue vs Hue, Hue vs Luma, Luma vs Sat and Sat vs Sat curves, drawn as a neutral-relative offset
+/// curve over the axis' colour band, with point drag/add/remove gestures and a Reset. Changes are
+/// queued on `actions` as a `prop.set` of the selected curve's point list; the visible tab is kept
+/// in `app.ui.fx_curve_channel` per group.
#[allow(clippy::too_many_arguments)]
fn huesat_curves(
app: &mut EffectcraftApp,
@@ -441,6 +452,12 @@ fn wheel_point(c: Pos2, radius: f32, phase: f32) -> Pos2 {
pos2(c.x + radius * a.sin(), c.y - radius * a.cos())
}
+/// Colorama's Output Cycle wheel for effect group `g`: the palette drawn as a ring with its stops.
+/// Clicking the ring adds a stop with the colour there, dragging moves one, and Alt-clicking or
+/// dragging one off removes it while another stop remains; the selected stop's colour can be
+/// edited below. A change queues
+/// the rewritten palette on `actions`, and for a preset palette also switches the effect to the
+/// custom palette in the same undo step.
#[allow(clippy::too_many_arguments)]
fn colorama_wheel(
app: &mut EffectcraftApp,
@@ -657,6 +674,10 @@ pub fn join_map(m: &[fw::CurvePoints; 3]) -> String {
m.iter().map(|c| c.format()).collect::>().join(" | ")
}
+/// Glow's Colour Map for effect group `g`: a strip showing the gradient the glow uses (A/B colours,
+/// or the arbitrary map sampled through the loop settings). In arbitrary-map mode it also draws the
+/// RGB curve tabs and the selected channel's graph with a Reset; edits queue a `prop.set` of
+/// `arbitraryMap` on `actions`.
#[allow(clippy::too_many_arguments)]
fn glow_map(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::Painter, layer: &Layer, g: &PropGroup, ectx: &EvalCtx, r: Rect, actions: &mut Actions) {
let t = app.tokens;
@@ -769,6 +790,10 @@ pub fn add_pair(v: &[(f64, f64)]) -> (f64, f64) {
((a.0 + ds * 0.5).rem_euclid(1.0), (a.1 + gap * 0.5).rem_euclid(1.0))
}
+/// Reshape's correspondence buttons: Add Point appends a pair at the widest destination-fraction
+/// gap (or `(0, 0)` for an empty list), Remove Point drops the last stored pair, and Clear removes
+/// all pairs. A status line says whether points are automatic. Each change
+/// queues a `prop.set` of the `correspondencePoints` string on `actions`.
#[allow(clippy::too_many_arguments)]
fn reshape_buttons(
app: &mut EffectcraftApp,
diff --git a/crates/ui-egui/src/panels/gradient_editor.rs b/crates/ui-egui/src/panels/gradient_editor.rs
index 9db4d6163..fe10f4ddb 100644
--- a/crates/ui-egui/src/panels/gradient_editor.rs
+++ b/crates/ui-egui/src/panels/gradient_editor.rs
@@ -246,6 +246,12 @@ fn to_color32(c: [f32; 4]) -> Color32 {
Color32::from_rgba_unmultiplied(b(c[0]), b(c[1]), b(c[2]), b(c[3]))
}
+/// The Gradient Editor dialog for the gradient in `app.dialog_state.gradient`: a stop track for
+/// the opacity and colour tracks over a checkerboard preview, the selected stop's location,
+/// opacity or colour and a Delete button (when its track has more than one stop), the
+/// mismatched-stop-count warning, and OK/Cancel. Dragging moves stops, Delete/Backspace removes the
+/// selected one unless a widget wants keyboard input. OK runs the commit path; Cancel closes the dialog and drops the
+/// draft. With no gradient target it closes the dialog.
pub fn show(app: &mut EffectcraftApp, ctx: &egui::Context, t: &Tokens) {
if app.dialog_state.gradient.target.is_none() {
app.dialog = None;
diff --git a/crates/ui-egui/src/panels/graph.rs b/crates/ui-egui/src/panels/graph.rs
index fa082040c..66ba31470 100644
--- a/crates/ui-egui/src/panels/graph.rs
+++ b/crates/ui-egui/src/panels/graph.rs
@@ -189,6 +189,9 @@ const MORE_POPUP: &str = "graph-more";
impl ButtonBar {
const MORE_W: f32 = 24.0;
+ /// A bar starting 8 points into `bar`, stopping short of its right end by the "»" button's
+ /// width. It takes the id picked from the "»" menu in the previous frame, so the button whose
+ /// id that was reports a click on the frame after the pick.
fn new(ctx: &egui::Context, bar: Rect) -> Self {
let chosen = ctx.data_mut(|d| d.remove_temp::(egui::Id::unique(MORE_POPUP).with("chosen")));
ButtonBar { x: bar.min.x + 8.0, limit: bar.max.x - 8.0 - Self::MORE_W - 4.0, hidden: Vec::new(), chosen }
@@ -233,6 +236,10 @@ impl ButtonBar {
}
}
+/// One text button of the Graph Editor's button bar at the bar's current `x`, in the toolbar row
+/// at `y`: draws it, registers it for automation and advances the bar. Once a button does not fit
+/// (or a previous one overflowed), the button goes to the "»" menu instead and only the id the
+/// menu picked reports a click. Returns whether this button was chosen.
fn text_button(
app: &mut EffectcraftApp,
ui: &mut egui::Ui,
@@ -627,6 +634,8 @@ fn fit_all(app: &mut EffectcraftApp) {
app.ui.timeline.pps = None;
}
+/// The `egui::Id` of the one-shot flag [`track_open`] sets when the Graph Editor is switched on,
+/// so [`show`] frames all graphs on its next pass, once the plot rectangle is known.
fn fit_pending_id() -> egui::Id {
egui::Id::unique("graph-fit-pending")
}
@@ -739,6 +748,8 @@ struct KeyGrab {
t: f64,
}
+/// The `egui::Id` of the key drag in progress ([`KeyGrab`]): where the button went down and the
+/// grabbed key's comp time when it did.
fn key_grab_id() -> egui::Id {
egui::Id::unique("graph-key-grab")
}
@@ -786,6 +797,8 @@ impl HandleGrab {
/// A handle drag: where the button went down, and the handles that move.
type HandleDrag = (Pos2, Vec);
+/// The `egui::Id` of the Bezier handle drag in progress ([`HandleDrag`]): the press position and
+/// the handles the drag moves.
fn handle_drag_id() -> egui::Id {
egui::Id::unique("graph-handle-drag")
}
diff --git a/crates/ui-egui/src/panels/graph_tools.rs b/crates/ui-egui/src/panels/graph_tools.rs
index ee5d7543f..7950d4a66 100644
--- a/crates/ui-egui/src/panels/graph_tools.rs
+++ b/crates/ui-egui/src/panels/graph_tools.rs
@@ -34,6 +34,7 @@ struct BoxDrag {
last: [f64; 2],
}
+/// The `egui::Id` of the transform-box drag in progress ([`BoxDrag`]).
fn box_id() -> egui::Id {
egui::Id::unique("graph-transform-box")
}
@@ -254,6 +255,7 @@ struct AltScale {
span: Option,
}
+/// The `egui::Id` of the Timeline Alt-drag group scale in progress ([`AltScale`]).
fn alt_id() -> egui::Id {
egui::Id::unique("timeline-alt-scale")
}
diff --git a/crates/ui-egui/src/panels/info.rs b/crates/ui-egui/src/panels/info.rs
index a075087d3..86a1e6444 100644
--- a/crates/ui-egui/src/panels/info.rs
+++ b/crates/ui-egui/src/panels/info.rs
@@ -6,6 +6,11 @@ use egui::{Align2, Color32, Rect, pos2, vec2};
use crate::theme::Tokens;
use crate::{EffectcraftApp, widgets};
+/// The Info panel: the colour and alpha under the pointer (sampled from the shown viewer frame,
+/// read back for GPU frames) with its position and a swatch, then the selected layers, the current
+/// time, the duration/In/Out of a single selected layer, the achieved preview frame rate, the
+/// render time and queue state (when the preference asks for it) and the selected keyframe's
+/// property, time and value. Read-only: it draws and scrolls but changes no document state.
pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
let t = app.tokens;
let p = ui.painter().with_clip_rect(rect);
diff --git a/crates/ui-egui/src/panels/layer_panel.rs b/crates/ui-egui/src/panels/layer_panel.rs
index 2ebb2dee0..f6157da47 100644
--- a/crates/ui-egui/src/panels/layer_panel.rs
+++ b/crates/ui-egui/src/panels/layer_panel.rs
@@ -40,10 +40,14 @@ struct Tex {
rect: [f64; 4],
}
+/// The `egui::Id` of the cached render of the layer shown in this panel ([`Tex`]), with the key
+/// the image was made from.
fn tex_id() -> egui::Id {
egui::Id::unique("layer-panel-tex")
}
+/// The `egui::Id` under which the panel's last Fit magnification is kept, so View ▸ Zoom In/Out
+/// can start from it (see [`last_fit`]).
fn fit_id() -> egui::Id {
egui::Id::unique("layer-panel-fit")
}
@@ -83,6 +87,13 @@ fn default_view(layer: &Layer, tool: Tool) -> usize {
}
}
+/// The Layer panel: one layer in its own space with its masks and effects up to the View menu's
+/// choice, rendered synchronously at a zoom/pan the panel keeps (the last Fit magnification is
+/// published for the View menu). Wheel or pinch zooms about the pointer, the Hand tool or
+/// Space-drag pans, and the Zoom tool clicks zoom. The paint tools record a stroke's layer-space
+/// points while dragging and run `paint.stroke` on release (or on a click); Alt-click with the
+/// Clone Stamp sets its source. With a Roto Brush effect it hands the canvas to
+/// [`super::roto_tool`]. Without a current layer it shows how to open one.
pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
let t = app.tokens;
let ctx = ui.ctx().clone();
diff --git a/crates/ui-egui/src/panels/layer_styles_dialog.rs b/crates/ui-egui/src/panels/layer_styles_dialog.rs
index e687dffa1..a4af4dae2 100644
--- a/crates/ui-egui/src/panels/layer_styles_dialog.rs
+++ b/crates/ui-egui/src/panels/layer_styles_dialog.rs
@@ -61,7 +61,7 @@ pub fn open(app: &mut EffectcraftApp, params: &Value) -> Result<(), String> {
Ok(())
}
-/// Menu routing: choosing one of the Layer ▸ Layer Styles ▸