Skip to content

Commit 463b11a

Browse files
committed
Fix zoom-out bounds when reaching fit-screen layout
1 parent cf9d295 commit 463b11a

1 file changed

Lines changed: 29 additions & 5 deletions

File tree

src/tui.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ struct PageConstraints {
7272
r_to_l: bool
7373
}
7474

75-
#[derive(Default, Debug)]
75+
#[derive(Default, Debug, Clone, Copy)]
7676
struct Zoom {
7777
// just how much 'zoom' you have. 0 means it fills the screen (instead of fits), such
7878
// that one axis is fully on-screen
@@ -86,7 +86,7 @@ struct Zoom {
8686
}
8787
impl Zoom {
8888
/// Returns the zoom factor, where 1 is the default and means fill-screen
89-
fn factor(&self) -> f32 {
89+
fn factor(self) -> f32 {
9090
// TODO: Make these configurable once we have a good way to set options after startup
9191
const ZOOM_RATE: f32 = 1.1;
9292
const ZOOM_RATE_GRANULAR: f32 = 1.05;
@@ -274,17 +274,41 @@ impl Tui {
274274
/ 2;
275275
};
276276

277-
// TODO: Detect max zoom-out in zoom levels
278277
if img_page_w_ratio < img_page_h_ratio {
279-
// vertical scroll / tall image. zooming out means decreasing the width of the page area
278+
// To detect if we're already at fit-screen, we perform a first
279+
// pass on `img_area` that emulates the last call to
280+
// `render_zoomed` by subtracting from the `zoom`'s level. This
281+
// holds because the `img_area` that gets passed is always the
282+
// same.
283+
let mut first_pass_area = img_area;
284+
let mut first_pass_zoom = *zoom;
285+
if first_pass_zoom.level.is_negative() {
286+
first_pass_zoom.step_in();
287+
}
288+
let first_pass_zoom_factor = first_pass_zoom.factor();
289+
shrink_move_page(
290+
&mut first_pass_area.width,
291+
&mut first_pass_area.x,
292+
first_pass_zoom_factor.max(1.0 / img_page_h_ratio)
293+
);
294+
log::debug!("first_pass_area: {first_pass_area:#?}");
295+
// vertical scroll / tall image. zooming out means decreasing
296+
// the width of the page area
280297
shrink_move_page(
281298
&mut img_area.width,
282299
&mut img_area.x,
283300
// disallow zooming out past fit-screen
284301
zoom_factor.max(1.0 / img_page_h_ratio)
285302
);
303+
log::debug!("img_area: {img_area:#?}");
304+
// The moment the image area is left unmodified, we've hit
305+
// fit-screen and the zoom level ought be normalized.
306+
if first_pass_area == img_area {
307+
zoom.step_in();
308+
}
286309
} else {
287-
// horizontal scroll / wide image. zooming out means decreasing the width of the page area
310+
// horizontal scroll / wide image. zooming out means decreasing
311+
// the height of the page area
288312
shrink_move_page(
289313
&mut img_area.height,
290314
&mut img_area.y,

0 commit comments

Comments
 (0)