image/zoom: Force zoom to center for buttons
Before, using buttons on touchscreen could zoom to the cursor position.
This commit is contained in:
parent
88099b1ec9
commit
b1d1d547cf
6 changed files with 94 additions and 46 deletions
|
|
@ -170,7 +170,7 @@ impl LpApplication {
|
||||||
);
|
);
|
||||||
self.set_accels_for_action("win.zoom-best-fit", &["0", "KP_0", "<Ctrl>0", "<Ctrl>KP_0"]);
|
self.set_accels_for_action("win.zoom-best-fit", &["0", "KP_0", "<Ctrl>0", "<Ctrl>KP_0"]);
|
||||||
self.set_accels_for_action(
|
self.set_accels_for_action(
|
||||||
"win.zoom-in",
|
"win.zoom-in-cursor",
|
||||||
&[
|
&[
|
||||||
"<Ctrl>plus",
|
"<Ctrl>plus",
|
||||||
"plus",
|
"plus",
|
||||||
|
|
@ -181,7 +181,7 @@ impl LpApplication {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
self.set_accels_for_action(
|
self.set_accels_for_action(
|
||||||
"win.zoom-out",
|
"win.zoom-out-cursor",
|
||||||
&["<Ctrl>minus", "minus", "<Ctrl>KP_Subtract", "KP_Subtract"],
|
&["<Ctrl>minus", "minus", "<Ctrl>KP_Subtract", "KP_Subtract"],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ impl imp::LpImage {
|
||||||
if animated {
|
if animated {
|
||||||
obj.zoom_to(zoom);
|
obj.zoom_to(zoom);
|
||||||
} else {
|
} else {
|
||||||
obj.imp().zoom_to_full(zoom, false, false);
|
obj.imp().zoom_to_full(zoom, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not propagate event to scrolled window
|
// do not propagate event to scrolled window
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,8 @@ impl imp::LpImage {
|
||||||
(x, y)
|
(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Required adjustment to put image coordinate under the cursor at this zoom level
|
/// Required adjustment to put image coordinate under the cursor at this
|
||||||
|
/// zoom level
|
||||||
fn adj_for_position(
|
fn adj_for_position(
|
||||||
&self,
|
&self,
|
||||||
(cur_x, cur_y): (f64, f64),
|
(cur_x, cur_y): (f64, f64),
|
||||||
|
|
@ -216,8 +217,14 @@ impl imp::LpImage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn zoom_to_full(&self, mut zoom: f64, animated: bool, snap_best_fit: bool) {
|
pub(super) fn zoom_to_full(
|
||||||
let obj = self.obj();
|
&self,
|
||||||
|
mut zoom: f64,
|
||||||
|
animated: bool,
|
||||||
|
snap_best_fit: bool,
|
||||||
|
force_cursor_center: bool,
|
||||||
|
) {
|
||||||
|
let obj = self.obj().to_owned();
|
||||||
|
|
||||||
let max_zoom = self.max_zoom();
|
let max_zoom = self.max_zoom();
|
||||||
if zoom >= max_zoom {
|
if zoom >= max_zoom {
|
||||||
|
|
@ -254,16 +261,26 @@ impl imp::LpImage {
|
||||||
}
|
}
|
||||||
|
|
||||||
if animated {
|
if animated {
|
||||||
let animation: &adw::TimedAnimation = self.zoom_animation();
|
let animation = self.zoom_animation();
|
||||||
|
|
||||||
// Set new point in image that should remain under the cursor while zooming if
|
if force_cursor_center {
|
||||||
// there isn't one already
|
animation.set_target(&adw::CallbackAnimationTarget::new(
|
||||||
if self.zoom_cursor_target.get().is_none() {
|
glib::clone!(@weak obj => move |zoom| {
|
||||||
let img_pos = self
|
obj.imp().set_zoom_aiming(zoom, None);
|
||||||
.pointer_position
|
}),
|
||||||
.get()
|
));
|
||||||
.map(|x| self.widget_to_img_coord(x));
|
} else {
|
||||||
self.zoom_cursor_target.set(img_pos);
|
// Set new point in image that should remain under the cursor while zooming if
|
||||||
|
// there isn't one already
|
||||||
|
if self.zoom_cursor_target.get().is_none() {
|
||||||
|
let img_pos = self
|
||||||
|
.pointer_position
|
||||||
|
.get()
|
||||||
|
.map(|x| self.widget_to_img_coord(x));
|
||||||
|
self.zoom_cursor_target.set(img_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.set_target(&adw::PropertyAnimationTarget::new(&obj, "zoom"));
|
||||||
}
|
}
|
||||||
|
|
||||||
animation.set_value_from(obj.zoom());
|
animation.set_value_from(obj.zoom());
|
||||||
|
|
@ -283,7 +300,6 @@ impl imp::LpImage {
|
||||||
let animation = adw::TimedAnimation::builder()
|
let animation = adw::TimedAnimation::builder()
|
||||||
.duration(ZOOM_ANIMATION_DURATION)
|
.duration(ZOOM_ANIMATION_DURATION)
|
||||||
.widget(&*obj)
|
.widget(&*obj)
|
||||||
.target(&adw::PropertyAnimationTarget::new(&*obj, "zoom"))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
animation.connect_done(glib::clone!(@weak obj => move |_| {
|
animation.connect_done(glib::clone!(@weak obj => move |_| {
|
||||||
|
|
@ -300,20 +316,38 @@ impl imp::LpImage {
|
||||||
impl LpImage {
|
impl LpImage {
|
||||||
/// Zoom in a step with animation
|
/// Zoom in a step with animation
|
||||||
///
|
///
|
||||||
/// Used by buttons
|
/// Used by keyboard shortcuts
|
||||||
pub fn zoom_in(&self) {
|
pub fn zoom_in_cursor(&self) {
|
||||||
let zoom = self.imp().zoom_target.get() * ZOOM_FACTOR_BUTTON;
|
let zoom = self.imp().zoom_target.get() * ZOOM_FACTOR_BUTTON;
|
||||||
|
|
||||||
self.zoom_to(zoom);
|
self.zoom_to(zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Zoom in a step with animation
|
||||||
|
///
|
||||||
|
/// Used by buttons
|
||||||
|
pub fn zoom_in_center(&self) {
|
||||||
|
let zoom = self.imp().zoom_target.get() * ZOOM_FACTOR_BUTTON;
|
||||||
|
|
||||||
|
self.imp().zoom_to_full(zoom, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Zoom out a step with animation
|
||||||
|
///
|
||||||
|
/// Used by keyboard shortcuts
|
||||||
|
pub fn zoom_out_cursor(&self) {
|
||||||
|
let zoom = self.imp().zoom_target.get() / ZOOM_FACTOR_BUTTON;
|
||||||
|
|
||||||
|
self.zoom_to(zoom);
|
||||||
|
}
|
||||||
|
|
||||||
/// Zoom out a step with animation
|
/// Zoom out a step with animation
|
||||||
///
|
///
|
||||||
/// Used by buttons
|
/// Used by buttons
|
||||||
pub fn zoom_out(&self) {
|
pub fn zoom_out_center(&self) {
|
||||||
let zoom = self.imp().zoom_target.get() / ZOOM_FACTOR_BUTTON;
|
let zoom = self.imp().zoom_target.get() / ZOOM_FACTOR_BUTTON;
|
||||||
|
|
||||||
self.zoom_to(zoom);
|
self.imp().zoom_to_full(zoom, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Zoom to best fit
|
/// Zoom to best fit
|
||||||
|
|
@ -325,14 +359,14 @@ impl LpImage {
|
||||||
|
|
||||||
/// Zoom to specific level with animation
|
/// Zoom to specific level with animation
|
||||||
pub fn zoom_to(&self, zoom: f64) {
|
pub fn zoom_to(&self, zoom: f64) {
|
||||||
self.imp().zoom_to_full(zoom, true, true);
|
self.imp().zoom_to_full(zoom, true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Zoom to specific level with animation not snapping to best-fit
|
/// Zoom to specific level with animation not snapping to best-fit
|
||||||
///
|
///
|
||||||
/// Used for zooming to 100% or 200%
|
/// Used for zooming to 100% or 200%
|
||||||
pub fn zoom_to_exact(&self, zoom: f64) {
|
pub fn zoom_to_exact(&self, zoom: f64) {
|
||||||
self.imp().zoom_to_full(zoom, true, false);
|
self.imp().zoom_to_full(zoom, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_best_fit(&self) -> bool {
|
pub fn is_best_fit(&self) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -632,18 +632,6 @@ impl LpImageView {
|
||||||
self.imp().fullscreen_button.set_icon_name(icon);
|
self.imp().fullscreen_button.set_icon_name(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zoom_out(&self) {
|
|
||||||
if let Some(current_page) = self.current_page() {
|
|
||||||
current_page.image().zoom_out();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn zoom_in(&self) {
|
|
||||||
if let Some(current_page) = self.current_page() {
|
|
||||||
current_page.image().zoom_in();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rotate_image(&self, angle: f64) {
|
pub fn rotate_image(&self, angle: f64) {
|
||||||
if let Some(current_page) = self.current_page() {
|
if let Some(current_page) = self.current_page() {
|
||||||
current_page.image().rotate_by(angle);
|
current_page.image().rotate_by(angle);
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="zoom_out">
|
<object class="GtkButton" id="zoom_out">
|
||||||
<property name="icon-name">zoom-out-symbolic</property>
|
<property name="icon-name">zoom-out-symbolic</property>
|
||||||
<property name="action-name">win.zoom-out</property>
|
<property name="action-name">win.zoom-out-center</property>
|
||||||
<property name="tooltip-text" translatable="yes">Zoom Out</property>
|
<property name="tooltip-text" translatable="yes">Zoom Out</property>
|
||||||
<style>
|
<style>
|
||||||
<class name="osd" />
|
<class name="osd" />
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="zoom_in">
|
<object class="GtkButton" id="zoom_in">
|
||||||
<property name="icon-name">zoom-in-symbolic</property>
|
<property name="icon-name">zoom-in-symbolic</property>
|
||||||
<property name="action-name">win.zoom-in</property>
|
<property name="action-name">win.zoom-in-center</property>
|
||||||
<property name="tooltip-text" translatable="yes">Zoom In</property>
|
<property name="tooltip-text" translatable="yes">Zoom In</property>
|
||||||
<style>
|
<style>
|
||||||
<class name="osd" />
|
<class name="osd" />
|
||||||
|
|
|
||||||
|
|
@ -180,12 +180,20 @@ mod imp {
|
||||||
win.imp().image_view.jump(Position::Last);
|
win.imp().image_view.jump(Position::Last);
|
||||||
});
|
});
|
||||||
|
|
||||||
klass.install_action("win.zoom-out", None, move |win, _, _| {
|
klass.install_action("win.zoom-out-cursor", None, move |win, _, _| {
|
||||||
win.zoom_out();
|
win.zoom_out_cursor();
|
||||||
});
|
});
|
||||||
|
|
||||||
klass.install_action("win.zoom-in", None, move |win, _, _| {
|
klass.install_action("win.zoom-out-center", None, move |win, _, _| {
|
||||||
win.zoom_in();
|
win.zoom_out_center();
|
||||||
|
});
|
||||||
|
|
||||||
|
klass.install_action("win.zoom-in-cursor", None, move |win, _, _| {
|
||||||
|
win.zoom_in_cursor();
|
||||||
|
});
|
||||||
|
|
||||||
|
klass.install_action("win.zoom-in-center", None, move |win, _, _| {
|
||||||
|
win.zoom_in_center();
|
||||||
});
|
});
|
||||||
|
|
||||||
klass.install_action("win.zoom-to-exact", Some("d"), move |win, _, level| {
|
klass.install_action("win.zoom-to-exact", Some("d"), move |win, _, level| {
|
||||||
|
|
@ -485,12 +493,28 @@ impl LpWindow {
|
||||||
self.set_fullscreened(fullscreen);
|
self.set_fullscreened(fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zoom_out(&self) {
|
fn zoom_out_cursor(&self) {
|
||||||
self.imp().image_view.zoom_out();
|
if let Some(image) = self.imp().image_view.current_image() {
|
||||||
|
image.zoom_out_cursor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zoom_in(&self) {
|
fn zoom_out_center(&self) {
|
||||||
self.imp().image_view.zoom_in();
|
if let Some(image) = self.imp().image_view.current_image() {
|
||||||
|
image.zoom_out_center();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zoom_in_cursor(&self) {
|
||||||
|
if let Some(image) = self.imp().image_view.current_image() {
|
||||||
|
image.zoom_in_cursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zoom_in_center(&self) {
|
||||||
|
if let Some(image) = self.imp().image_view.current_image() {
|
||||||
|
image.zoom_in_center();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zoom_to_exact(&self, level: f64) {
|
fn zoom_to_exact(&self, level: f64) {
|
||||||
|
|
@ -870,8 +894,10 @@ impl LpWindow {
|
||||||
.map(|image| !image.is_max_zoom())
|
.map(|image| !image.is_max_zoom())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
self.action_set_enabled("win.zoom-out", can_zoom_out);
|
self.action_set_enabled("win.zoom-out-cursor", can_zoom_out);
|
||||||
self.action_set_enabled("win.zoom-in", can_zoom_in);
|
self.action_set_enabled("win.zoom-out-center", can_zoom_out);
|
||||||
|
self.action_set_enabled("win.zoom-in-cursor", can_zoom_in);
|
||||||
|
self.action_set_enabled("win.zoom-in-center", can_zoom_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_fullscreen_changed(&self) {
|
fn on_fullscreen_changed(&self) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue