From d2ccf737a8808404fca28fd256d509f74ca4c784 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sat, 3 Oct 2026 00:11:19 -0400 Subject: [PATCH] M13.5: Layer Style dialog LYR-9: Layer > Layer Styles > Layer Style Options... (layer.style.options) and choosing a style from that menu open a Layer Style dialog: style list with check boxes (Blending Options first) and the selected style's controls built from its layerStyles properties, edited live through prop.set (one undo step per control); Cancel rolls back everything done since it opened. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/commands/frontend.rs | 1 + crates/engine/src/menus.rs | 2 + crates/engine/src/tests_tail.rs | 3 +- crates/ui-egui/src/lib.rs | 2 + crates/ui-egui/src/menus.rs | 8 + crates/ui-egui/src/panels/dialogs.rs | 3 + .../ui-egui/src/panels/layer_styles_dialog.rs | 226 ++++++++++++++++++ crates/ui-egui/src/panels/mod.rs | 1 + crates/ui-egui/tests/ui_tail.rs | 43 ++++ 9 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 crates/ui-egui/src/panels/layer_styles_dialog.rs diff --git a/crates/engine/src/commands/frontend.rs b/crates/engine/src/commands/frontend.rs index f0068ae9..168e77a5 100644 --- a/crates/engine/src/commands/frontend.rs +++ b/crates/engine/src/commands/frontend.rs @@ -16,6 +16,7 @@ pub fn specs() -> Vec { vec![ // Application. fe!("app.about", "About EffectCraft...", [], None, "{}", always), + fe!("layer.style.options", "Layer Style Options...", ["Layer", "Layer Styles"], None, "{layer?, style?: blendingOptions|dropShadow|…}", has_layers), fe!( "app.settings", "Settings...", diff --git a/crates/engine/src/menus.rs b/crates/engine/src/menus.rs index 0191c6ea..a110fca7 100644 --- a/crates/engine/src/menus.rs +++ b/crates/engine/src/menus.rs @@ -674,6 +674,8 @@ Layer Matte with Layer Above | layer.trackMatte {"op":"above"} Matte with Layer Below | layer.trackMatte {"op":"below"} Layer Styles + Layer Style Options... | layer.style.options + --- Convert to Editable Styles | layer.style.convertToEditable Show All | layer.style.showAll Remove All | layer.style.removeAll diff --git a/crates/engine/src/tests_tail.rs b/crates/engine/src/tests_tail.rs index 17f2a6b6..4bd2bc5a 100644 --- a/crates/engine/src/tests_tail.rs +++ b/crates/engine/src/tests_tail.rs @@ -271,7 +271,8 @@ fn tate_chu_yoko_via_set_text_with_undo_and_serde() { let lay = effectcraft_text::layout_doc(&doc); assert!((lay.glyphs[1].origin.y - lay.glyphs[2].origin.y).abs() < 1e-6, "the digits share a row"); let back = roundtrip(&s); - let effectcraft_keyframe::Value::Text(d) = &back.comp(s.active_comp_id().unwrap()).unwrap().layer(LayerId(t)).unwrap().props.prop("text/sourceText").unwrap().value + let effectcraft_keyframe::Value::Text(d) = + &back.comp(s.active_comp_id().unwrap()).unwrap().layer(LayerId(t)).unwrap().props.prop("text/sourceText").unwrap().value else { panic!() }; diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 996d9cba..a9763d30 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -71,6 +71,8 @@ pub enum Dialog { Marker, /// Layer ▸ Pre-compose. Precompose, + /// Layer ▸ Layer Styles ▸ Layer Style Options… + LayerStyles, } /// Host hooks provided by the native app (file pickers etc.). diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index 482bf4cd..4b7366cb 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -153,6 +153,10 @@ pub fn invoke(app: &mut EffectcraftApp, ctx: &egui::Context, id: &str, params: V if crate::panels::dialogs_3d::route(app, id, ¶ms)? { return Ok(Value::Null); } + // Layer ▸ Layer Styles ▸