fix(ui): restore free Shift-middle orbit

This commit is contained in:
lillith committed 2026-10-12 00:30:05 +02:00
1 parent e171ff07ad
commit 8601e38d4b
2 files changed
+31 -4

No files matched your search

+28 -2
View File
@@ -1534,7 +1534,11 @@ pub fn show(app: &mut SolveApp, ui: &mut egui::Ui) {
if mode == Some(NavMode::Orbit) { if mode == Some(NavMode::Orbit) {
let press = ui.input(|i| i.pointer.press_origin()); let press = ui.input(|i| i.pointer.press_origin());
app.cancel_view_animation(); app.cancel_view_animation();
orbit_drag(app, rect, f64::from(delta.x), f64::from(delta.y), press, mods.shift, true); // Shift can be required to enter orbit (Fusion/Inventor middle drag), rather
// than an additional request for snapping. Only an extra modifier snaps.
let without_shift = egui::Modifiers { shift: false, ..mods };
let snap = mods.shift && (!middle || crate::prefs::nav_mode(app, middle, secondary_down, without_shift) == Some(NavMode::Orbit));
orbit_drag(app, rect, f64::from(delta.x), f64::from(delta.y), press, snap, true);
} else { } else {
if matches!(mode, Some(NavMode::Pan | NavMode::Zoom)) { if matches!(mode, Some(NavMode::Pan | NavMode::Zoom)) {
app.viewport.orbit_snap = None; app.viewport.orbit_snap = None;
@@ -3408,7 +3412,8 @@ mod tests {
h.call("ui.view", json!({"view":"front"})); h.call("ui.view", json!({"view":"front"}));
let before = h.app.cam; let before = h.app.cam;
h.call("ui.drag", json!({"x0":800,"y0":500,"x1":1020,"y1":500,"button":"middle","shift":true,"steps":40})); h.call("ui.drag", json!({"x0":800,"y0":500,"x1":1020,"y1":500,"button":"middle","shift":true,"steps":40}));
assert!((h.app.cam.yaw - std::f64::consts::FRAC_PI_2).abs() < 1e-6, "before={before:?}, after={:?}", h.app.cam); assert!((h.app.cam.yaw - 1.76).abs() < 1e-6, "before={before:?}, after={:?}", h.app.cam);
assert!(h.app.viewport.orbit_snap.is_none());
h.call("ui.view", json!({"view":"front"})); h.call("ui.view", json!({"view":"front"}));
h.call("ui.drag", json!({"x0":800,"y0":500,"x1":850,"y1":520,"button":"middle"})); h.call("ui.drag", json!({"x0":800,"y0":500,"x1":850,"y1":520,"button":"middle"}));
assert_eq!(h.app.cam.yaw, before.yaw); assert_eq!(h.app.cam.yaw, before.yaw);
@@ -3416,6 +3421,27 @@ mod tests {
assert_ne!(h.app.cam.target, before.target); assert_ne!(h.app.cam.target, before.target);
} }
#[test]
fn preset_shift_middle_orbit_is_free_but_shift_right_orbit_snaps() {
for preset in ["fusion", "inventor"] {
let mut h = crate::scenario::Harness::new();
h.app.preferences.nav = preset.into();
h.call("ui.view", json!({"view":"front"}));
let before = h.app.cam;
h.call("ui.drag", json!({"x0":800,"y0":500,"x1":850,"y1":520,"button":"middle","shift":true,"steps":20}));
let mut expected = before;
expected.orbit(50.0, 20.0);
assert!((h.app.cam.yaw - expected.yaw).abs() < 1e-6, "{preset}: {:?}", h.app.cam);
assert!((h.app.cam.pitch - expected.pitch).abs() < 1e-6, "{preset}: {:?}", h.app.cam);
assert_eq!(h.app.cam.target, before.target);
assert_eq!(h.app.cam.distance, before.distance);
assert!(h.app.viewport.orbit_snap.is_none());
h.call("ui.view", json!({"view":"front"}));
h.call("ui.drag", json!({"x0":800,"y0":500,"x1":1020,"y1":500,"button":"right","shift":true,"steps":40}));
assert!((h.app.cam.yaw - std::f64::consts::FRAC_PI_2).abs() < 1e-6, "{preset}: {:?}", h.app.cam);
}
}
#[test] #[test]
fn axis_view_click_again_flips_and_drag_snaps() { fn axis_view_click_again_flips_and_drag_snaps() {
let mut h = crate::scenario::Harness::new(); let mut h = crate::scenario::Harness::new();
+3 -2
View File
@@ -14,8 +14,9 @@
row gives that item's menu. Rows drag into groups and other components. row gives that item's menu. Rows drag into groups and other components.
- **Viewport.** Click to select, Shift or Ctrl to add, drag for a window or crossing box. The - **Viewport.** Click to select, Shift or Ctrl to add, drag for a window or crossing box. The
wheel zooms at the cursor, the middle button pans and right-drag orbits freely (the mouse wheel zooms at the cursor, the middle button pans and right-drag orbits freely (the mouse
preset in Preferences switches to SolidWorks or Inventor style). Hold Shift during an orbit preset in Preferences switches to SolidWorks or Inventor style). Shift+middle orbits freely
to snap to the nearest standard or diagonal view; the default Shift+middle gesture also snaps. in the default and Inventor presets. Shift+right-drag snaps to the nearest standard or
diagonal view; Shift does not request snapping when the preset already requires it to orbit.
The axis view shows the world's X/Y/Z directions in SolidCraft's colors. Click a signed The axis view shows the world's X/Y/Z directions in SolidCraft's colors. Click a signed
axis tip to look along that axis; click the aligned tip again to look from the opposite side. axis tip to look along that axis; click the aligned tip again to look from the opposite side.
Drag the axis view to orbit around the view centre, with Shift for snapping. Top and bottom Drag the axis view to orbit around the view centre, with Shift for snapping. Top and bottom