Preferences: reverse horizontal pan direction (#2007) (#2047)

Thanks @lasselian.
This commit is contained in:
Lasse Lian authored and GitHub committed 2026-10-18 03:12:23 -04:00
1 parent 8f768b65c8
commit b685b7301f
6 files changed
+34 -2

No files matched your search

+2 -1
View File
@@ -307,7 +307,8 @@ pub(crate) fn handle(app: &mut SolveApp, ui: &mut egui::Ui, rect: Rect, resp: &e
// (its End was lost); a stuck flag would pan future mouse input.
app.viewport.trackpad_gesture = false;
}
let pan = if trackpad_pan { raw.pan } else { egui::Vec2::ZERO } + raw.mouse_pan;
let mut pan = if trackpad_pan { raw.pan } else { egui::Vec2::ZERO } + raw.mouse_pan;
pan.x *= crate::prefs::pan_sign_x(app);
let scroll = if app.viewport.wheel_zoom_raw_until_idle || (trackpad_pan && app.viewport.trackpad_until_idle) {
raw.zoom + if trackpad_pan { 0.0 } else { raw.point_zoom }
} else {
+25
View File
@@ -321,6 +321,8 @@ pub struct Prefs {
pub smooth_wheel_zoom: bool,
/// Two-finger trackpad scroll pans (off: it zooms like the wheel); pinch always zooms.
pub trackpad_pan: bool,
/// Horizontal trackpad and thumb-wheel scrolling pans the view the other way (#2007).
pub pan_reverse_x: bool,
/// View changes (axis view, Look At, Home) animate; `look_at_speed` scales how fast.
pub look_at_anim: bool,
pub look_at_speed: f32,
@@ -432,6 +434,7 @@ impl Default for Prefs {
zoom_to_cursor: true,
smooth_wheel_zoom: true,
trackpad_pan: true,
pan_reverse_x: false,
look_at_anim: true,
look_at_speed: 1.0,
up_axis: "z".into(),
@@ -626,6 +629,7 @@ fn defaults(app: &mut SolveApp, page: usize) {
p.zoom_to_cursor = d.zoom_to_cursor;
p.smooth_wheel_zoom = d.smooth_wheel_zoom;
p.trackpad_pan = d.trackpad_pan;
p.pan_reverse_x = d.pan_reverse_x;
p.orbit_around = d.orbit_around;
p.orbit_cursor = d.orbit_cursor;
p.space_mouse_enabled = d.space_mouse_enabled;
@@ -729,6 +733,11 @@ pub fn nav_mode(app: &SolveApp, button: NavButton, mods: Modifiers) -> Option<Na
nav_preset(&app.preferences.nav).mode(button, mods)
}
/// +1, or −1 when horizontal scrolling pans the other way (#2007).
pub fn pan_sign_x(app: &SolveApp) -> f32 {
if app.preferences.pan_reverse_x { -1.0 } else { 1.0 }
}
/// +1, or −1 when the wheel zooms the other way.
pub fn zoom_sign(app: &SolveApp) -> f64 {
if app.preferences.zoom_reverse { -1.0 } else { 1.0 }
@@ -1158,6 +1167,10 @@ fn page(app: &mut SolveApp, ui: &mut egui::Ui, t: &Tokens) {
crate::i18n::tr_label("Trackpad gestures pan (off: they zoom like the wheel); mouse wheel zooms, thumb wheel pans sideways, pinch always zooms")
});
ui.end_row();
ui.label(crate::i18n::tr_label("Reverse horizontal pan direction"));
ui.checkbox(&mut app.preferences.pan_reverse_x, "")
.on_hover_text(crate::i18n::tr_label("Horizontal two-finger scrolling and the thumb wheel pan the other way"));
ui.end_row();
ui.label(crate::i18n::tr_label("Orbit around"));
// Wrapped: three choices, and German or Russian labels are long.
ui.horizontal_wrapped(|ui| {
@@ -1838,6 +1851,18 @@ mod tests {
assert_eq!(other.preferences.nav, OPENSCAD_NAV);
}
#[test]
fn pan_reverse_x_defaults_off_persists_and_flips_the_sign() {
assert!(!serde_json::from_value::<Prefs>(json!({})).unwrap().pan_reverse_x);
let mut app = SolveApp::new(solidcraft_engine::Session::default(), Default::default());
assert_eq!(pan_sign_x(&app), 1.0);
set(&mut app, &json!({"pan_reverse_x": true})).unwrap();
assert_eq!(pan_sign_x(&app), -1.0);
let mut other = SolveApp::new(solidcraft_engine::Session::default(), Default::default());
other.load_prefs(&app.prefs());
assert!(other.preferences.pan_reverse_x);
}
#[test]
fn trackpad_pan_defaults_on_persists_and_follows_dialog_buttons() {
assert!(serde_json::from_value::<Prefs>(json!({})).unwrap().trackpad_pan);