image/zoom: Allow 50% zoom via menu for 16px images

Zoom out for 16px or smaller images is usually blocked. But allow it for
zoom menu as we allow 50% via zoom menu in other situations where it is
blocked otherwise. Also, this is probably much less complex
implementation wise.

Closes #544
This commit is contained in:
Sophie Herold 2025-12-23 23:04:56 +01:00
parent f34f9dd988
commit 32a4d0f0aa
3 changed files with 17 additions and 8 deletions

View file

@ -0,0 +1 @@
Don't allow endless zoom out

View file

@ -130,6 +130,9 @@ const SMALL_OCCUPY_SCREEN: f64 = 0.8;
/// this value, unless the image itself is smaller than this.
const SMALLEST_RENDERED_PIXEL_SIZE: f64 = 16.0;
/// Smallest zoom level reachable via entries in the zoom menu
const LOWEST_MENU_ZOOM_LEVEL: f64 = 0.5;
#[derive(Default, Debug, Clone, Copy, glib::Variant, glib::Enum, PartialEq, Eq)]
#[enum_type(name = "LpFitMode")]
pub enum FitMode {

View file

@ -99,20 +99,25 @@ impl imp::LpImage {
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
let zoom_level = if (width as f64) < SMALLEST_RENDERED_PIXEL_SIZE
|| (height as f64) < SMALLEST_RENDERED_PIXEL_SIZE
{
// If the image is smaller than the smallest rendered pixel size,
// block zooming out entirely
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 {
} else if width < height {
// Prevent the rendered size from going below SMALLEST_RENDERED_PIXEL_SIZE
SMALLEST_RENDERED_PIXEL_SIZE / (width as f64)
} else {
SMALLEST_RENDERED_PIXEL_SIZE / (height as f64)
};
if matches!(self.obj().fit_mode(), FitMode::ExactVolatile) {
// Allow zoom menu to allways function. We are allowing this since disabling the
// zoom menu entries would probably be more complicated.
f64::min(zoom_level, LOWEST_MENU_ZOOM_LEVEL)
} else {
zoom_level
}
}