From 47f8f8ffc4734d4b4747265dd7fe17da48dcf504 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Tue, 2 Feb 2010 01:06:14 +0000 Subject: [PATCH] Improved zoom-on-mouse: when changing zoom factor, the pixel under mouse cursor, either in normal or magnified view, stays 'stuck' under it, and both views re-center accordingly. Only limits are the scrolling constraints of Grafx2: The zoomed view must always be part of the non-zoomed view, it's not allowed to see above and left of picture limits, and it auto-scrolls left or top when you go near the right or bottom limit (show more pixels) git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1295 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- windows.c | 104 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 22 deletions(-) diff --git a/windows.c b/windows.c index 2ed2e673..a97c5f32 100644 --- a/windows.c +++ b/windows.c @@ -1655,8 +1655,7 @@ void Position_screen_according_to_zoom(void) -(Main_separator_position>>1); if (Main_offset_X<0) Main_offset_X=0; - else - if (Main_image_width>1); if (Main_offset_Y<0) Main_offset_Y=0; - else - if (Main_image_heightMain_separator_position) + { + Main_offset_X=target_x-Mouse_X; + // Do not allow the zoomed part to show something that the + // non-zoomed part doesn't see. All clipping is computed according + // to the non-zoomed part. + if (Main_magnifier_offset_X Main_offset_X+Main_separator_position) + Main_offset_X = Main_magnifier_offset_X+Main_magnifier_width-Main_separator_position; + if (Main_offset_X<0) + Main_offset_X=0; + else if (Main_image_widthMenu_Y) + { + Main_offset_Y=target_y-Mouse_Y; + // Do not allow the zoomed part to show something that the + // non-zoomed part doesn't see. All clipping is computed according + // to the non-zoomed part. + if (Main_magnifier_offset_Y Main_offset_Y) + Main_offset_Y = Main_magnifier_offset_Y+Main_magnifier_height; + if (Main_offset_Y<0) + Main_offset_Y=0; + else if (Main_image_height> 1); + target_y = Main_magnifier_offset_Y + (Main_magnifier_height >> 1); + } + else if (Mouse_X>=Main_X_zoom) + { + // Locate the pixel under the cursor, in magnified area + target_x=((Mouse_X-Main_X_zoom)/Main_magnifier_factor)+Main_magnifier_offset_X; + target_y=(Mouse_Y/Main_magnifier_factor)+Main_magnifier_offset_Y; + point_at_mouse=1; + } + else + { + // Locate the pixel under the cursor, in normal area + target_x=Mouse_X+Main_offset_X; + target_y=Mouse_Y+Main_offset_Y; + magnified_view_leads=0; } Main_magnifier_factor=ZOOM_FACTOR[factor_index]; @@ -1756,17 +1810,20 @@ void Change_magnifier_factor(byte factor_index) if (Main_magnifier_mode) { - // Recalculer le décalage de la loupe - // Centrage "brut" de lécran par rapport à la loupe - if (Cursor_in_menu) + // Recompute the magnifier offset (center its view) + if (point_at_mouse) { - Main_magnifier_offset_X=center_x-(Main_magnifier_width>>1); - Main_magnifier_offset_Y=center_y-(Main_magnifier_height>>1); - } else { - Main_magnifier_offset_X = Paintbrush_X - center_x * Main_magnifier_width ; - Main_magnifier_offset_Y = Paintbrush_Y - center_y * Main_magnifier_height ; + // Target pixel must be located under the mouse position. + Main_magnifier_offset_X = target_x-((Mouse_X-Main_X_zoom)/Main_magnifier_factor); + Main_magnifier_offset_Y = target_y-((Mouse_Y)/Main_magnifier_factor); } - // Correction en cas de débordement de l'image + else + { + // Target pixel must be positioned at new center + Main_magnifier_offset_X = target_x-(Main_magnifier_width>>1); + Main_magnifier_offset_Y = target_y-(Main_magnifier_height>>1); + } + // Fix cases where the image would overflow on edges if (Main_magnifier_offset_X+Main_magnifier_width>Main_image_width) Main_magnifier_offset_X=Main_image_width-Main_magnifier_width; if (Main_magnifier_offset_Y+Main_magnifier_height>Main_image_height) @@ -1776,7 +1833,10 @@ void Change_magnifier_factor(byte factor_index) if (Main_magnifier_offset_Y<0) Main_magnifier_offset_Y=0; - Position_screen_according_to_zoom(); + if (magnified_view_leads) + Position_screen_according_to_zoom(); + else + Position_screen_according_to_position(target_x, target_y); Pixel_preview=Pixel_preview_magnifier;