image/zoom: Store pointer target through animation

Closes #48 #287
This commit is contained in:
Sophie Herold 2024-01-03 13:51:54 +01:00
parent a0e4791e6b
commit 56625f2309
2 changed files with 23 additions and 44 deletions

View file

@ -169,11 +169,7 @@ mod imp {
/// Targeted zoom level, might differ from `zoom` when animation is /// Targeted zoom level, might differ from `zoom` when animation is
/// running /// running
pub(super) zoom_target: Cell<f64>, pub(super) zoom_target: Cell<f64>,
/// Current animation is transitioning from having horizontal scrollbars pub(super) zoom_cursor_target: Cell<Option<(f64, f64)>>,
/// to not having them or vice versa.
pub(super) zoom_hscrollbar_transition: Cell<bool>,
/// Same but for vertical
pub(super) zoom_vscrollbar_transition: Cell<bool>,
/// Always fit image into window, causes `zoom` to change automatically /// Always fit image into window, causes `zoom` to change automatically
#[property(get, set)] #[property(get, set)]

View file

@ -178,32 +178,25 @@ impl imp::LpImage {
self.configure_adjustments(); self.configure_adjustments();
let center_x = self.widget_width() / 2.; let (h_adj, v_adj) = if let Some(adj) = self
let center_y = self.widget_height() / 2.; .zoom_cursor_target
.get()
let (x, y) = aiming.unwrap_or((center_x, center_y)); .and_then(|pos| self.adj_for_position(pos, zoom))
{
if self.zoom_hscrollbar_transition.get() { adj
if zoom_ratio < 1. {
self.set_hadj_value(self.max_hadjustment_value() / 2.);
} else {
// move towards center
self.set_hadj_value(self.hadjustment_corrected_for_zoom(zoom_ratio, center_x));
}
} else { } else {
self.set_hadj_value(self.hadjustment_corrected_for_zoom(zoom_ratio, x)); let center_x = self.widget_width() / 2.;
} let center_y = self.widget_height() / 2.;
let (x, y) = aiming.unwrap_or((center_x, center_y));
if self.zoom_vscrollbar_transition.get() { (
if zoom_ratio < 1. { self.hadjustment_corrected_for_zoom(zoom_ratio, x),
self.set_vadj_value(self.max_vadjustment_value() / 2.); self.vadjustment_corrected_for_zoom(zoom_ratio, y),
} else { )
// move towards center };
self.set_vadj_value(self.vadjustment_corrected_for_zoom(zoom_ratio, center_y));
} self.set_hadj_value(h_adj);
} else { self.set_vadj_value(v_adj);
self.set_vadj_value(self.vadjustment_corrected_for_zoom(zoom_ratio, y));
}
obj.notify_zoom(); obj.notify_zoom();
obj.queue_draw(); obj.queue_draw();
@ -257,20 +250,11 @@ impl imp::LpImage {
} }
if animated { if animated {
// wild code let animation: &adw::TimedAnimation = self.zoom_animation();
let current_hborder = self.widget_width() - self.image_displayed_width();
let target_hborder = self.widget_width() - obj.image_size().0 as f64 * zoom;
self.zoom_hscrollbar_transition if self.zoom_cursor_target.get().is_none() {
.set(current_hborder.signum() != target_hborder.signum() && current_hborder != 0.); self.zoom_cursor_target.set(self.cursor_position());
}
let current_vborder = self.widget_height() - self.image_displayed_height();
let target_vborder = self.widget_height() - obj.image_size().1 as f64 * zoom;
self.zoom_hscrollbar_transition
.set(current_vborder.signum() != target_vborder.signum() && current_vborder != 0.);
let animation = self.zoom_animation();
animation.set_value_from(obj.zoom()); animation.set_value_from(obj.zoom());
animation.set_value_to(zoom); animation.set_value_to(zoom);
@ -294,8 +278,7 @@ impl imp::LpImage {
animation.connect_done(glib::clone!(@weak obj => move |_| { animation.connect_done(glib::clone!(@weak obj => move |_| {
let imp = obj.imp(); let imp = obj.imp();
imp.zoom_hscrollbar_transition.set(false); imp.zoom_cursor_target.set(None);
imp.zoom_vscrollbar_transition.set(false);
imp.set_zoom_target(obj.imp().zoom_target.get()); imp.set_zoom_target(obj.imp().zoom_target.get());
})); }));