View: Escape during a canvas pan or zoom drag keeps full screen

A Hand or Space drag, a middle-button pan, a Zoom tool drag, a Rotate View
drag or a touch gesture is held in the canvas's drag state, which the tool
busy check does not see. Escape pressed while one is held no longer leaves
Full Screen Mode, closes the Edit Toolbar drawer or ends another action; an
Escape after the release does.
This commit is contained in:
dotCooCoo
2026-10-31 02:52:22 +07:00
committed by bflatastic
parent 030baab798
commit d792557bbe
3 changed files with 57 additions and 3 deletions
+5
View File
@@ -164,6 +164,11 @@ enum Drag {
Present,
}
/// Whether the canvas is holding a pointer drag across frames.
pub(crate) fn dragging(ctx: &egui::Context) -> bool {
ctx.data(|d| d.get_temp::<Drag>(drag_id()).is_some())
}
/// Paint the document canvas, complete or cached artwork, navigation and tool overlays.
pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
let t = Tokens::get(ui.ctx());
+4 -3
View File
@@ -205,10 +205,11 @@ pub fn handle(app: &mut VectorcraftApp, ctx: &egui::Context) {
presentation_keys(app, ctx, escape_pair);
return;
}
let escape_ended_gesture = crate::canvas::ruler_origin_dragging(ctx) || crate::tools_float::escape_cancelled_move(ctx);
let escape_held_by_drag =
crate::canvas::dragging(ctx) || crate::canvas::ruler_origin_dragging(ctx) || crate::tools_float::escape_cancelled_move(ctx);
let typing = ctx.egui_wants_keyboard_input();
// Escape closes Edit Toolbar's drawer first (egui drops a drag from it on Escape already).
if app.ui.tools_drawer && !typing && !escape_ended_gesture && ctx.input_mut(|i| i.consume_key(Modifiers::NONE, Key::Escape)) {
if app.ui.tools_drawer && !typing && !escape_held_by_drag && ctx.input_mut(|i| i.consume_key(Modifiers::NONE, Key::Escape)) {
app.ui.tools_drawer = false;
}
let view = app.view_info();
@@ -249,7 +250,7 @@ pub fn handle(app: &mut VectorcraftApp, ctx: &egui::Context) {
ctx.input_mut(|i| i.consume_key(Modifiers::NONE, k));
ctx.input_mut(|i| i.consume_key(Modifiers::SHIFT, k));
}
if k == Key::Escape && !busy && !claimed && !escape_ended_gesture {
if k == Key::Escape && !busy && !claimed && !escape_held_by_drag {
if app.session.active().is_some_and(|d| d.doc.pattern_edit.is_some()) {
let _ = app.run("object.pattern.done", json!({}));
} else if app.session.active().is_some_and(|d| d.isolation.is_some()) {
+48
View File
@@ -223,6 +223,54 @@ fn a_tool_drag_takes_escape_before_full_screen_exits() {
assert_eq!(app.ui.screen_mode, 0);
}
fn navigation_drag_keeps_screen_mode(kind: &str) {
for mode in [1, 2] {
let ctx = egui::Context::default();
let mut app = in_screen_mode(&ctx, mode);
let button = match kind {
"hand" => {
app.select_tool("hand");
egui::PointerButton::Primary
}
"middle" => egui::PointerButton::Middle,
"zoom_box" => {
app.select_tool("zoom");
app.session.prefs.animated_zoom = false;
egui::PointerButton::Primary
}
_ => panic!("unknown navigation drag"),
};
frame(&mut app, &ctx, vec![]);
let start = app.canvas_rect.unwrap().center();
let end = start + egui::vec2(35.0, 20.0);
let pointer = |pos, pressed| egui::Event::PointerButton { pos, button, pressed, modifiers: Default::default() };
frame(&mut app, &ctx, vec![egui::Event::PointerMoved(start), pointer(start, true)]);
frame(&mut app, &ctx, vec![egui::Event::PointerMoved(end)]);
assert!(crate::canvas::dragging(&ctx), "{kind} drag began in mode {mode}");
frame(&mut app, &ctx, escape());
assert_eq!(app.ui.screen_mode, mode, "{kind} drag holds Escape in mode {mode}");
frame(&mut app, &ctx, vec![pointer(end, false)]);
assert!(!crate::canvas::dragging(&ctx), "{kind} drag ended in mode {mode}");
frame(&mut app, &ctx, escape());
assert_eq!(app.ui.screen_mode, 0, "Escape after {kind} drag in mode {mode}");
}
}
#[test]
fn a_hand_drag_keeps_both_full_screen_modes_until_release() {
navigation_drag_keeps_screen_mode("hand");
}
#[test]
fn a_middle_button_pan_keeps_both_full_screen_modes_until_release() {
navigation_drag_keeps_screen_mode("middle");
}
#[test]
fn a_zoom_box_drag_keeps_both_full_screen_modes_until_release() {
navigation_drag_keeps_screen_mode("zoom_box");
}
#[test]
fn a_ruler_origin_drag_takes_escape_before_full_screen_exits() {
for mode in [1, 2] {