diff --git a/crates/ui-egui/src/dialogs/brush_options.rs b/crates/ui-egui/src/dialogs/brush_options.rs index 3b3c16523..f03518b16 100644 --- a/crates/ui-egui/src/dialogs/brush_options.rs +++ b/crates/ui-egui/src/dialogs/brush_options.rs @@ -177,10 +177,20 @@ pub(super) fn open_new(app: &mut VectorcraftApp, ty: &str, ids: Option) - Ok(Value::Null) } -/// OK of a new brush's Brush Options: `brush.new` with the type, the name, the values set and the -/// dropped art's ids. The dialog closes once the brush is made. +/// OK of a new brush's Brush Options: `brush.new` with the type, the name, the values set, the art +/// the dialog opened with (`art` or `side` of `__def`, which the preview draws) and the dropped +/// art's ids. A selection changed or cleared while the dialog is open does not change the art. The +/// dialog closes once the brush is made. fn create(app: &mut VectorcraftApp, d: &Dialog) -> Result { - let mut p = json!({ "type": d.str("__type"), "name": d.str("name").trim(), "params": params(d) }); + let mut brush_params = params(d); + if let Some(def) = d.fields.get("__def") { + for key in ["art", "side"] { + if let Some(art) = def.get(key).filter(|v| !v.is_null()) { + brush_params[key] = art.clone(); + } + } + } + let mut p = json!({ "type": d.str("__type"), "name": d.str("name").trim(), "params": brush_params }); if let Some(ids) = d.fields.get(IDS) { p["ids"] = ids.clone(); } diff --git a/crates/ui-egui/src/dialogs/new_brush.rs b/crates/ui-egui/src/dialogs/new_brush.rs index 3746a5874..6ec926c07 100644 --- a/crates/ui-egui/src/dialogs/new_brush.rs +++ b/crates/ui-egui/src/dialogs/new_brush.rs @@ -166,6 +166,33 @@ mod tests { assert_eq!((&def["type"], &def["size"]), (&json!("calligraphic"), &json!(9.0))); } + /// The new brush takes the art its Brush Options opened with: changing or clearing the + /// selection while the dialog is open does not change the art, and OK still makes the brush. + #[test] + fn ok_makes_the_brush_from_the_art_the_dialog_opened_with() { + for (ty, key) in [("scatter", "art"), ("art", "art"), ("pattern", "side")] { + for change in ["select.set", "select.none"] { + let mut app = app(); + app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 50, "height": 20})).unwrap(); + app.run("ui.newBrush", json!({})).unwrap(); + set(&mut app, json!({"type": ty})); + super::super::confirm(&mut app).unwrap(); + let captured = app.ui.dialog.as_ref().unwrap().fields["__def"][key].clone(); + assert!(captured.is_object(), "{ty}"); + if change == "select.set" { + app.run("shape.ellipse", json!({"x": 100, "y": 50, "width": 120, "height": 90})).unwrap(); + } else { + app.run("select.none", json!({})).unwrap(); + } + super::super::confirm(&mut app).unwrap_or_else(|e| panic!("{ty} after {change}: {e}")); + assert!(app.ui.dialog.is_none(), "{ty} after {change}"); + let name = format!("New {}{} Brush", ty[..1].to_uppercase(), &ty[1..]); + let def = app.run("brush.get", json!({ "name": name })).unwrap(); + assert_eq!(def[key], captured, "{ty} after {change}"); + } + } + } + /// Cancel in New Brush, or in the Brush Options it opens, adds no brush and no undo step. #[test] fn cancel_adds_no_brush() {