mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 11:16:56 -04:00
Fix #1881: a Ctrl/Cmd drag while typing keeps what was typed
With the Type tool editing, a press with Ctrl (Cmd on the Mac) lends the Selection tool for the drag. Its drag joined the open typing session, so its preview started from the document before the typing: the type moved or scaled and lost what had just been typed. The typing is now kept as its own undo step before the lent tool takes the press, as Undo already does, and typing goes on after the drag.
This commit is contained in:
1 parent
6fd31d4dbd
commit
7f1ad31a7b
3 files changed
+31
No files matched your search
@@ -457,6 +457,7 @@ pub(crate) fn unique_name(base: &str, taken: impl Fn(&str) -> bool) -> String {
|
||||
(2..).map(|i| format!("{base} {i}")).find(|n| !taken(n)).unwrap_or_else(|| base.to_string())
|
||||
}
|
||||
|
||||
pub(crate) use edit::{settle_interaction, typing_in_progress};
|
||||
pub(crate) use vectorcraft_doc::range::parse_range;
|
||||
|
||||
/// A date param in Unix seconds that defaults to the clock: `None` when absent (now, see
|
||||
|
||||
@@ -150,6 +150,30 @@ fn undo_while_typing_takes_back_only_the_typing_and_redo_returns_it() {
|
||||
assert_eq!(obj(&s, id).plain_text(), "abc!");
|
||||
}
|
||||
|
||||
/// #1881: a Cmd/Ctrl drag while typing (the Selection tool lent to the Type tool) moves the type
|
||||
/// and keeps what was typed, and typing goes on after it.
|
||||
#[test]
|
||||
fn a_cmd_drag_while_typing_moves_the_type_and_keeps_the_typing() {
|
||||
let mut s = session();
|
||||
let v = ViewInfo::default();
|
||||
s.select_tool("type", v).unwrap();
|
||||
click(&mut s, 200.0, 200.0);
|
||||
let id = s.doc().unwrap().selection.objects[0];
|
||||
s.tool_text("Hello", v).unwrap();
|
||||
let before = s.doc().unwrap().doc.bounds_of(&[id], false).unwrap();
|
||||
let (at, cmd) = (before.center(), Mods { cmd: true, ..Default::default() });
|
||||
for (kind, dx) in [(PointerKind::Down, 0.0), (PointerKind::Drag, 100.0), (PointerKind::Up, 100.0)] {
|
||||
s.pointer(&PointerEvent::new(kind, at.x + dx, at.y).with_mods(cmd), v).unwrap();
|
||||
}
|
||||
assert_eq!(obj(&s, id).plain_text(), "Hello", "the typing is kept");
|
||||
let moved = s.doc().unwrap().doc.bounds_of(&[id], false).unwrap();
|
||||
assert!(moved.x0 - before.x0 > 50.0, "the type moved: {before:?} → {moved:?}");
|
||||
s.tool_text("!", v).unwrap();
|
||||
assert_eq!(obj(&s, id).plain_text(), "Hello!");
|
||||
let after = s.doc().unwrap().doc.bounds_of(&[id], false).unwrap();
|
||||
assert!((after.x0 - moved.x0).abs() < 1e-6, "and stays where it was moved: {after:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn undo_during_a_drag_takes_back_only_the_drag() {
|
||||
let mut s = session();
|
||||
|
||||
@@ -115,6 +115,12 @@ impl Session {
|
||||
return *ev;
|
||||
}
|
||||
let Some(id) = self.lent_tool(self.tool.id()) else { return *ev };
|
||||
// Typing in progress is kept as its own step first: the lent tool's drag previews from the
|
||||
// document its interaction started from, which would drop the typing (#1881).
|
||||
if crate::cmd::typing_in_progress(self) {
|
||||
// Fails only without a document, and then there is no typing to keep.
|
||||
let _ = crate::cmd::settle_interaction(self);
|
||||
}
|
||||
let lent = self.make_tool(id);
|
||||
self.lender = Some(std::mem::replace(&mut self.tool, lent));
|
||||
PointerEvent { mods: Mods { cmd: false, ..ev.mods }, ..*ev }
|
||||
|
||||
Reference in new issue
Block a user