From 8756ec1846f26537e80d44383b0b6a15d74fca5b Mon Sep 17 00:00:00 2001 From: Camille Moine Date: Mon, 19 Oct 2026 10:25:17 +0200 Subject: [PATCH] Timeline: Preserve Transparency toggles from the clicked row (#1849) layer.setSwitch with no value toggles relative to the first selected layer in composition order, so with a mixed selection (A checked, C unchecked) clicking C's box could leave C unchanged. The checkbox now sends the value it toggles to, as the switches do. --- crates/ui-egui/src/panels/timeline.rs | 11 ++++++++++- crates/ui-egui/tests/ui_batch_switches.rs | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/panels/timeline.rs b/crates/ui-egui/src/panels/timeline.rs index ebe076dc8..1366b7504 100644 --- a/crates/ui-egui/src/panels/timeline.rs +++ b/crates/ui-egui/src/panels/timeline.rs @@ -2241,7 +2241,16 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) { let tr = Rect::from_center_size(pos2(cw.mode + 76.0 + 6.0, cy), vec2(14.0, 14.0)); app.auto.add(&format!("timeline.layer.{}.preserveTransparency", layer.id.0), tr, "Preserve Transparency"); if widgets::checkbox(ui, tr, layer.preserve_transparency, &t, egui::Id::new(("pt", layer.id.0))).clicked() { - actions.push(("layer.setSwitch".into(), json!({"layers": mode_targets(&comp, layer.id, &selected), "switch": "preserveTransparency"}))); + // The click gives the selection the state the clicked row toggles to, + // whatever the first selected layer's value (as the switches do). + actions.push(( + "layer.setSwitch".into(), + json!({ + "layers": mode_targets(&comp, layer.id, &selected), + "switch": "preserveTransparency", + "value": !layer.preserve_transparency + }), + )); } // Track matte: layer picker + kind. let mr = Rect::from_min_size(pos2(cw.trkmat + 2.0, cy - 9.0), vec2(104.0, 18.0)); diff --git a/crates/ui-egui/tests/ui_batch_switches.rs b/crates/ui-egui/tests/ui_batch_switches.rs index acbc91f87..407ac194e 100644 --- a/crates/ui-egui/tests/ui_batch_switches.rs +++ b/crates/ui-egui/tests/ui_batch_switches.rs @@ -225,3 +225,20 @@ fn the_modes_column_sets_the_whole_selection() { h.run_steps(2); assert_eq!(states(&h, &ids, preserved), [false; 4], "one undo step put both back"); } + +/// Preserve Transparency toggles from the row it is clicked on, not from the first selected layer: +/// A on and C off, clicking C's box turns both on. +#[test] +fn preserve_transparency_toggles_from_the_clicked_row() { + let (mut h, ids) = harness(); + h.state_mut().ui.timeline.show_modes = true; + h.run_steps(3); + h.state_mut().session.execute("layer.setSwitch", json!({"layers": [ids[0]], "switch": "preserveTransparency", "value": true})).unwrap(); + h.run_steps(2); + select(&mut h, &[ids[0], ids[2]]); + click(&mut h, &format!("timeline.layer.{}.preserveTransparency", ids[2])); + assert_eq!(states(&h, &ids, preserved), [true, false, true, false]); + // The next click turns both off again. + click(&mut h, &format!("timeline.layer.{}.preserveTransparency", ids[2])); + assert_eq!(states(&h, &ids, preserved), [false; 4]); +}