Shape Builder: a deferred pointer reply names the tool active after the gesture

This commit is contained in:
dotCooCoo
2026-10-29 10:49:02 -07:00
parent 061b519e20
commit c45707a13e
3 changed files with 12 additions and 18 deletions
+5 -5
View File
@@ -88,8 +88,8 @@ impl VectorcraftApp {
}
}
}
control::Outcome::AfterToolEdit { from, to, document, tool } => {
self.pointer_replies.push(control::PendingPointerReply { from, to, document, tool, reply });
control::Outcome::AfterToolEdit { from, to, document } => {
self.pointer_replies.push(control::PendingPointerReply { from, to, document, reply });
}
}
}
@@ -123,11 +123,11 @@ impl VectorcraftApp {
/// Sends the waiting `ui.pointer` replies whose events have been made.
fn send_pointer_replies(&mut self) {
for pending in std::mem::take(&mut self.pointer_replies) {
let control::PendingPointerReply { from, to, document, tool, reply } = pending;
let control::PendingPointerReply { from, to, document, reply } = pending;
if self.session.input_applied(from, to) {
let _ = reply.send(control::pointer_reply_for(self, document, &tool));
let _ = reply.send(control::pointer_reply_for(self, document));
} else {
self.pointer_replies.push(control::PendingPointerReply { from, to, document, tool, reply });
self.pointer_replies.push(control::PendingPointerReply { from, to, document, reply });
}
}
}
+4 -6
View File
@@ -99,7 +99,6 @@ pub(crate) struct PendingPointerReply {
pub from: u64,
pub to: u64,
pub document: Option<u64>,
pub tool: String,
pub reply: Sender<ControlResponse>,
}
@@ -160,16 +159,15 @@ pub enum Outcome {
from: u64,
to: u64,
document: Option<u64>,
tool: String,
},
}
/// The reply to `ui.pointer`: the selection, the key object and the active tool.
pub(crate) fn pointer_reply(app: &mut VectorcraftApp) -> Value {
pointer_reply_for(app, app.session.active().map(|d| d.uid), app.session.tool_id())
pointer_reply_for(app, app.session.active().map(|d| d.uid))
}
pub(crate) fn pointer_reply_for(app: &VectorcraftApp, document: Option<u64>, tool: &str) -> Value {
pub(crate) fn pointer_reply_for(app: &VectorcraftApp, document: Option<u64>) -> Value {
let state = document.and_then(|uid| app.session.documents().iter().find(|d| d.uid == uid));
match state {
Some(state) => json!({
@@ -177,7 +175,7 @@ pub(crate) fn pointer_reply_for(app: &VectorcraftApp, document: Option<u64>, too
"result": {
"selection": state.selection.objects.iter().map(|id| id.0).collect::<Vec<_>>(),
"key": state.selection.key.map(|id| id.0),
"tool": tool,
"tool": app.session.tool_id(),
}
}),
None => json!({"ok": false, "error": "the gesture's document is no longer open"}),
@@ -580,7 +578,7 @@ fn pointer_events(app: &mut VectorcraftApp, ctx: &egui::Context, req: &ControlRe
// a hover is answered at once.
let to = app.session.input_count();
if !app.session.input_applied(from, to) {
return Outcome::AfterToolEdit { from, to, document: app.session.active().map(|d| d.uid), tool: app.session.tool_id().to_string() };
return Outcome::AfterToolEdit { from, to, document: app.session.active().map(|d| d.uid) };
}
Outcome::Done(pointer_reply(app))
}
+3 -7
View File
@@ -20,21 +20,17 @@ fn deferred_pointer_reply_uses_the_gesture_document_after_file_new() {
app.run("select.set", json!({"ids": [id]})).unwrap();
let (reply, received) = std::sync::mpsc::channel();
let at = app.session.input_count();
app.pointer_replies.push(super::PendingPointerReply {
from: at,
to: at,
document: app.session.active().map(|d| d.uid),
tool: app.session.tool_id().to_string(),
reply,
});
app.pointer_replies.push(super::PendingPointerReply { from: at, to: at, document: app.session.active().map(|d| d.uid), reply });
app.run("file.new", json!({"width": 200, "height": 200})).unwrap();
app.run("tool.select", json!({"tool": "rectangle"})).unwrap();
app.answer_pointer_replies(&egui::Context::default());
let result = received.try_recv().unwrap();
assert_eq!(result["ok"], true, "{result}");
assert_eq!(result["result"]["selection"], json!([id]));
assert_eq!(result["result"]["key"], Value::Null);
assert_eq!(result["result"]["tool"], "rectangle");
}
#[test]