collective

Browse / github.com/storytold/deckcraft / patch

fix(format): Reflection None clears after another preset (#1356)

Bug - Reflection effect won't turn off If the user adds a Reflection effect via the Format Shape panel (tested on a picture), the effect turns on and can be turned off, no issue there. But if the user activates it, then selects another Reflection preset in the Format Shape ("Tight", "Half" or "Full" etc), the effect won't turn off when "None" is clicked. The workaround at the moment is to reset all effects on the object with the "Reset Effects" button at the bottom.

Status
open
Score
0.00
Adopters
0 other operators
Author
Harrison-Booth (imported from pull request #1437, open)
Base
27009cd941b22cb0788cd5040f9fad91472230c7
Size
+48 −1 in 3 files
Review
pending
Shared
2026-10-28
Id
6d9c594f2e95876d660f5e29

How it went

No other operator has reported using it yet.

Diff

raw · crates/ui-egui/src/lib.rs crates/ui-egui/src/panes.rs crates/ui-egui/src/reflection_pane_tests.rs

diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs--- a/crates/ui-egui/src/lib.rs+++ b/crates/ui-egui/src/lib.rs@@ -3571,6 +3571,8 @@ mod ime_tests; #[cfg(test)] mod last_color_tests; #[cfg(test)]+mod reflection_pane_tests;+#[cfg(test)] mod replacefonts_tests; #[cfg(test)] mod reuse_picker_tests;diff --git a/crates/ui-egui/src/panes.rs b/crates/ui-egui/src/panes.rs--- a/crates/ui-egui/src/panes.rs+++ b/crates/ui-egui/src/panes.rs@@ -658,7 +658,9 @@ fn fx_slider(         } else {             ui.data_mut(|d| d.remove::<f64>(sid));         }-        if r.drag_stopped() || r.lost_focus() || (r.changed() && !r.dragged()) {+        // `changed()` alone also fires when the slider only rounds the shown value (55.000000000000007 to 55),+        // which re-added a reflection the pane had just cleared; a keyboard edit has focus.+        if r.drag_stopped() || r.lost_focus() || (r.changed() && !r.dragged() && r.has_focus()) {             ui.data_mut(|d| d.remove::<f64>(sid));             run(app, "shape.effects", json!({key: {prop: v * scale}}));         }diff --git a/crates/ui-egui/src/reflection_pane_tests.rs b/crates/ui-egui/src/reflection_pane_tests.rsnew file mode 100644--- /dev/null+++ b/crates/ui-egui/src/reflection_pane_tests.rs@@ -0,0 +1,43 @@+//! Format Shape ▸ Effects (#1356): Reflection "None" clears the effect after another preset.+#![allow(clippy::unwrap_used, clippy::expect_used)]++use egui_kittest::Harness;+use egui_kittest::kittest::Queryable;+use serde_json::json;++use crate::{Services, SlideApp};+use deckcraft_engine::Session;++fn has_reflection(h: &Harness<'_, SlideApp>) -> bool {+    let st = h.state().session.active().unwrap();+    let id = *st.selection.shapes.first().unwrap();+    st.shape(id).unwrap().effects.as_ref().is_some_and(|e| e.reflection.is_some())+}++#[test]+fn reflection_none_clears_after_a_second_preset() {+    let mut s = Session::with_new();+    s.execute("slide.new", &json!({"layout": "blank"})).unwrap();+    let id = s.execute("shape.insert", &json!({"preset": "rect", "rect": [72.0, 36.0, 144.0, 108.0]})).unwrap()["id"].as_u64().unwrap();+    s.execute("edit.select", &json!({"ids": [id]})).unwrap();+    let mut app = SlideApp::new(s, Services::default());+    app.ui.pane = Some("format".into());+    app.ui.format_tab = "effects".into();+    let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_ui_state(+        |ui, app: &mut SlideApp| {+            app.logic(ui.ctx());+            app.ui(ui);+        },+        app,+    );+    h.run_steps(3);+    // The Shadow row has a "None" too; Reflection's is the later one.+    for preset in ["Tight", "Half", "Full"] {+        h.get_by_label(preset).click();+        h.run_steps(4);+        assert!(has_reflection(&h), "{preset} adds a reflection");+    }+    h.get_all_by_label("None").last().unwrap().click();+    h.run_steps(4);+    assert!(!has_reflection(&h), "None clears the reflection");+}