mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 02:37:01 -06:00
Fix #693: a click activates its artboard; in-place pastes go onto it
- A press with a selection tool inside an artboard makes it the active one, as the Artboard tool's does; before, only the navigator and the Artboards panel changed it. - Paste in Place, in Front and in Back take `artboard` (the UI passes the active one): the objects go where they were on the artboard they were copied from, on that artboard. Without it, they paste where they were, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
843507549f
commit
e9bbf43d15
@@ -864,6 +864,15 @@ pub fn dispatch(app: &mut VectorcraftApp, ev: &PointerEvent, view: vectorcraft_e
|
||||
{
|
||||
v.artboard = i;
|
||||
}
|
||||
// A press with a selection tool inside an artboard makes it the active one (#693), as the
|
||||
// Artboard tool's does: Paste in Place and in Front or Back then paste onto it.
|
||||
if ev.kind == PointerKind::Down
|
||||
&& vectorcraft_tools::catalog::is_selection_tool(app.session.tool_id())
|
||||
&& let Some(i) = app.session.active().and_then(|d| d.doc.artboard_at(ev.pos))
|
||||
&& let Some(v) = app.view_mut()
|
||||
{
|
||||
v.artboard = i;
|
||||
}
|
||||
apply_requests(app, r);
|
||||
}
|
||||
|
||||
@@ -2051,6 +2060,34 @@ mod tests {
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
|
||||
/// A click with the Selection tool inside an artboard makes it the active one, and Paste in
|
||||
/// Place then pastes onto it, where the objects were on their own artboard (#693).
|
||||
#[test]
|
||||
fn a_click_activates_its_artboard_and_paste_in_place_goes_onto_it() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.session.execute("file.new", &json!({"width": 200, "height": 100, "artboards": 3})).unwrap();
|
||||
let boards: Vec<_> = app.session.active().unwrap().doc.artboards.iter().map(|a| a.rect).collect();
|
||||
app.session.execute("shape.rectangle", &json!({"x": boards[0].x0 + 10.0, "y": boards[0].y0 + 15.0, "width": 20, "height": 20})).unwrap();
|
||||
app.run("edit.copy", json!({})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
frame(&mut app, &ctx, vec![]);
|
||||
app.select_tool("selection");
|
||||
let view = app.view_info();
|
||||
let at = boards[2].center();
|
||||
for kind in [PointerKind::Down, PointerKind::Up] {
|
||||
dispatch(&mut app, &PointerEvent { kind, pos: at, mods: Default::default(), pressure: 1.0 }, view);
|
||||
}
|
||||
assert_eq!(app.view().unwrap().artboard, 2, "the clicked artboard is the active one");
|
||||
let ids: Vec<vectorcraft_doc::NodeId> = app.run("edit.pasteInPlace", json!({})).unwrap()["ids"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|v| vectorcraft_doc::NodeId(v.as_u64().unwrap()))
|
||||
.collect();
|
||||
let b = app.session.active().unwrap().doc.bounds_of(&ids, false).unwrap();
|
||||
assert_eq!((b.x0, b.y0), (boards[2].x0 + 10.0, boards[2].y0 + 15.0));
|
||||
}
|
||||
|
||||
/// Enable Touch Gestures (#585): a two-finger tap undoes and a three-finger one redoes, and the
|
||||
/// first finger's press (the pointer egui makes of it) draws nothing. Off, a tap does nothing.
|
||||
#[test]
|
||||
|
||||
@@ -534,6 +534,14 @@ impl VectorcraftApp {
|
||||
{
|
||||
p.insert("center".into(), serde_json::json!([c.x, c.y]));
|
||||
}
|
||||
// In place, in front, in back: onto the active artboard (#693).
|
||||
if matches!(id, "edit.pasteInPlace" | "edit.pasteInFront" | "edit.pasteInBack")
|
||||
&& params.get("artboard").is_none()
|
||||
&& let Some(i) = self.view().map(|v| v.artboard)
|
||||
&& let Some(p) = params.as_object_mut()
|
||||
{
|
||||
p.insert("artboard".into(), serde_json::json!(i));
|
||||
}
|
||||
if let Some(r) = dialogs::swatch_conflict::ask(self, id, ¶ms) {
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user