mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-08 19:42:05 +00:00
M1, #1758: a primary drag let go during a pan still ends
This commit is contained in:
2 files changed
+48
-14
No files matched your search
@@ -148,6 +148,31 @@ fn import_dropped(app: &mut FigApp, ctx: &egui::Context, hover_pos: Option<egui:
|
||||
}
|
||||
}
|
||||
|
||||
/// One frame of a pan (the middle or a side button held, or Space + drag): the view follows the
|
||||
/// pointer from where the pan began, and the pan ends once no button that pans is held.
|
||||
fn pan_view(app: &mut FigApp, ctx: &egui::Context, pos: Pos2, mods: &egui::Modifiers, middle_down: bool) {
|
||||
if let Ok(ds) = app.session.ds_mut() {
|
||||
match app.canvas.middle_pan {
|
||||
None => app.canvas.middle_pan = Some((pos, ds.view.cx, ds.view.cy)),
|
||||
Some((p0, cx, cy)) => {
|
||||
let z = ds.view.zoom.max(1e-6);
|
||||
ds.view.cx = cx - f64::from(pos.x - p0.x) / z;
|
||||
ds.view.cy = cy - f64::from(pos.y - p0.y) / z;
|
||||
ds.revision += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// A primary drag under way when the pan began ends when its button is let go, pan or
|
||||
// not: the engine gets its release here, as it does over the canvas or off it.
|
||||
if app.canvas.dragging && !ctx.input(|i| i.pointer.primary_down()) {
|
||||
app.canvas.dragging = false;
|
||||
send(app, PointerKind::Up, pos, mods);
|
||||
}
|
||||
if !middle_down && !ctx.input(|i| i.pointer.primary_down()) {
|
||||
app.canvas.middle_pan = None;
|
||||
}
|
||||
}
|
||||
|
||||
/// The pointer and keys on the canvas. False when something on it with a cursor of its own has
|
||||
/// the pointer (a comment pin, a ruler guide, a gradient or padding handle): the tool's cursor
|
||||
/// then doesn't show.
|
||||
@@ -224,20 +249,7 @@ pub(super) fn input(app: &mut FigApp, ui: &mut Ui, resp: &egui::Response) -> boo
|
||||
// Middle-button (or side-button) / space panning.
|
||||
let middle_down = ctx.input(pan_button_down);
|
||||
if (middle_down || (app.canvas.space_pan && ctx.input(|i| i.pointer.primary_down()))) && resp.hovered() || app.canvas.middle_pan.is_some() {
|
||||
if let Ok(ds) = app.session.ds_mut() {
|
||||
match app.canvas.middle_pan {
|
||||
None => app.canvas.middle_pan = Some((pos, ds.view.cx, ds.view.cy)),
|
||||
Some((p0, cx, cy)) => {
|
||||
let z = ds.view.zoom.max(1e-6);
|
||||
ds.view.cx = cx - f64::from(pos.x - p0.x) / z;
|
||||
ds.view.cy = cy - f64::from(pos.y - p0.y) / z;
|
||||
ds.revision += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !middle_down && !ctx.input(|i| i.pointer.primary_down()) {
|
||||
app.canvas.middle_pan = None;
|
||||
}
|
||||
pan_view(app, &ctx, pos, &mods, middle_down);
|
||||
return true;
|
||||
}
|
||||
// A handle drag whose button went up ends first, wherever on the canvas the pointer is: over a
|
||||
|
||||
@@ -109,3 +109,25 @@ fn side_buttons_pan_like_the_middle_button() {
|
||||
check_button(b, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// A primary drag under way when a pan starts (a side or the middle button pressed mid-drag) ends
|
||||
/// when the primary button is let go during the pan: the engine gets the release, so its gesture
|
||||
/// isn't left open once the pan is over.
|
||||
#[test]
|
||||
fn a_primary_drag_released_during_a_pan_ends() {
|
||||
for pan in [PointerButton::Middle, PointerButton::Extra1] {
|
||||
let mut u = Frames::new();
|
||||
let rect = u.app.canvas.rect;
|
||||
let start = Pos2::new(rect.min.x + 200.0, rect.center().y);
|
||||
let moved = Pos2::new(rect.min.x + 400.0, rect.center().y);
|
||||
u.frame(vec![Event::PointerMoved(start)]);
|
||||
u.frame(vec![button(start, PointerButton::Primary, true)]);
|
||||
u.frame(vec![Event::PointerMoved(moved)]);
|
||||
assert!(u.app.session.tool.busy(), "{pan:?}: a primary drag is under way");
|
||||
u.frame(vec![button(moved, pan, true)]);
|
||||
u.frame(vec![button(moved, PointerButton::Primary, false)]);
|
||||
u.frame(vec![button(moved, pan, false)]);
|
||||
u.frame(vec![]);
|
||||
assert!(!u.app.session.tool.busy(), "{pan:?}: the primary release reached the engine");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user