Objects on Path: the tool's Rotate stays within -360 to 360

tool.setOption kept any finite rotate, while the Objects on Path Tool
Options dialog shows Rotate clamped to -360 to 360 and saves the value
it was given, so a rotate of 450 showed as 360 and the next attach used
450. The tool now clamps rotate to -360 to 360, and attach clamps the
saved rotate it falls back to the same way.
This commit is contained in:
dotCooCoo
2026-11-01 04:53:41 +07:00
committed by bflatastic
parent af86b2c833
commit 9ba55b3c03
2 changed files with 10 additions and 4 deletions
+1 -1
View File
@@ -204,7 +204,7 @@ fn attach(s: &mut Session, p: &Value) -> Result<Value> {
// Without them in `p`, the tool's options (Objects on Path Tool Options) give Pivot and Rotate.
let saved = s.tool_options_of(TOOL);
let tool_pivot = saved.get("pivot").and_then(Value::as_u64).filter(|n| *n <= 8).map_or(CENTER, |n| n as u8);
let tool_rotate = saved.get("rotate").and_then(Value::as_f64).filter(|r| r.is_finite()).unwrap_or(0.0);
let tool_rotate = saved.get("rotate").and_then(Value::as_f64).filter(|r| r.is_finite()).map_or(0.0, |r| r.clamp(-360.0, 360.0));
let (pivot, rotate) = pivot_rotate(p, C, tool_pivot, tool_rotate)?;
let roots = match p.get("ids") {
Some(_) => roots_of(&s.doc()?.doc, checked_ids_param(s, p, "ids", C)?),
+9 -3
View File
@@ -98,8 +98,8 @@ impl Tool for ObjectsOnPathTool {
json!({ "pivot": self.pivot, "rotate": self.rotate })
}
/// `pivot` takes a whole number from 0 to 8 and `rotate` a finite number; other values are
/// ignored.
/// `pivot` takes a whole number from 0 to 8 and `rotate` a finite number, clamped to -360 to
/// 360; other values are ignored.
fn set_option(&mut self, key: &str, value: &Value) {
match key {
"pivot" => {
@@ -109,7 +109,7 @@ impl Tool for ObjectsOnPathTool {
}
"rotate" => {
if let Some(r) = value.as_f64().filter(|r| r.is_finite()) {
self.rotate = r;
self.rotate = r.clamp(-360.0, 360.0);
}
}
_ => {}
@@ -180,6 +180,12 @@ mod tests {
t.set_option("pivot", &json!(9));
t.set_option("rotate", &json!("x"));
assert_eq!(t.options(), json!({ "pivot": 0, "rotate": 45.5 }));
// Rotate is kept within the dialog's -360 to 360.
t.set_option("rotate", &json!(450));
assert_eq!(t.options()["rotate"], 360.0);
t.set_option("rotate", &json!(-720.5));
assert_eq!(t.options()["rotate"], -360.0);
t.set_option("rotate", &json!(45.5));
t.pointer(&cx, &ev(PointerKind::Down, 200.0, 300.0));
let acts = t.pointer(&cx, &ev(PointerKind::Up, 200.0, 300.0));
assert!(matches!(acts.as_slice(), [Action::Exec(_, p)] if p["pivot"] == 0 && p["rotate"] == 45.5), "{acts:?}");