mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-15 21:57:04 +00:00
Brushes: a one-point brush.freehand continuation follows keepSelected
A brush.freehand call that continued a path by one point changed the path's brush and left the selection as it was. With keepSelected off the path stayed selected, and with it on the path was not selected, unlike a longer continuation and unlike what path.freehand's params text says. The brush edit now selects the path, or deselects it while the rest of the selection stays, as a longer continuation does. A call that leaves the brush as it is still changes nothing.
This commit is contained in:
@@ -227,12 +227,18 @@ pub(crate) fn freehand_brushed(s: &mut Session, p: &Value, brush_name: Option<&s
|
||||
let Some(p0) = pts.first_mut() else { return Err(bad(C, "needs points")) };
|
||||
*p0 = end;
|
||||
if pts.len() < 2 {
|
||||
// No stroke to add: the brush alone changes, when it is not the path's already.
|
||||
// No stroke to add: the brush alone changes, when it is not the path's already, and the
|
||||
// path is selected or deselected as a longer continuation leaves it.
|
||||
if let Some(name) = brush_name
|
||||
&& s.doc()?.doc.node(target).and_then(|n| n.appearance.stroke()).is_some_and(|st| st.brush.as_deref() != Some(name))
|
||||
{
|
||||
s.edit("Paintbrush", |d, _| {
|
||||
s.edit("Paintbrush", |d, sel| {
|
||||
set_brush(d, target, name);
|
||||
if keep_selected {
|
||||
sel.set([id]);
|
||||
} else {
|
||||
sel.remove(id);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
@@ -1037,6 +1037,40 @@ fn brush_freehand_direct_call_has_one_undo_step() {
|
||||
assert_eq!(s.doc().unwrap().history.undo.last().map(|e| e.label.as_str()), Some("Paintbrush"), "a stroke with a brush is a Paintbrush step");
|
||||
}
|
||||
|
||||
/// A `brush.freehand` call that continues a path by one point changes only the path's brush, and
|
||||
/// applies `keepSelected` as a longer continuation does: off, the path is deselected while the
|
||||
/// rest of the selection stays; on, the path is selected. A call that leaves the brush as it is
|
||||
/// changes neither the selection nor the undo history.
|
||||
#[test]
|
||||
fn brush_freehand_continued_by_one_point_follows_keep_selected() {
|
||||
let mut s = session();
|
||||
let r = s.execute("brush.freehand", &json!({"points": [[10, 10], [60, 40], [120, 10]], "style": "brush", "brush": "Charcoal"})).unwrap();
|
||||
let p = NodeId(r["id"].as_u64().unwrap());
|
||||
let a = rect(&mut s, 200.0, 200.0, 10.0, 10.0);
|
||||
let extend = json!({"id": p.0, "end": "end"});
|
||||
|
||||
select(&mut s, &[p, a]);
|
||||
let off = json!({"points": [[120, 10]], "extend": extend, "brush": "Dots", "keepSelected": false});
|
||||
assert_eq!(s.execute("brush.freehand", &off).unwrap()["id"], json!(p.0));
|
||||
assert_eq!(brush_of(&s, p).as_deref(), Some("Dots"));
|
||||
assert_eq!(selected(&s), [a], "Keep selected off: the path is deselected and the rest stays");
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert_eq!(brush_of(&s, p).as_deref(), Some("Charcoal"), "one Undo takes back the brush");
|
||||
assert_eq!(selected(&s), [p, a], "Undo gives back the earlier selection");
|
||||
|
||||
select(&mut s, &[a]);
|
||||
let on = json!({"points": [[120, 10]], "extend": extend, "brush": "Dots"});
|
||||
s.execute("brush.freehand", &on).unwrap();
|
||||
assert_eq!(brush_of(&s, p).as_deref(), Some("Dots"));
|
||||
assert_eq!(selected(&s), [p], "Keep selected on: the continued path is selected");
|
||||
|
||||
select(&mut s, &[a]);
|
||||
let undo = s.doc().unwrap().history.undo.len();
|
||||
s.execute("brush.freehand", &on).unwrap();
|
||||
assert_eq!(selected(&s), [a], "the same brush again: the selection stays");
|
||||
assert_eq!(s.doc().unwrap().history.undo.len(), undo, "the same brush again: no undo step");
|
||||
}
|
||||
|
||||
/// `brush.freehand` refuses a brush for a path with no stroke (a continued path, a redrawn one
|
||||
/// and a new filled pencil path while the stroke is None) instead of reporting it painted: the
|
||||
/// document, the selection and the undo history stay as they were. Without a brush the path is
|
||||
|
||||
Reference in New Issue
Block a user