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
|
||||
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 {
|
||||
#[default]
|
||||
BestFit,
|
||||
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 {
|
||||
|
|
@ -199,6 +204,7 @@ mod imp {
|
|||
#[property(get, set)]
|
||||
pub(super) best_fit: Cell<bool>,
|
||||
/// Determines what `best-fit` does
|
||||
#[property(get, set=Self::set_fit_mode, builder(FitMode::default()))]
|
||||
pub(super) fit_mode: Cell<FitMode>,
|
||||
/// Max zoom level is reached, stored to only send signals on change
|
||||
#[property(get, set)]
|
||||
|
|
|
|||
|
|
@ -339,7 +339,9 @@ impl imp::LpImage {
|
|||
log::debug!("Zoom gesture end");
|
||||
|
||||
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));
|
||||
} else {
|
||||
// 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
|
||||
FitMode::BestFit => 1.,
|
||||
// Allow arbitrary zoom
|
||||
FitMode::LargeFit => f64::MAX,
|
||||
FitMode::LargeFit | FitMode::ExactVolatile => f64::MAX,
|
||||
};
|
||||
|
||||
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 max_deviation = minimum / ZOOM_FACTOR_MAX_RUBBERBAND;
|
||||
let deviation = zoom / minimum;
|
||||
|
|
@ -222,7 +222,14 @@ impl imp::LpImage {
|
|||
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();
|
||||
obj.set_best_fit(true);
|
||||
} else {
|
||||
|
|
@ -290,6 +297,13 @@ impl imp::LpImage {
|
|||
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 {
|
||||
|
|
@ -348,19 +362,19 @@ impl LpImage {
|
|||
self.imp().zoom_to_full(zoom, true, false, false);
|
||||
}
|
||||
|
||||
/// Same as `zoom_to_exact` but zoom to center
|
||||
pub fn zoom_to_exact_center(&self, zoom: f64) {
|
||||
pub fn zoom_to_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, 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);
|
||||
}
|
||||
|
||||
pub fn is_best_fit(&self) -> bool {
|
||||
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() {
|
||||
image.zoom_to_exact_center(value);
|
||||
image.zoom_to_center_no_best_fit(value);
|
||||
}
|
||||
|
||||
// Close popover after click
|
||||
|
|
@ -276,7 +276,7 @@ mod imp {
|
|||
move |_| {
|
||||
if let Some(page) = obj.current_page() {
|
||||
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