G11: open Arc tool options on canvas click (WIP)

Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-10-22 13:38:04 +07:00
committed by bflatastic
co-authored by nrq6993-a11y
parent 5013189fd3
commit fa3d6d9298
5 changed files with 53 additions and 8 deletions
+3 -2
View File
@@ -63,7 +63,7 @@ fn lengths(kind: &str) -> &'static [&'static str] {
"roundedRectangle" => &["width", "height", "radius"],
"polygon" => &["radius"],
"star" => &["radius1", "radius2"],
"lineSegment" => &["length"],
"lineSegment" | "arc" => &["length"],
"offsetPath" => &["offset"],
_ => &[],
}
@@ -73,7 +73,7 @@ fn lengths(kind: &str) -> &'static [&'static str] {
/// number: fields that ↑/↓ step by one (Shift: ten) and that do math, as the distances do.
fn suffix(kind: &str, key: &str) -> Option<&'static str> {
match (kind, key) {
("rotate" | "shear" | "reflect" | "move", "angle") => Some("°"),
("rotate" | "shear" | "reflect" | "move" | "arc" | "lineSegment", "angle") => Some("°"),
("scale", "sx" | "sy") => Some("%"),
_ => None,
}
@@ -96,6 +96,7 @@ fn order(kind: &str) -> &'static [&'static str] {
"rectangularGrid" => &["width", "height", "rows", "rowSkew", "columns", "columnSkew"],
"polarGrid" => &["width", "height", "concentric", "concentricSkew", "radial", "radialSkew"],
"artboardOptions" => &["name", "width", "height"],
"arc" | "lineSegment" => &["length", "angle"],
_ => &[],
}
}
+1 -1
View File
@@ -246,7 +246,7 @@ macro_rules! registry {
registry! {
DimensionOptions: [dimension::KIND] => dimension::SPEC,
NewDocument: [new_document::KIND] => new_document::SPEC,
Shape: ["rectangle", "roundedRectangle", "ellipse", "polygon", "star", "lineSegment", "rectangularGrid", "polarGrid"] => shapes::SPEC,
Shape: ["rectangle", "roundedRectangle", "ellipse", "polygon", "star", "lineSegment", "arc", "rectangularGrid", "polarGrid"] => shapes::SPEC,
Transform: ["move", "rotate", "scale", "reflect", "shear"] => transform::SPEC,
PathOp: ["average", "offsetPath", "simplify", "splitIntoGrid"] => path_ops::SPEC,
DocumentSetup: ["documentSetup"] => document_setup::SPEC,
+25 -5
View File
@@ -21,6 +21,7 @@ fn title(kind: &str) -> &'static str {
"star" => tl!("Star"),
"rectangularGrid" => tl!("Rectangular Grid"),
"polarGrid" => tl!("Polar Grid"),
"arc" => tl!("Arc"),
_ => tl!("Line Segment Tool Options"),
}
}
@@ -80,6 +81,10 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
});
} else {
form::grid(ui, d, unit);
if d.kind == "arc" {
ui.add_space(8.0);
form::check(ui, d, "closed", tl!("Closed"));
}
}
let own = match d.kind.as_str() {
"rectangularGrid" => ("frame", tl!("Use Outside Rectangle As Frame")),
@@ -109,11 +114,13 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
"star" => Some(("points", 5.0, 2.0)),
_ => None,
};
let options = count.map(|(key, default, min)| {
let mut values = json!({});
values[key] = json!(d.f64(key, default).clamp(min, 1000.0) as u64);
values
});
let options = count
.map(|(key, default, min)| {
let mut values = json!({});
values[key] = json!(d.f64(key, default).clamp(min, 1000.0) as u64);
values
})
.or_else(|| (d.kind == "arc").then(|| json!({"closed": d.bool("closed")})));
let (x, y) = (d.f64("x", 0.0), d.f64("y", 0.0));
let (bx, by) = box_origin(d);
let (id, params) = match d.kind.as_str() {
@@ -140,6 +147,19 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
let (l, a) = (d.f64("length", 100.0), d.f64("angle", 0.0).to_radians());
("shape.line", json!({"x1": x, "y1": y, "x2": x + l * a.cos(), "y2": y - l * a.sin()}))
}
"arc" => {
let (l, a) = (d.f64("length", 100.0), d.f64("angle", 0.0).to_radians());
(
"shape.arc",
json!({
"x1": x,
"y1": y,
"x2": x + l * a.cos(),
"y2": y - l * a.sin(),
"closed": d.bool("closed"),
}),
)
}
_ => (
"shape.rectangle",
json!({"x": bx, "y": by, "width": d.f64("width", 100.0), "height": d.f64("height", 100.0), "radius": d.f64("radius", 0.0)}),
+14
View File
@@ -41,6 +41,7 @@ fn kinds_map_to_their_dialogs() {
("newDocument", DialogKind::NewDocument),
("roundedRectangle", DialogKind::Shape),
("lineSegment", DialogKind::Shape),
("arc", DialogKind::Shape),
("rectangularGrid", DialogKind::Shape),
("polarGrid", DialogKind::Shape),
("shear", DialogKind::Transform),
@@ -88,6 +89,7 @@ fn every_dialog_draws() {
"polygon",
"star",
"lineSegment",
"arc",
"rectangularGrid",
"polarGrid",
"rotate",
@@ -1711,6 +1713,18 @@ fn polar_grid_shared_canvas_click_defaults_units_counts_and_history() {
assert_eq!(app.session.doc().unwrap().doc, made);
}
/// Part of gap G11: an Arc tool click opens its options at the pointer; OK draws an arc there.
#[test]
fn arc_click_opens_options_and_ok_draws() {
use vectorcraft_doc::NodeKind;
let mut app = app();
open_tool_dialog(&mut app, "arc", json!({"x": 100.0, "y": 50.0}));
assert_eq!(app.ui.dialog.as_ref().unwrap().kind, "arc");
super::confirm(&mut app).unwrap();
let n = app.session.doc().unwrap().doc.layers[0].children().unwrap().last().unwrap();
assert!(matches!(n.kind, NodeKind::Path { .. }));
}
/// #1377: Polar Grid's dialog has a skew slider under each divider count, Create Compound Path
/// From Ellipses and Fill Grid, opened with the tool's stored values; OK draws with them and
/// stores them.
+10
View File
@@ -20,6 +20,16 @@ pub fn open_tool_dialog(app: &mut VectorcraftApp, kind: &str, p: Value) {
Dialog::new(kind, json!({"x": x, "y": y, "radius1": "50 pt", "radius2": "25 pt", "points": app.session.tool_options_of(kind)["points"]}))
}
"lineSegment" => Dialog::new(kind, json!({"x": x, "y": y, "length": "100 pt", "angle": 0})),
"arc" => Dialog::new(
kind,
json!({
"x": x,
"y": y,
"length": "100 pt",
"angle": 0,
"closed": app.session.tool_options_of(kind).get("closed").and_then(Value::as_bool).unwrap_or(false),
}),
),
// The grids: the tool's stored options (divider counts and skews, switches) at the default size.
"rectangularGrid" | "polarGrid" => {
let mut obj = match app.session.tool_options_of(kind) {