@@ -30,6 +30,7 @@ pub struct NavigationMessageHandler {
3030 mouse_position : ViewportPosition ,
3131 finish_operation_with_click : bool ,
3232 abortable_pan_start : Option < f64 > ,
33+ pub canvas_flipped : bool ,
3334}
3435
3536impl MessageHandler < NavigationMessage , NavigationMessageData < ' _ > > for NavigationMessageHandler {
@@ -459,6 +460,35 @@ impl MessageHandler<NavigationMessage, NavigationMessageData<'_>> for Navigation
459460
460461 self . mouse_position = ipp. mouse . position ;
461462 }
463+ NavigationMessage :: FlipCanvas => {
464+ let Some ( ptz) = get_ptz_mut ( document_ptz, network_interface, graph_view_overlay_open, breadcrumb_network_path) else {
465+ log:: error!( "Could not get mutable PTZ in FlipCanvas" ) ;
466+ return ;
467+ } ;
468+
469+ // Calculate document center point before flipping
470+ let document_to_viewport = self . calculate_offset_transform ( ipp. viewport_bounds . center ( ) , ptz) ;
471+ let viewport_center = ipp. viewport_bounds . center ( ) ;
472+ let document_center = document_to_viewport. inverse ( ) . transform_point2 ( viewport_center) ;
473+
474+ // Toggle the document-specific flip state
475+ self . canvas_flipped = !self . canvas_flipped ;
476+
477+ // Calculate the new document-to-viewport transform after flipping
478+ let new_document_to_viewport = self . calculate_offset_transform ( viewport_center, ptz) ;
479+
480+ // Calculate where the center point would be after flipping
481+ let new_document_center = new_document_to_viewport. inverse ( ) . transform_point2 ( viewport_center) ;
482+
483+ // Calculate the offset needed to keep the same center point
484+ let center_offset = document_center - new_document_center;
485+
486+ // Apply the offset to the pan to maintain the same view center
487+ ptz. pan -= center_offset;
488+
489+ responses. add ( DocumentMessage :: PTZUpdate ) ;
490+ responses. add ( BroadcastEvent :: CanvasTransformed ) ;
491+ }
462492 }
463493 }
464494
@@ -521,10 +551,11 @@ impl NavigationMessageHandler {
521551 // Try to avoid fractional coordinates to reduce anti aliasing.
522552 let scale = self . snapped_zoom ( zoom) ;
523553 let rounded_pan = ( ( pan + scaled_center) * scale) . round ( ) / scale - scaled_center;
554+ let scale_vec = if self . canvas_flipped { DVec2 :: new ( -scale, scale) } else { DVec2 :: splat ( scale) } ;
524555
525556 // TODO: replace with DAffine2::from_scale_angle_translation and fix the errors
526557 let offset_transform = DAffine2 :: from_translation ( scaled_center) ;
527- let scale_transform = DAffine2 :: from_scale ( DVec2 :: splat ( scale ) ) ;
558+ let scale_transform = DAffine2 :: from_scale ( scale_vec ) ;
528559 let angle_transform = DAffine2 :: from_angle ( self . snapped_tilt ( tilt) ) ;
529560 let translation_transform = DAffine2 :: from_translation ( rounded_pan) ;
530561 scale_transform * offset_transform * angle_transform * translation_transform
0 commit comments