mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 12:28:56 +00:00
Shape Builder: a Cmd-drag held during a merge can carry art to another tab
A Cmd-press held while a merge is computed reached the lent Selection tool after the merge, but the drag had no document-drag origin, because the press was handed over while Shape Builder was still the active tool. The frontend now records the origin when the held press is made.
This commit is contained in:
@@ -413,6 +413,10 @@ pub fn apply_requests(app: &mut VectorcraftApp, r: vectorcraft_engine::Result<Ve
|
||||
vectorcraft_engine::UiRequest::HeldPress { doc, pos, tool } => {
|
||||
let index = doc.and_then(|uid| app.session.documents().iter().position(|d| d.uid == uid));
|
||||
pressed_with(app, index, pos, tool);
|
||||
// The selection tool Cmd lent has the press now, so its drag can carry art to another tab.
|
||||
if let Some(ctx) = app.ui_ctx.clone() {
|
||||
crate::document_drag::begin(app, &ctx, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use egui::{Event, PointerButton, Pos2};
|
||||
use serde_json::json;
|
||||
use vectorcraft_engine::Session;
|
||||
use vectorcraft_geom::Point;
|
||||
use vectorcraft_tools::{PointerEvent, PointerKind};
|
||||
|
||||
use crate::{VectorcraftApp, canvas, chrome};
|
||||
|
||||
@@ -142,6 +143,57 @@ fn drag_fixture_modifiers(modifiers: egui::Modifiers) -> (VectorcraftApp, egui::
|
||||
(app, ctx, grab, tabs)
|
||||
}
|
||||
|
||||
/// A Cmd-press held while a Shape Builder merge is computed reaches the lent Selection tool once
|
||||
/// the merge is applied, and its drag carries the artwork over another tab.
|
||||
#[test]
|
||||
fn a_cmd_drag_held_during_a_merge_activates_another_tab() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width":800,"height":200,"name":"Source"})).unwrap();
|
||||
for k in 0..40 {
|
||||
app.run("shape.rectangle", json!({"x": k * 10, "y": 0, "width": 20, "height": 20})).unwrap();
|
||||
}
|
||||
app.run("select.all", json!({})).unwrap();
|
||||
app.run("file.new", json!({"width":800,"height":200,"name":"Target"})).unwrap();
|
||||
app.session.set_active(0);
|
||||
app.select_tool("shapeBuilder");
|
||||
app.ui.task_bar = false;
|
||||
app.ui.view.rulers = false;
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
app.ui_ctx = Some(ctx.clone());
|
||||
frame(&mut app, &ctx, 0.0, vec![]);
|
||||
let tabs = frame(&mut app, &ctx, 0.01, vec![]);
|
||||
let view = app.view_info();
|
||||
app.session.pointer(&PointerEvent::new(PointerKind::Move, 15.0, 10.0), view).unwrap();
|
||||
app.session.tool_poll(view, true).unwrap();
|
||||
app.session.pointer(&PointerEvent::new(PointerKind::Down, 15.0, 10.0), view).unwrap();
|
||||
app.session.pointer(&PointerEvent::new(PointerKind::Up, 15.0, 10.0), view).unwrap();
|
||||
assert!(app.session.tool_editing(), "the click starts a merge on another thread");
|
||||
let grab = canvas::Xf::new(app.canvas_rect.unwrap(), app.view().unwrap()).to_screen(Point::new(355.0, 10.0));
|
||||
let modifiers = egui::Modifiers::COMMAND;
|
||||
frame(
|
||||
&mut app,
|
||||
&ctx,
|
||||
0.05,
|
||||
vec![
|
||||
Event::ModifiersChanged(modifiers),
|
||||
Event::PointerMoved(grab),
|
||||
Event::PointerButton { pos: grab, button: PointerButton::Primary, pressed: true, modifiers },
|
||||
],
|
||||
);
|
||||
assert_eq!(app.session.tool_id(), "shapeBuilder", "the press waits for the merge");
|
||||
let r = app.session.tool_poll(view, true);
|
||||
canvas::apply_requests(&mut app, r);
|
||||
frame(&mut app, &ctx, 0.08, vec![]);
|
||||
assert_eq!(app.session.tool_id(), "selection", "the held press borrowed the Selection tool");
|
||||
frame(&mut app, &ctx, 0.1, vec![Event::PointerMoved(grab + egui::vec2(20.0, 10.0))]);
|
||||
let tab = tabs[1].center();
|
||||
frame(&mut app, &ctx, 0.2, vec![Event::PointerMoved(tab)]);
|
||||
frame(&mut app, &ctx, 0.25, vec![]);
|
||||
frame(&mut app, &ctx, 0.8, vec![]);
|
||||
assert_eq!(app.session.active_index(), Some(1), "holding the artwork over the tab activates it");
|
||||
}
|
||||
|
||||
/// Verify that leaving a tab restarts its dwell timer and hovering its close button never activates it.
|
||||
#[test]
|
||||
fn tab_hover_delay_restarts_after_leaving_and_close_button_does_not_activate() {
|
||||
|
||||
Reference in New Issue
Block a user