Timeline: Markers ▸ Add Marker in the layer context menu (#976)

Right-clicking a layer offered no way to mark it. The layer context menu
now has After Effects' Markers submenu with Add Marker (layer.addMarker,
as Layer ▸ Markers ▸ Add Marker), which marks the right-clicked layer, or
the selection it belongs to, at the current time. The submenu title reuses
the menu catalogs' "Markers" translation in the panel catalogs.
This commit is contained in:
Marco Arnulfo committed 2026-10-12 14:43:18 +02:00
1 parent 9efe75330c
commit 3174e68d0e
3 files changed
+38

No files matched your search

+6
View File
@@ -295,6 +295,7 @@ const JAPANESE: &[(&str, &str)] = &[
("MIT OR Apache-2.0 • Fonts: Inter, JetBrains Mono (OFL)", "MIT OR Apache-2.0 • フォント:Inter、JetBrains Mono (OFL)"),
("Magnification ratio popup", "拡大率のポップアップ"),
("Make Comp Size", "コンポジションサイズにする"),
("Markers", "マーカー"),
("Masks", "マスク"),
("Maximize Panel", "パネルを最大化"),
("Media Replacement", "メディアの置き換え"),
@@ -742,6 +743,7 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
("MIT OR Apache-2.0 • Fonts: Inter, JetBrains Mono (OFL)", "MIT 或 Apache-2.0 • 字体:Inter、JetBrains Mono(OFL)"),
("Magnification ratio popup", "放大倍率弹出菜单"),
("Make Comp Size", "设为合成长宽"),
("Markers", "标记"),
("Masks", "蒙版"),
("Maximize Panel", "最大化面板"),
("Media Replacement", "媒体替换"),
@@ -1277,6 +1279,7 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
("MIT OR Apache-2.0 • Fonts: Inter, JetBrains Mono (OFL)", "MIT 或 Apache-2.0 • 字型:Inter、JetBrains Mono(OFL)"),
("Magnification ratio popup", "放大倍率快顯選單"),
("Make Comp Size", "設為合成長寬"),
("Markers", "標記"),
("Masks", "遮色片"),
("Maximize Panel", "最大化面板"),
("Media Replacement", "媒體替換"),
@@ -1815,6 +1818,7 @@ const UKRAINIAN: &[(&str, &str)] = &[
("MIT OR Apache-2.0 • Fonts: Inter, JetBrains Mono (OFL)", "MIT OR Apache-2.0 • Шрифти: Inter, JetBrains Mono (OFL)"),
("Magnification ratio popup", "Меню коефіцієнта збільшення"),
("Make Comp Size", "За розміром композиції"),
("Markers", "Маркери"),
("Masks", "Маски"),
("Maximize Panel", "Розгорнути панель"),
("Media Replacement", "Заміна матеріалу"),
@@ -2351,6 +2355,7 @@ const PORTUGUESE: &[(&str, &str)] = &[
("MIT OR Apache-2.0 • Fonts: Inter, JetBrains Mono (OFL)", "MIT OU Apache-2.0 • Fontes: Inter, JetBrains Mono (OFL)"),
("Magnification ratio popup", "Menu de proporção de ampliação"),
("Make Comp Size", "Ajustar ao tamanho da composição"),
("Markers", "Marcadores"),
("Masks", "Máscaras"),
("Maximize Panel", "Maximizar painel"),
("Media Replacement", "Substituição de mídia"),
@@ -2795,6 +2800,7 @@ const CZECH: &[(&str, &str)] = &[
("MIT OR Apache-2.0 • Fonts: Inter, JetBrains Mono (OFL)", "MIT OR Apache-2.0 • Písma: Inter, JetBrains Mono (OFL)"),
("Magnification ratio popup", "Nabídka míry přiblížení"),
("Make Comp Size", "Nastavit velikost kompozice"),
("Markers", "Značky"),
("Masks", "Masky"),
("Maximize Panel", "Maximalizovat panel"),
("Media Replacement", "Nahrazení médií"),
+3
View File
@@ -3569,6 +3569,9 @@ pub(crate) fn layer_menu(ui: &mut egui::Ui, layers: &[u64], vector: bool, action
item(ui, "Freeze Frame", "layer.freezeFrame", json!({"layers": layers}));
item(ui, "Freeze on Last Frame", "layer.freezeOnLastFrame", json!({"layers": layers}));
});
ui.menu_button(crate::i18n::tr("Markers"), |ui| {
item(ui, "Add Marker", "layer.addMarker", json!({"layers": layers}));
});
ui.menu_button(crate::i18n::tr("Blending Mode"), |ui| {
widgets::menu_scroll(ui, |ui| {
for m in BlendMode::ALL {
@@ -226,3 +226,32 @@ fn context_menu_rows_leave_no_gap_between_them() {
}
snapshot(&mut h, "project-rows");
}
/// #976: a layer's context menu has After Effects' Markers ▸ Add Marker, which marks the layer that
/// was right-clicked (not the one selected before, and not the composition) at the current time.
#[test]
fn layer_context_menu_adds_a_layer_marker() {
let mut h = harness();
let solid = |h: &mut Harness<'_, EffectcraftApp>, name: &str| -> u64 {
h.state_mut().session.execute("layer.newSolid", json!({"name": name, "color": "#406080"})).unwrap()["layer"].as_u64().unwrap()
};
let (below, top) = (solid(&mut h, "Below"), solid(&mut h, "Top"));
h.state_mut().session.execute("layer.select", json!({"layers": [below]})).unwrap();
h.state_mut().session.execute("time.set", json!({"time": 1.5})).unwrap();
h.run_steps(3);
let r = rect(&h, &format!("timeline.layer.{top}.row"));
right_click(&mut h, pos2(r.min.x + 210.0, r.center().y));
h.get_by_label("Markers ⏵").click();
h.run_steps(3);
snapshot(&mut h, "layer-markers");
h.get_by_label("Add Marker").click();
h.run_steps(3);
let now = h.state().session.time().seconds();
let comp = h.state().session.active_comp().unwrap();
let markers = |id: u64| -> Vec<f64> { comp.layer(effectcraft_engine::project::LayerId(id)).unwrap().markers.iter().map(|m| m.time.seconds()).collect() };
assert_eq!(markers(top), vec![now]);
assert!((now - 1.5).abs() < 0.01, "at the current time: {now}");
assert!(markers(below).is_empty(), "{:?}", markers(below));
assert!(comp.markers.is_empty(), "no composition marker");
assert_eq!(h.state().session.history.undo.last().map(|u| u.0.as_str()), Some("Add Marker"));
}