mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-08 22:28:09 +00:00
Shortcuts: an Escape that cancels a Tools or ruler move runs no Escape command
A command bound to plain Escape no longer runs when that Escape cancels a floating Tools panel move or a ruler-origin drag, nor on the key repeats while Escape stays held. The next separate Escape press runs it as before. A test binds Select None to Escape and holds Escape through both cancels.
This commit is contained in:
@@ -350,10 +350,12 @@ pub fn handle(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
||||
let row_key = |chord: &craft_keymap::Chord| {
|
||||
rows_keys && chord.is_plain() && !chord.mods.shift && matches!(chord.key, craft_keymap::Key::Delete | craft_keymap::Key::Backspace)
|
||||
};
|
||||
// An Escape that ended a ruler-origin drag or floating Tools move runs no command bound to it.
|
||||
let gesture_escape = |chord: &craft_keymap::Chord| escape_ended_gesture && chord.is_plain() && chord.key == craft_keymap::Key::Escape;
|
||||
let hits = dispatch(app, ctx, |hit| {
|
||||
let chord = &hit.trigger.chord;
|
||||
let shifted_punctuation = chord.mods.shift && chord.key.name().chars().all(|c| !c.is_alphanumeric());
|
||||
!(chord.is_plain() && types_text(chord.key) && !shifted_punctuation || row_key(chord))
|
||||
!(chord.is_plain() && types_text(chord.key) && !shifted_punctuation || row_key(chord) || gesture_escape(chord))
|
||||
});
|
||||
let ran = !hits.is_empty();
|
||||
for c in hits {
|
||||
|
||||
@@ -465,6 +465,29 @@ fn held_escape_that_cancels_ruler_origin_drag_keeps_the_tool() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn held_escape_that_cancels_a_move_skips_a_command_bound_to_escape() {
|
||||
for ruler in [false, true] {
|
||||
let ctx = egui::Context::default();
|
||||
let mut app = in_screen_mode(&ctx, 0);
|
||||
app.run("shortcuts.set", json!({"id": "select.none", "shortcut": "Escape", "force": true})).unwrap();
|
||||
let selected = app.session.active().unwrap().selection.objects.clone();
|
||||
assert!(!selected.is_empty());
|
||||
let to = if ruler { begin_ruler_origin_drag(&mut app, &ctx) } else { begin_tools_move(&mut app, &ctx).1 };
|
||||
frame(&mut app, &ctx, escape_event(true, false));
|
||||
assert_eq!(app.session.active().unwrap().selection.objects, selected, "the cancelling Escape runs no command (ruler: {ruler})");
|
||||
for _ in 0..3 {
|
||||
frame(&mut app, &ctx, escape_event(true, true));
|
||||
}
|
||||
release_drag(&mut app, &ctx, to);
|
||||
frame(&mut app, &ctx, escape_event(true, true));
|
||||
assert_eq!(app.session.active().unwrap().selection.objects, selected, "held Escape runs no command (ruler: {ruler})");
|
||||
frame(&mut app, &ctx, escape_event(false, false));
|
||||
frame(&mut app, &ctx, escape());
|
||||
assert!(app.session.active().unwrap().selection.objects.is_empty(), "the next Escape runs the command (ruler: {ruler})");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_popup_takes_escape_before_full_screen_exits() {
|
||||
let ctx = egui::Context::default();
|
||||
|
||||
Reference in New Issue
Block a user