Shortcuts: Numpad * marks the selected layers (#976)

Numpad * always added a composition marker. As in After Effects, it now
adds a layer marker to the selected layers at the current time, and a
composition marker only when no layer is selected.
This commit is contained in:
Marco Arnulfo committed 2026-10-12 14:43:18 +02:00
1 parent 3174e68d0e
commit 424dcab40b
2 files changed
+31 -1

No files matched your search

+5
View File
@@ -1744,6 +1744,11 @@ fn handle_shortcuts_impl(app: &mut EffectcraftApp, ctx: &egui::Context, tab_only
// comes as text.
if !tab_only && clipboard && app.dialog.is_none() && ctx.input(|i| i.events.iter().any(|e| matches!(e, egui::Event::Text(t) if t == "*"))) {
let bound = app.session.shortcuts().bindings().into_iter().find(|(k, _)| *k == "Num*").map(|(_, b)| (b.command.clone(), b.params.clone()));
// As in After Effects, it marks the selected layers; only with none selected does it add
// a composition marker (#976).
let bound = bound.map(|(id, params)| {
if id == "comp.addMarker" && !app.session.state.selected_layers.is_empty() { ("layer.addMarker".to_owned(), params) } else { (id, params) }
});
if let Some((id, params)) = bound
&& let Err(e) = invoke(app, ctx, &id, if params.is_null() { json!({}) } else { params })
{
+26 -1
View File
@@ -333,13 +333,38 @@ fn dragging_out_of_the_marker_bin_adds_a_comp_marker() {
assert_eq!(markers(&h), vec![13.0]);
let history = &h.state().session.history.undo;
assert_eq!((history.len(), history.last().map(|u| u.0.as_str())), (undo + 1, Some("Add Marker")), "one undo step");
// Numpad * (it arrives as text): Add Marker at the current time.
// Numpad * (it arrives as text) with no layer selected: Add Marker at the current time.
h.state_mut().session.execute("edit.deselectAll", json!({})).unwrap();
h.state_mut().session.execute("time.set", json!({"time": 20.0})).unwrap();
h.event(Event::Text("*".into()));
h.run_steps(2);
assert_eq!(markers(&h), vec![13.0, 20.0]);
}
/// #976: as in After Effects, Numpad * marks the selected layers at the current time; only with
/// no layer selected does it add a composition marker.
#[test]
fn numpad_star_marks_the_selected_layer() {
let (mut h, layer) = harness();
let comp_markers =
|h: &Harness<'_, EffectcraftApp>| -> Vec<f64> { h.state().session.active_comp().unwrap().markers.iter().map(|m| m.time.seconds()).collect() };
let layer_markers = |h: &Harness<'_, EffectcraftApp>| -> Vec<f64> {
let comp = h.state().session.active_comp().unwrap();
comp.layer(effectcraft_engine::project::LayerId(layer)).unwrap().markers.iter().map(|m| m.time.seconds()).collect()
};
let star = |h: &mut Harness<'_, EffectcraftApp>, time: f64| {
h.state_mut().session.execute("time.set", json!({"time": time})).unwrap();
h.event(Event::Text("*".into()));
h.run_steps(2);
};
h.state_mut().session.execute("layer.select", json!({"layers": [layer]})).unwrap();
star(&mut h, 2.0);
assert_eq!((layer_markers(&h), comp_markers(&h)), (vec![2.0], vec![]));
h.state_mut().session.execute("edit.deselectAll", json!({})).unwrap();
star(&mut h, 3.0);
assert_eq!((layer_markers(&h), comp_markers(&h)), (vec![2.0], vec![3.0]));
}
/// #468: zoomed in, a CTI scrub held past the right end of the ruler scrolls the timeline (the
/// CTI rides the edge), past the left end scrolls it back; during playback the view pages to
/// keep the CTI in sight.