Open and Place: a file read in the background waits for a busy tool only during a drag

A file opened or placed off the UI thread waited while the active tool
reported busy. The Dimension tool also reports busy between its clicks,
so after one click a ready file stayed queued with its spinner until
the dimension was finished or canceled. Files also waited between the
clicks of the Blend tool.

The session now records whether the pointer button is held. A file
waits for a busy tool only while the button is held. A file that
opens between a tool's clicks resets the tool, as a switch of
documents does; a file placed in the active document leaves the
tool's clicks in place. Files still wait while a dialog is open, a
drag is under way or a preview is open, and a tool's preview between
its clicks counts as one (the Flare tool after its center drag, the
Dimension tool's line once the pointer moves after its second click).
This commit is contained in:
dotCooCoo
2026-10-24 02:05:19 +07:00
committed by bflatastic
parent 78213cdf00
commit 2db1ada660
5 changed files with 166 additions and 10 deletions
+4
View File
@@ -1425,6 +1425,9 @@ pub struct Session {
pub(crate) liquify_stroke: Option<Box<cmd::distortcmds::LiquifyStroke>>,
/// A press on the Plane Switching Widget is under way: its drag and release are the widget's.
pub(crate) plane_widget_press: bool,
/// The pointer button is held: the last pointer event was a press or a drag, not a release or
/// a move ([`Session::pointer_held`]).
pub(crate) pointer_held: bool,
/// A guide being dragged out of a ruler ([`Session::ruler_guide`]).
pub(crate) ruler_guide: Option<vectorcraft_tools::rulerguide::NewGuide>,
/// Which selected type overflows its frame, for the markers every tool but the Type tools shows.
@@ -1520,6 +1523,7 @@ impl Session {
envelope_defaults: None,
liquify_stroke: None,
plane_widget_press: false,
pointer_held: false,
ruler_guide: None,
overflow_marks: Default::default(),
font_search: None,
+20
View File
@@ -825,6 +825,26 @@ fn selection_tool_drag_is_one_undo_step() {
assert_eq!(s.doc().unwrap().doc.node(a).unwrap().geometric_bounds().unwrap().x0, 100.0);
}
/// The pointer button is held from a press or a drag until a release or a move. The Dimension
/// tool stays busy after its first click with the button released, waiting for the second one.
#[test]
fn the_pointer_is_held_from_a_press_until_a_release_or_a_move() {
let mut s = session();
let v = ViewInfo::default();
s.select_tool("dimension", v).unwrap();
let mut held = vec![];
for (kind, x) in [(PointerKind::Down, 100.0), (PointerKind::Drag, 100.0), (PointerKind::Up, 100.0)] {
s.pointer(&PointerEvent::new(kind, x, 100.0), v).unwrap();
held.push(s.pointer_held());
}
assert!(s.tool_busy(), "the first point waits for the second");
for (kind, x) in [(PointerKind::Move, 200.0), (PointerKind::Down, 300.0), (PointerKind::Drag, 310.0), (PointerKind::Move, 320.0)] {
s.pointer(&PointerEvent::new(kind, x, 100.0), v).unwrap();
held.push(s.pointer_held());
}
assert_eq!(held, [true, true, false, false, true, true, false]);
}
/// How many steps there are to undo and to redo, and whether the document has unsaved changes.
pub(crate) fn history(s: &Session) -> (usize, usize, bool) {
let st = s.doc().unwrap();
+12
View File
@@ -313,6 +313,11 @@ impl Session {
/// Feed a pointer event to the active tool. Returns requests for the UI.
pub fn pointer(&mut self, ev: &PointerEvent, view: ViewInfo) -> Result<Vec<UiRequest>> {
self.last_view = view;
match ev.kind {
PointerKind::Down | PointerKind::Drag => self.pointer_held = true,
PointerKind::Up | PointerKind::Move => self.pointer_held = false,
PointerKind::DoubleClick => {}
}
// The Plane Switching Widget takes its clicks whatever the tool.
if let Some(r) = self.plane_widget_pointer(ev, view) {
return r;
@@ -437,6 +442,13 @@ impl Session {
self.tool.busy()
}
/// Is the pointer button held: was the last pointer event a press or a drag, not a release or a
/// move? A tool that is busy while the button is not held is waiting between its clicks (the
/// Dimension tool after its first point).
pub fn pointer_held(&self) -> bool {
self.pointer_held
}
/// Is the active tool moving, scaling or rotating the selection with a drag?
pub fn tool_transforming(&self) -> bool {
self.tool.transforming()