Skip to content

Commit 57de687

Browse files
Sidharth-Singh10Keavon
authored andcommittedMar 7, 2025
feat: flip canvas
1 parent c4cf477 commit 57de687

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed
 

‎editor/src/messages/portfolio/document/document_message_handler.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -2529,7 +2529,7 @@ impl<'a> ClickXRayIter<'a> {
25292529
}
25302530
}
25312531

2532-
pub fn navigation_controls(ptz: &PTZ, navigation_handler: &NavigationMessageHandler, tooltip_name: &str) -> [WidgetHolder; 5] {
2532+
pub fn navigation_controls(ptz: &PTZ, navigation_handler: &NavigationMessageHandler, tooltip_name: &str) -> [WidgetHolder; 7] {
25332533
[
25342534
IconButton::new("ZoomIn", 24)
25352535
.tooltip("Zoom In")
@@ -2547,6 +2547,11 @@ pub fn navigation_controls(ptz: &PTZ, navigation_handler: &NavigationMessageHand
25472547
.on_update(|_| NavigationMessage::CanvasTiltResetAndZoomTo100Percent.into())
25482548
.disabled(ptz.tilt().abs() < 1e-4 && (ptz.zoom() - 1.).abs() < 1e-4)
25492549
.widget_holder(),
2550+
CheckboxInput::new(navigation_handler.canvas_flipped)
2551+
.on_update(|_| NavigationMessage::FlipCanvas.into())
2552+
.tooltip("Flip Canvas Horizontally")
2553+
.widget_holder(),
2554+
TextLabel::new("Flip Canvas").widget_holder(),
25502555
// PopoverButton::new()
25512556
// .popover_layout(vec![
25522557
// LayoutGroup::Row {

‎editor/src/messages/portfolio/document/navigation/navigation_message.rs

+1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ pub enum NavigationMessage {
2626
FitViewportToBounds { bounds: [DVec2; 2], prevent_zoom_past_100: bool },
2727
FitViewportToSelection,
2828
PointerMove { snap: Key },
29+
FlipCanvas,
2930
}

‎editor/src/messages/portfolio/document/navigation/navigation_message_handler.rs

+32-1
Original file line numberDiff line numberDiff line change
@@ -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

3536
impl 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

Comments
 (0)