mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-29 12:17:14 -06:00
Merge pull request #4376 from dotCooCoo/fix/pencil-alt-smooth-radius
Pencil: Alt smooths as far from the drag as the Smooth tool does
This commit is contained in:
@@ -22,6 +22,10 @@ use super::{FEEDBACK, eraser_area, points_json, polyline};
|
||||
use crate::guides::DrawSnap;
|
||||
use crate::{Action, Cursor, Mods, Overlay, PointerEvent, PointerKind, Tool, ToolContext, ToolKey};
|
||||
|
||||
/// How far from its drag the Smooth tool smooths, in screen pixels. The Pencil uses the same
|
||||
/// radius while Alt switches it to the Smooth tool.
|
||||
const SMOOTH_RADIUS: f64 = 12.0;
|
||||
|
||||
pub struct GestureTool {
|
||||
/// How many points the last preview of the stroke had ([`crate::previews_at`]).
|
||||
previewed: usize,
|
||||
@@ -339,9 +343,13 @@ impl GestureTool {
|
||||
let pts = &self.points;
|
||||
let has_sel = !cx.selection.is_empty();
|
||||
let tol = cx.tol(self.edit_within);
|
||||
let radius = cx.tol(SMOOTH_RADIUS);
|
||||
if self.smoothing {
|
||||
if has_sel && pts.len() >= 2 {
|
||||
return vec![Action::Exec("path.smoothRegion".into(), json!({"points": points_json(pts), "radius": tol, "fidelity": self.fidelity}))];
|
||||
return vec![Action::Exec(
|
||||
"path.smoothRegion".into(),
|
||||
json!({"points": points_json(pts), "radius": radius, "fidelity": self.fidelity}),
|
||||
)];
|
||||
}
|
||||
return vec![];
|
||||
}
|
||||
@@ -378,7 +386,7 @@ impl GestureTool {
|
||||
)],
|
||||
"knife" if pts.len() >= 2 => vec![Action::Exec("path.knife".into(), json!({"points": points_json(pts)}))],
|
||||
"smooth" if has_sel && pts.len() >= 2 => {
|
||||
vec![Action::Exec("path.smoothRegion".into(), json!({"points": points_json(pts), "radius": tol, "fidelity": self.fidelity}))]
|
||||
vec![Action::Exec("path.smoothRegion".into(), json!({"points": points_json(pts), "radius": radius, "fidelity": self.fidelity}))]
|
||||
}
|
||||
"pathEraser" if has_sel => vec![Action::Exec("path.eraseSegments".into(), json!({"points": points_json(pts), "width": cx.tol(8.0)}))],
|
||||
"join" if pts.len() >= 2 => vec![Action::Exec("path.joinScrub".into(), json!({"points": points_json(pts), "tolerance": tol}))],
|
||||
|
||||
@@ -703,6 +703,34 @@ fn pencil_alt_with_alt_to_smooth_on_smooths_instead_of_drawing_a_line() {
|
||||
assert!(matches!(&acts.last().unwrap()[0], Action::Exec(c, v) if c == "path.smoothRegion" && v["points"].as_array().unwrap().len() == 3));
|
||||
}
|
||||
|
||||
/// While Alt switches the Pencil to the Smooth tool, the Pencil smooths within the Smooth tool's
|
||||
/// radius at any Edit selected paths Within value, 0 included.
|
||||
#[test]
|
||||
fn pencil_alt_smooths_within_the_smooth_tools_radius() {
|
||||
let (d, id) = doc_with_rect();
|
||||
let mut s = Selection::default();
|
||||
s.set([id]);
|
||||
let p = paint();
|
||||
let mut cx = cx(&d, &s, &p);
|
||||
cx.smart_guides = false;
|
||||
let pts = [(50.0, 150.0), (150.0, 150.0), (250.0, 160.0)];
|
||||
let radius = |acts: &[Vec<Action>]| match acts.last().and_then(|a| a.first()) {
|
||||
Some(Action::Exec(c, v)) if c == "path.smoothRegion" => v["radius"].as_f64().unwrap(),
|
||||
a => panic!("expected path.smoothRegion, got: {a:?}"),
|
||||
};
|
||||
let alt = Mods { alt: true, ..Default::default() };
|
||||
for zoom in [1.0, 2.0] {
|
||||
cx.zoom = zoom;
|
||||
let want = radius(&drag(&mut GestureTool::new("smooth"), &cx, &pts, Mods::default()));
|
||||
for within in [0.0, 5.0, 40.0] {
|
||||
let mut t = GestureTool::new("pencil");
|
||||
t.set_option("altSmooth", &json!(true));
|
||||
t.set_option("editWithin", &json!(within));
|
||||
assert_eq!(radius(&drag_held(&mut t, &cx, &pts, alt)), want, "zoom {zoom}, editWithin {within}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// #3799: Alt's line starts and ends on Smart Guides as a stroke does, and pressed on an end of
|
||||
/// a selected open path it continues the path from that end to the pointer.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user