Brackets: keep to the tools whose size the keys are documented for

The typed [ and ] now reach the Blob Brush, the Eraser and the Symbolism
tools, whose bracket keys are in the public shortcut lists. A size of the
Paintbrush's own (and path.freehand's scale) is left out until its
behaviour is decided: #1661 stays open for that.
This commit is contained in:
bflatastic
2026-10-14 03:55:41 +07:00
parent 3f1e72d983
commit 3152436020
4 changed files with 28 additions and 94 deletions
+8 -42
View File
@@ -29,8 +29,7 @@ pub struct GestureTool {
extend: Option<(NodeId, bool)>,
/// Fit tolerance in points (Pencil/Paintbrush/Smooth "Fidelity").
pub fidelity: f64,
/// Brush / eraser diameter in points; the Paintbrush's size, its strokes drawn at
/// `size / PAINTBRUSH_SIZE` of the stroke weight.
/// Brush / eraser diameter in points.
pub size: f64,
/// Fill new pencil/brush strokes.
pub fill: bool,
@@ -42,11 +41,6 @@ pub struct GestureTool {
snap: DrawSnap,
}
/// The Paintbrush's starting size, as the Blob Brush's: strokes at the stroke weight. `[` and `]`
/// take a point off or add one, so each press draws the next stroke a tenth of the weight thinner
/// or thicker (our own step; the public references give none).
pub const PAINTBRUSH_SIZE: f64 = 10.0;
impl GestureTool {
pub fn new(id: &str) -> Self {
let id: &'static str = match id {
@@ -68,7 +62,7 @@ impl GestureTool {
began: false,
extend: None,
fidelity,
size: if id == "paintbrush" { PAINTBRUSH_SIZE } else { 10.0 },
size: 10.0,
fill: false,
edit_within: 12.0,
close_within: 15.0,
@@ -153,8 +147,6 @@ impl GestureTool {
});
if let Some((id, start)) = self.extend {
v["extend"] = json!({"id": id.0, "end": if start { "start" } else { "end" }});
} else if self.id == "paintbrush" && self.size != PAINTBRUSH_SIZE {
v["scale"] = json!(self.size / PAINTBRUSH_SIZE);
}
v
}
@@ -257,8 +249,9 @@ impl Tool for GestureTool {
_ => vec![],
}
}
/// `[` and `]` are the Blob Brush's and the Eraser's: their size (#1661).
fn claims_key(&self, _cx: &ToolContext, key: ToolKey) -> bool {
matches!(key, ToolKey::BracketLeft | ToolKey::BracketRight) && matches!(self.id, "paintbrush" | "blobBrush" | "eraser")
matches!(key, ToolKey::BracketLeft | ToolKey::BracketRight) && matches!(self.id, "blobBrush" | "eraser")
}
fn key(&mut self, _cx: &ToolContext, key: ToolKey, _m: Mods) -> Vec<Action> {
match key {
@@ -270,13 +263,11 @@ impl Tool for GestureTool {
self.clear();
if began { vec![Action::Cancel] } else { vec![] }
}
// The Paintbrush's size is its own: the stroke weight and the selection stay as they
// are, and the next stroke is drawn thinner or thicker.
ToolKey::BracketLeft if matches!(self.id, "blobBrush" | "eraser" | "paintbrush") => {
ToolKey::BracketLeft if matches!(self.id, "blobBrush" | "eraser") => {
self.size = (self.size - 1.0).max(1.0);
vec![]
}
ToolKey::BracketRight if matches!(self.id, "blobBrush" | "eraser" | "paintbrush") => {
ToolKey::BracketRight if matches!(self.id, "blobBrush" | "eraser") => {
self.size = (self.size + 1.0).min(1000.0);
vec![]
}
@@ -309,9 +300,8 @@ impl Tool for GestureTool {
}
fn options(&self) -> Value {
match self.id {
"pencil" => json!({"fidelity": self.fidelity, "fill": self.fill, "editWithin": self.edit_within, "closeWithin": self.close_within}),
"paintbrush" => {
json!({"fidelity": self.fidelity, "fill": self.fill, "editWithin": self.edit_within, "closeWithin": self.close_within, "size": self.size})
"pencil" | "paintbrush" => {
json!({"fidelity": self.fidelity, "fill": self.fill, "editWithin": self.edit_within, "closeWithin": self.close_within})
}
"smooth" => json!({"fidelity": self.fidelity}),
"blobBrush" | "eraser" => json!({"size": self.size}),
@@ -453,28 +443,4 @@ mod tests {
b.key(&cx, ToolKey::BracketRight, Mods::default());
assert_eq!(b.options()["size"], 11.0);
}
/// #1661: `[` and `]` size the Paintbrush itself, a tenth of its starting size a press:
/// the next stroke is drawn that much thinner or thicker; continuing a path keeps its weight.
#[test]
fn paintbrush_brackets_size_its_next_stroke() {
let (d, _) = doc_with_rect();
let s = Selection::default();
let p = paint();
let cx = cx(&d, &s, &p);
let mut t = GestureTool::new("paintbrush");
assert!(t.claims_key(&cx, ToolKey::BracketRight) && t.freehand_params(false).get("scale").is_none());
for _ in 0..10 {
assert!(t.key(&cx, ToolKey::BracketRight, Mods::default()).is_empty(), "no command: the weight stays");
}
assert_eq!(t.options()["size"], 20.0);
assert_eq!(t.freehand_params(false)["scale"], json!(2.0));
for _ in 0..40 {
t.key(&cx, ToolKey::BracketLeft, Mods::default());
}
assert_eq!(t.options()["size"], 1.0);
t.extend = Some((NodeId(1), false));
assert!(t.freehand_params(false).get("scale").is_none());
assert!(!GestureTool::new("pencil").claims_key(&cx, ToolKey::BracketRight));
}
}