Merge pull request #628 from MarekSpodBiedry/issue-505

This commit is contained in:
Claude committed 2026-10-10 18:51:15 +00:00
commit 5727754a54
3 files changed
+72 -2

No files matched your search

+15 -1
View File
@@ -215,8 +215,22 @@ pub fn viewer_hook(
return;
}
// Interaction over the image.
let resp = ui.interact(map.area, egui::Id::new("viewer-camera-tracker"), Sense::click_and_drag());
// While Space (Hand tool) is held the overlay only hovers, so the viewer underneath gets the pan drag.
let sense = if super::space_hand(&ctx) { Sense::hover() } else { Sense::click_and_drag() };
let resp = ui.interact(map.area, egui::Id::new("viewer-camera-tracker"), sense);
app.auto.add("viewer.cameraTracker", map.area, "3D Camera Tracker points");
// The overlay is on top of the viewer, so a middle-button drag lands here: pan the viewer like the Hand tool.
if resp.dragged_by(egui::PointerButton::Middle) {
let pid = egui::Id::new("viewer-camera-tracker-pan");
if resp.drag_started() {
let start_pan = app.ui.viewer.pan;
ui.data_mut(|d| d.insert_temp(pid, start_pan));
}
if let (Some(start_pan), Some(d)) = (ui.data(|m| m.get_temp::<[f32; 2]>(pid)), resp.total_drag_delta()) {
app.ui.viewer.pan = [start_pan[0] + d.x, start_pan[1] + d.y];
}
return;
}
for (id, sp, r) in hits.iter().take(400) {
app.auto.add(&format!("viewer.cameraTracker.point.{id}"), Rect::from_center_size(*sp, vec2(r * 2.0 + 4.0, r * 2.0 + 4.0)), "track point");
}
+3 -1
View File
@@ -1046,7 +1046,9 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
}
}
let gid = egui::Id::new("viewer-gesture");
if let Some(hp) = resp.hover_pos() {
// An overlay on top of the viewer (e.g. the camera tracker points) takes the hover, but the pointer is still over the viewer: keep wheel zoom working.
let hover_pos = resp.hover_pos().or_else(|| if resp.contains_pointer() { ui.input(|i| i.pointer.hover_pos()) } else { None });
if let Some(hp) = hover_pos {
app.pointer_comp = Some({
let c = map.to_comp(hp);
[c[0] as f32, c[1] as f32]
+54
View File
@@ -145,6 +145,60 @@ fn viewer_points_selection_and_effect_controls() {
assert!(h.state().session.is_enabled("track.camera"));
}
/// Drag with `button` from `from` to `to` in steps, then release.
fn drag_with(h: &mut Harness<'_, EffectcraftApp>, button: egui::PointerButton, from: egui::Pos2, to: egui::Pos2) {
h.input_mut().events.push(egui::Event::PointerMoved(from));
h.input_mut().events.push(egui::Event::PointerButton { pos: from, button, pressed: true, modifiers: Default::default() });
h.step();
for i in 1..=8 {
h.input_mut().events.push(egui::Event::PointerMoved(from + (to - from) * (i as f32 / 8.0)));
h.step();
}
h.input_mut().events.push(egui::Event::PointerButton { pos: to, button, pressed: false, modifiers: Default::default() });
h.run_steps(3);
}
/// #505: with the track points shown, the wheel still zooms the viewer, and a middle-button drag
/// and a Spacebar (Hand tool) drag over the points still pan it.
#[test]
fn viewer_zooms_and_pans_over_the_track_points() {
let (a, ..) = app();
let mut h = Harness::builder().with_size(egui::vec2(1600.0, 1000.0)).build_eframe(|_| a);
h.state_mut().show_panel(PanelKind::Composition);
h.run_steps(4);
// Wheel over a point: zooms.
let at = rect(&h, "viewer.cameraTracker.point.7").center();
let zoom = h.state().ui.viewer.zoom;
h.input_mut().events.push(egui::Event::PointerMoved(at));
h.input_mut().events.push(egui::Event::MouseWheel {
unit: egui::MouseWheelUnit::Point,
delta: egui::vec2(0.0, 120.0),
modifiers: Default::default(),
phase: egui::TouchPhase::Move,
});
h.run_steps(20);
assert_ne!(h.state().ui.viewer.zoom, zoom, "the wheel zooms over the track points");
// Middle-button drag from a point: pans, and selects nothing.
let at = rect(&h, "viewer.cameraTracker.point.7").center();
let before = h.state().ui.viewer.pan;
drag_with(&mut h, egui::PointerButton::Middle, at, at + egui::vec2(120.0, 60.0));
let after = h.state().ui.viewer.pan;
assert!((after[0] - before[0] - 120.0).abs() < 1.0 && (after[1] - before[1] - 60.0).abs() < 1.0, "{before:?} → {after:?}");
assert!(h.state().session.state.camera_points.is_empty(), "a pan selects no points");
// Spacebar held: a primary drag from a point pans instead of drawing a marquee.
let at = rect(&h, "viewer.cameraTracker.point.7").center();
let space = |h: &mut Harness<'_, EffectcraftApp>, pressed: bool| {
h.input_mut().events.push(egui::Event::Key { key: egui::Key::Space, physical_key: None, pressed, repeat: false, modifiers: Default::default() });
h.step();
};
space(&mut h, true);
drag_with(&mut h, egui::PointerButton::Primary, at, at + egui::vec2(80.0, 40.0));
space(&mut h, false);
let end = h.state().ui.viewer.pan;
assert!((end[0] - after[0] - 80.0).abs() < 1.0 && (end[1] - after[1] - 40.0).abs() < 1.0, "{after:?} → {end:?}");
assert!(h.state().session.state.camera_points.is_empty(), "a Spacebar pan selects no points");
}
/// Step the UI until background frame renders have landed.
fn settle(h: &mut Harness<'_, EffectcraftApp>) {
for _ in 0..600 {