Constrain minimum zoom level
This commit is contained in:
parent
6e2f38de56
commit
f34f9dd988
3 changed files with 51 additions and 2 deletions
|
|
@ -126,6 +126,10 @@ const SMALL_SCREEN_AREA: f64 = 1280. * 1024.;
|
|||
/// For small monitors occupy 80% of the screen area
|
||||
const SMALL_OCCUPY_SCREEN: f64 = 0.8;
|
||||
|
||||
/// The smallest edge of the image should not be rendered at a pixel size below
|
||||
/// this value, unless the image itself is smaller than this.
|
||||
const SMALLEST_RENDERED_PIXEL_SIZE: f64 = 16.0;
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy, glib::Variant, glib::Enum, PartialEq, Eq)]
|
||||
#[enum_type(name = "LpFitMode")]
|
||||
pub enum FitMode {
|
||||
|
|
@ -206,7 +210,10 @@ mod imp {
|
|||
/// 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
|
||||
/// Min zoom level is reached, stored to only send signals on change
|
||||
#[property(get, set)]
|
||||
pub(super) is_min_zoom: Cell<bool>,
|
||||
/// Analogous to is_min_zoom
|
||||
#[property(get, set)]
|
||||
pub(super) is_max_zoom: Cell<bool>,
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,27 @@ impl imp::LpImage {
|
|||
decoder::tiling::zoom_normalize(zoom) / self.scaling()
|
||||
}
|
||||
|
||||
/// Minimal zoom allowed for this image
|
||||
pub(super) fn min_zoom(&self) -> f64 {
|
||||
let (width, height) = self.untransformed_dimensions();
|
||||
|
||||
// If the image is smaller than the smallest rendered pixel size,
|
||||
// block zooming out entirely
|
||||
if (width as f64) < SMALLEST_RENDERED_PIXEL_SIZE
|
||||
|| (height as f64) < SMALLEST_RENDERED_PIXEL_SIZE
|
||||
{
|
||||
1.0
|
||||
}
|
||||
// Prevent the rendered size from going below SMALLEST_RENDERED_PIXEL_SIZE
|
||||
// Original size * zoom factor = rendered size
|
||||
// <=> Zoom factor = rendered size / original size
|
||||
else if width < height {
|
||||
SMALLEST_RENDERED_PIXEL_SIZE / (width as f64)
|
||||
} else {
|
||||
SMALLEST_RENDERED_PIXEL_SIZE / (height as f64)
|
||||
}
|
||||
}
|
||||
|
||||
/// Maximal zoom allowed for this image
|
||||
pub(super) fn max_zoom(&self) -> f64 {
|
||||
let obj = self.obj();
|
||||
|
|
@ -214,6 +235,15 @@ impl imp::LpImage {
|
|||
|
||||
tracing::trace!(zoom, animated, snap_best_fit, force_cursor_center, fit_mode=?obj.fit_mode(), "Zoom instruction");
|
||||
|
||||
let min_zoom = self.min_zoom();
|
||||
if zoom <= min_zoom {
|
||||
tracing::trace!(zoom, min_zoom, "Zoom reached minimum zoom level");
|
||||
zoom = min_zoom;
|
||||
obj.set_is_min_zoom(true);
|
||||
} else {
|
||||
obj.set_is_min_zoom(false);
|
||||
}
|
||||
|
||||
let max_zoom = self.max_zoom();
|
||||
if zoom >= max_zoom {
|
||||
tracing::trace!(zoom, max_zoom, "Zoom reached maximum zoom level");
|
||||
|
|
|
|||
|
|
@ -257,6 +257,18 @@ mod imp {
|
|||
),
|
||||
);
|
||||
|
||||
current_image_signals.connect_closure(
|
||||
"notify::is-min-zoom",
|
||||
false,
|
||||
glib::closure_local!(
|
||||
#[watch]
|
||||
obj,
|
||||
move |_: &LpImage, _: &glib::ParamSpec| {
|
||||
obj.update_image_actions_status();
|
||||
}
|
||||
),
|
||||
);
|
||||
|
||||
current_image_signals.connect_closure(
|
||||
"notify::is-max-zoom",
|
||||
false,
|
||||
|
|
@ -759,7 +771,7 @@ impl LpImageWindow {
|
|||
let can_zoom_out = self
|
||||
.image_view()
|
||||
.current_image()
|
||||
.is_some_and(|image| !image.is_best_fit());
|
||||
.is_some_and(|image| !image.is_best_fit() && !image.is_min_zoom());
|
||||
let can_zoom_in = self
|
||||
.image_view()
|
||||
.current_image()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue