Merge pull request #233 from theironchef/fix/canvas-edge-click
Canvas: a click just outside the canvas doesn't reach the tools
This commit is contained in:
commit
597b651bb6
|
|
@ -444,10 +444,15 @@ fn handle_input(app: &mut VectorcraftApp, ui: &Ui, resp: &egui::Response, rect:
|
|||
let tool = app.session.tool_id();
|
||||
let pan_mode = space || tool == "hand";
|
||||
let middle_pan = matches!(drag, Some(Drag::Pan { middle: true, .. }));
|
||||
if pointer.primary_pressed() && resp.hovered() && !middle_pan {
|
||||
// egui counts a press a few pixels outside the canvas as on it (its interaction radius): only a
|
||||
// press on the canvas itself reaches the tools, else it would land at the canvas's centre.
|
||||
if pointer.primary_pressed()
|
||||
&& resp.hovered()
|
||||
&& !middle_pan
|
||||
&& let Some(p) = hover
|
||||
{
|
||||
ui.ctx().memory_mut(|mem| mem.stop_text_input());
|
||||
app.ui.flyout = None;
|
||||
let p = hover.unwrap_or(rect.center());
|
||||
let d = if pan_mode {
|
||||
Drag::Pan { start: p, center: v.center, middle: false }
|
||||
} else if tool == "zoom" {
|
||||
|
|
@ -468,9 +473,12 @@ fn handle_input(app: &mut VectorcraftApp, ui: &Ui, resp: &egui::Response, rect:
|
|||
kind
|
||||
};
|
||||
ui.data_mut(|dd| dd.insert_temp(drag_id(), d));
|
||||
} else if drag.is_none() && resp.hovered() && pointer.button_pressed(egui::PointerButton::Middle) {
|
||||
} else if drag.is_none()
|
||||
&& resp.hovered()
|
||||
&& pointer.button_pressed(egui::PointerButton::Middle)
|
||||
&& let Some(start) = hover
|
||||
{
|
||||
// Middle-button drag pans the view whatever the tool.
|
||||
let start = hover.unwrap_or(rect.center());
|
||||
ui.data_mut(|dd| dd.insert_temp(drag_id(), Drag::Pan { start, center: v.center, middle: true }));
|
||||
} else if let Some(d) = drag {
|
||||
let p = pointer.interact_pos().unwrap_or(rect.center());
|
||||
|
|
@ -1411,6 +1419,42 @@ mod tests {
|
|||
egui::Event::PointerButton { pos, button: egui::PointerButton::Middle, pressed, modifiers: Default::default() }
|
||||
}
|
||||
|
||||
/// One headless frame with the canvas under a 40-point bar, as it is under the document tabs.
|
||||
fn frame_under_bar(app: &mut VectorcraftApp, ctx: &egui::Context, events: Vec<egui::Event>) {
|
||||
let raw = egui::RawInput { screen_rect: Some(egui::Rect::from_min_size(Pos2::ZERO, vec2(800.0, 600.0))), events, ..Default::default() };
|
||||
let mut out = ctx.run_ui(raw, |ui| {
|
||||
ui.add_space(40.0);
|
||||
show(app, ui);
|
||||
});
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_click_just_outside_the_canvas_does_not_reach_the_tool() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
// A square in the middle of the artboard, where the view is centred.
|
||||
let id = app.session.execute("shape.rectangle", &json!({"x": 180, "y": 130, "width": 40, "height": 40})).unwrap()["id"].as_u64().unwrap();
|
||||
app.session.execute("select.none", &json!({})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
frame_under_bar(&mut app, &ctx, vec![]);
|
||||
let rect = app.canvas_rect.unwrap();
|
||||
let click = |app: &mut VectorcraftApp, p: Pos2| {
|
||||
let button =
|
||||
|pressed| egui::Event::PointerButton { pos: p, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
|
||||
frame_under_bar(app, &ctx, vec![egui::Event::PointerMoved(p)]);
|
||||
frame_under_bar(app, &ctx, vec![button(true)]);
|
||||
frame_under_bar(app, &ctx, vec![button(false)]);
|
||||
};
|
||||
let selected = |app: &VectorcraftApp| app.session.active().unwrap().selection.objects.clone();
|
||||
// Two pixels above the canvas, within egui's interaction radius: nothing happens.
|
||||
click(&mut app, pos2(rect.center().x, rect.top() - 2.0));
|
||||
assert!(selected(&app).is_empty(), "a click above the canvas selected {:?}", selected(&app));
|
||||
// At the canvas's centre: the square.
|
||||
click(&mut app, rect.center());
|
||||
assert_eq!(selected(&app), vec![vectorcraft_doc::NodeId(id)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn middle_drag_pans_the_view_with_any_tool() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
|
|
|
|||
Loading…
Reference in New Issue