From 21de86b3df5ab413447cb0cb53b1ed45349edbe6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Oct 2026 17:29:00 +0000 Subject: [PATCH] UI: the loupe follows a texture's aspect only when it really differs (#280) A texture's whole-pixel size is slightly off the frame's exact aspect (a 128 px thumbnail by up to ~1 %), so following it always made the loupe rect jump a little as the thumbnail, preview and full render arrived, and moved mask and crop overlays with it. Follow it only when it differs by more than 2 % (an unsupported raw's embedded JPEG with another crop), and never in the crop tool, whose overlays need the frame's own geometry. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01912WaK6Rmew3wxZuPyX7E8 --- crates/ui-egui/src/panels/detail.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/panels/detail.rs b/crates/ui-egui/src/panels/detail.rs index f68168375..8ee7bfbf1 100644 --- a/crates/ui-egui/src/panels/detail.rs +++ b/crates/ui-egui/src/panels/detail.rs @@ -207,7 +207,10 @@ pub fn show(app: &mut LightcraftApp, ui: &mut egui::Ui) { .or_else(|| app.renderer.textures.get(&Slot::Preview).filter(|t| t.photo == id)) .or_else(|| app.renderer.thumb(id)) .map(|tex| tex.size[0].max(1) as f32 / tex.size[1].max(1) as f32); - let display_aspect = visible_texture_aspect.unwrap_or(aspect); + // Follow the texture only where it really differs (an unsupported raw's embedded JPEG with + // another crop): a texture's whole-pixel size is a little off the exact aspect, and the crop + // tool's overlays need the frame's own geometry. + let display_aspect = visible_texture_aspect.filter(|a| !crop_tool && (a / aspect - 1.0).abs() > 0.02).unwrap_or(aspect); let target_rect = fit_rect(main_area, display_aspect, app.ui.zoom, native, ppp, app.ui.pan); let img_rect = animated_rect(ui.ctx(), &mut app.ui.zoom_anim, target_rect); app.image_rect = Some(img_rect);