parent
c9e7f052e1
commit
e25b9aead6
4 changed files with 38 additions and 16 deletions
|
|
@ -124,11 +124,16 @@ const SMALL_SCREEN_AREA: f64 = 1280. * 1024.;
|
||||||
/// For small monitors occupy 80% of the screen area
|
/// For small monitors occupy 80% of the screen area
|
||||||
const SMALL_OCCUPY_SCREEN: f64 = 0.8;
|
const SMALL_OCCUPY_SCREEN: f64 = 0.8;
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Copy)]
|
#[derive(Default, Debug, Clone, Copy, glib::Variant, glib::Enum, PartialEq, Eq)]
|
||||||
|
#[enum_type(name = "LpFitMode")]
|
||||||
pub enum FitMode {
|
pub enum FitMode {
|
||||||
#[default]
|
#[default]
|
||||||
BestFit,
|
BestFit,
|
||||||
LargeFit,
|
LargeFit,
|
||||||
|
/// Allow zoom to be set smaller than best fit. Allow arbitrary zoom
|
||||||
|
/// operations until zoom is larger than best-fit, which resets to `BestFit`
|
||||||
|
/// mode.`
|
||||||
|
ExactVolatile,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
|
|
@ -199,6 +204,7 @@ mod imp {
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
pub(super) best_fit: Cell<bool>,
|
pub(super) best_fit: Cell<bool>,
|
||||||
/// Determines what `best-fit` does
|
/// Determines what `best-fit` does
|
||||||
|
#[property(get, set=Self::set_fit_mode, builder(FitMode::default()))]
|
||||||
pub(super) fit_mode: Cell<FitMode>,
|
pub(super) fit_mode: Cell<FitMode>,
|
||||||
/// Max zoom level is reached, stored to only send signals on change
|
/// Max zoom level is reached, stored to only send signals on change
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,9 @@ impl imp::LpImage {
|
||||||
log::debug!("Zoom gesture end");
|
log::debug!("Zoom gesture end");
|
||||||
|
|
||||||
let rotation_target = (obj.rotation() / 90.).round() * 90.;
|
let rotation_target = (obj.rotation() / 90.).round() * 90.;
|
||||||
if obj.zoom() < imp.zoom_level_best_fit_for_rotation(rotation_target) {
|
if obj.zoom() < imp.zoom_level_best_fit_for_rotation(rotation_target)
|
||||||
|
&& obj.fit_mode() != FitMode::ExactVolatile
|
||||||
|
{
|
||||||
obj.zoom_to(imp.zoom_level_best_fit_for_rotation(rotation_target));
|
obj.zoom_to(imp.zoom_level_best_fit_for_rotation(rotation_target));
|
||||||
} else {
|
} else {
|
||||||
// rubberband if over highest zoom level and sets `zoom_target`
|
// rubberband if over highest zoom level and sets `zoom_target`
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ impl imp::LpImage {
|
||||||
// Do not allow to zoom larger than original size
|
// Do not allow to zoom larger than original size
|
||||||
FitMode::BestFit => 1.,
|
FitMode::BestFit => 1.,
|
||||||
// Allow arbitrary zoom
|
// Allow arbitrary zoom
|
||||||
FitMode::LargeFit => f64::MAX,
|
FitMode::LargeFit | FitMode::ExactVolatile => f64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let default_zoom = if texture_aspect_ratio > widget_aspect_ratio {
|
let default_zoom = if texture_aspect_ratio > widget_aspect_ratio {
|
||||||
|
|
@ -138,7 +138,7 @@ impl imp::LpImage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if zoom < self.zoom_level_best_fit() {
|
if zoom < self.zoom_level_best_fit() && obj.fit_mode() == FitMode::BestFit {
|
||||||
let minimum = self.zoom_level_best_fit();
|
let minimum = self.zoom_level_best_fit();
|
||||||
let max_deviation = minimum / ZOOM_FACTOR_MAX_RUBBERBAND;
|
let max_deviation = minimum / ZOOM_FACTOR_MAX_RUBBERBAND;
|
||||||
let deviation = zoom / minimum;
|
let deviation = zoom / minimum;
|
||||||
|
|
@ -222,7 +222,14 @@ impl imp::LpImage {
|
||||||
self.zoom_level_best_fit()
|
self.zoom_level_best_fit()
|
||||||
};
|
};
|
||||||
|
|
||||||
if zoom <= extended_best_fit_threshold {
|
// Reset fit mode if entering in the usual zoom levels again
|
||||||
|
if obj.fit_mode() == FitMode::ExactVolatile
|
||||||
|
&& zoom >= f64::min(1.0, self.zoom_level_best_fit())
|
||||||
|
{
|
||||||
|
obj.set_fit_mode(FitMode::BestFit)
|
||||||
|
}
|
||||||
|
|
||||||
|
if zoom <= extended_best_fit_threshold && obj.fit_mode() != FitMode::ExactVolatile {
|
||||||
zoom = self.zoom_level_best_fit();
|
zoom = self.zoom_level_best_fit();
|
||||||
obj.set_best_fit(true);
|
obj.set_best_fit(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -290,6 +297,13 @@ impl imp::LpImage {
|
||||||
animation
|
animation
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_fit_mode(&self, fit_mode: FitMode) {
|
||||||
|
self.fit_mode.replace(fit_mode);
|
||||||
|
if fit_mode != FitMode::ExactVolatile {
|
||||||
|
self.configure_best_fit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LpImage {
|
impl LpImage {
|
||||||
|
|
@ -348,19 +362,19 @@ impl LpImage {
|
||||||
self.imp().zoom_to_full(zoom, true, false, false);
|
self.imp().zoom_to_full(zoom, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `zoom_to_exact` but zoom to center
|
pub fn zoom_to_no_best_fit(&self, zoom: f64) {
|
||||||
pub fn zoom_to_exact_center(&self, zoom: f64) {
|
self.set_fit_mode(FitMode::ExactVolatile);
|
||||||
|
self.set_best_fit(false);
|
||||||
|
self.imp().zoom_to_full(zoom, true, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn zoom_to_center_no_best_fit(&self, zoom: f64) {
|
||||||
|
self.set_fit_mode(FitMode::ExactVolatile);
|
||||||
|
self.set_best_fit(false);
|
||||||
self.imp().zoom_to_full(zoom, true, false, true);
|
self.imp().zoom_to_full(zoom, true, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_best_fit(&self) -> bool {
|
pub fn is_best_fit(&self) -> bool {
|
||||||
self.imp().best_fit.get()
|
self.imp().best_fit.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_fit_mode(&self, fit_mode: FitMode) {
|
|
||||||
let imp = self.imp();
|
|
||||||
|
|
||||||
imp.fit_mode.replace(fit_mode);
|
|
||||||
imp.configure_best_fit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ mod imp {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(image) = obj.current_image() {
|
if let Some(image) = obj.current_image() {
|
||||||
image.zoom_to_exact_center(value);
|
image.zoom_to_center_no_best_fit(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close popover after click
|
// Close popover after click
|
||||||
|
|
@ -276,7 +276,7 @@ mod imp {
|
||||||
move |_| {
|
move |_| {
|
||||||
if let Some(page) = obj.current_page() {
|
if let Some(page) = obj.current_page() {
|
||||||
if let Some(value) = obj.zoom_value_f64() {
|
if let Some(value) = obj.zoom_value_f64() {
|
||||||
page.image().zoom_to_exact(value);
|
page.image().zoom_to_no_best_fit(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue