image/inputHandling: Stop kinetic after zoom

Stop kinetic scrolling after having used Ctrl + Touchpaad to zoom.

Closes #165
This commit is contained in:
Sophie Herold 2024-01-04 21:48:44 +01:00
parent b1d1d547cf
commit 0c53c75127

View file

@ -42,11 +42,18 @@ impl imp::LpImage {
// Zoom via scroll wheels etc // Zoom via scroll wheels etc
let scroll_controller = let scroll_controller =
gtk::EventControllerScroll::new(gtk::EventControllerScrollFlags::VERTICAL); gtk::EventControllerScroll::new(gtk::EventControllerScrollFlags::BOTH_AXES);
scroll_controller.connect_scroll_end(glib::clone!(@weak obj => move |event| {
// Avoid kinetc scrolling in scrolled window after zooming
if event.current_event_state().contains(gdk::ModifierType::CONTROL_MASK) {
obj.imp().cancel_deceleration();
}
}));
scroll_controller.connect_scroll(glib::clone!(@weak obj => @default-return glib::Propagation::Proceed, move |event, _, y| { scroll_controller.connect_scroll(glib::clone!(@weak obj => @default-return glib::Propagation::Proceed, move |event, _, y| {
let imp = obj.imp();
let state = event.current_event_state(); let state = event.current_event_state();
if event.current_event_device().map(|x| x.source()) == Some(gdk::InputSource::Touchpad) if event.current_event_device().map(|x| x.source()) == Some(gdk::InputSource::Touchpad)
{ {
// Touchpads do zoom via gestures, expect when Ctrl key is pressed // Touchpads do zoom via gestures, expect when Ctrl key is pressed
@ -80,12 +87,12 @@ impl imp::LpImage {
} }
}; };
let zoom = obj.imp().zoom_target.get() * zoom_factor; let zoom = imp.zoom_target.get() * zoom_factor;
if animated { if animated {
obj.zoom_to(zoom); obj.zoom_to(zoom);
} else { } else {
obj.imp().zoom_to_full(zoom, false, false, false); imp.zoom_to_full(zoom, false, false, false);
} }
// do not propagate event to scrolled window // do not propagate event to scrolled window
@ -130,6 +137,8 @@ impl imp::LpImage {
obj.add_controller(drag_gesture.clone()); obj.add_controller(drag_gesture.clone());
drag_gesture.connect_drag_begin(glib::clone!(@weak obj => move |gesture, _, _| { drag_gesture.connect_drag_begin(glib::clone!(@weak obj => move |gesture, _, _| {
let imp = obj.imp();
// Allow only left and middle button // Allow only left and middle button
if ![1, 2].contains(&gesture.current_button()) if ![1, 2].contains(&gesture.current_button())
// Drag gesture for touchscreens is handled by ScrolledWindow // Drag gesture for touchscreens is handled by ScrolledWindow
@ -140,9 +149,9 @@ impl imp::LpImage {
} }
if obj.is_hscrollable() || obj.is_vscrollable() { if obj.is_hscrollable() || obj.is_vscrollable() {
obj.cancel_deceleration(); imp.cancel_deceleration();
obj.set_cursor(gdk::Cursor::from_name("grabbing", None).as_ref()); obj.set_cursor(gdk::Cursor::from_name("grabbing", None).as_ref());
obj.imp().last_drag_value.set(Some((0., 0.))); imp.last_drag_value.set(Some((0., 0.)));
} else { } else {
// let drag and drop handle the events when not scrollable // let drag and drop handle the events when not scrollable
gesture.set_state(gtk::EventSequenceState::Denied); gesture.set_state(gtk::EventSequenceState::Denied);
@ -169,7 +178,7 @@ impl imp::LpImage {
obj.add_controller(rotation_gesture.clone()); obj.add_controller(rotation_gesture.clone());
rotation_gesture rotation_gesture
.connect_begin(glib::clone!(@weak obj => move |_,_|obj.cancel_deceleration())); .connect_begin(glib::clone!(@weak obj => move |_, _| obj.imp().cancel_deceleration()));
rotation_gesture.connect_angle_changed(glib::clone!(@weak obj => move |gesture, _, _| { rotation_gesture.connect_angle_changed(glib::clone!(@weak obj => move |gesture, _, _| {
let angle = gesture.angle_delta().to_degrees(); let angle = gesture.angle_delta().to_degrees();
@ -211,10 +220,9 @@ impl imp::LpImage {
obj.add_controller(zoom_gesture.clone()); obj.add_controller(zoom_gesture.clone());
zoom_gesture.connect_begin(glib::clone!(@weak obj => move |gesture, _| { zoom_gesture.connect_begin(glib::clone!(@weak obj => move |gesture, _| {
obj.cancel_deceleration(); let imp = obj.imp();
obj.imp() imp.cancel_deceleration();
.zoom_gesture_center imp.zoom_gesture_center.set(gesture.bounding_box_center());
.set(gesture.bounding_box_center());
})); }));
zoom_gesture.connect_scale_changed(glib::clone!(@weak obj => move |gesture, scale| { zoom_gesture.connect_scale_changed(glib::clone!(@weak obj => move |gesture, scale| {
@ -268,14 +276,13 @@ impl imp::LpImage {
zoom_gesture.group_with(&rotation_gesture); zoom_gesture.group_with(&rotation_gesture);
} }
}
impl LpImage {
/// Cancel kinetic scrolling movements, needed for some gestures /// Cancel kinetic scrolling movements, needed for some gestures
/// ///
/// If deceleration is not canceled gestures become buggy. /// If deceleration is not canceled gestures become buggy.
fn cancel_deceleration(&self) { fn cancel_deceleration(&self) {
if let Some(scrolled_window) = self if let Some(scrolled_window) = self
.obj()
.parent() .parent()
.and_then(|x| x.downcast::<gtk::ScrolledWindow>().ok()) .and_then(|x| x.downcast::<gtk::ScrolledWindow>().ok())
{ {