Fix scale transform being applied when drawing shapes while zoomed in (#2286)

* Nothing works a.k.a. init commit

* Everything works a.k.a. final commit

* Minor change

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Nitish Choudhary 2025-02-13 02:36:15 +05:30 committed by GitHub
parent 7bbbf7fa7c
commit 95bbc95606
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 31 additions and 31 deletions

View File

@ -47,36 +47,38 @@ impl Resize {
/// Compute the drag start and end based on the current mouse position. Ignores the state of the layer. /// Compute the drag start and end based on the current mouse position. Ignores the state of the layer.
/// If you want to only draw whilst a layer exists, use [`Resize::calculate_points`]. /// If you want to only draw whilst a layer exists, use [`Resize::calculate_points`].
pub fn calculate_points_ignore_layer(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key) -> [DVec2; 2] { pub fn calculate_points_ignore_layer(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key) -> [DVec2; 2] {
let start = self.viewport_drag_start(document); let start = self.drag_start;
let mouse = input.mouse.position; let mouse = input.mouse.position;
let document_to_viewport = document.navigation_handler.calculate_offset_transform(input.viewport_bounds.center(), &document.document_ptz); let document_to_viewport = document.navigation_handler.calculate_offset_transform(input.viewport_bounds.center(), &document.document_ptz);
let document_mouse = document_to_viewport.inverse().transform_point2(mouse); let document_mouse = document_to_viewport.inverse().transform_point2(mouse);
let mut points_viewport = [start, mouse]; let mut document_points = [start, document_mouse];
let ignore = if let Some(layer) = self.layer { vec![layer] } else { vec![] }; let ignore = if let Some(layer) = self.layer { vec![layer] } else { vec![] };
let ratio = input.keyboard.get(lock_ratio as usize); let ratio = input.keyboard.get(lock_ratio as usize);
let center = input.keyboard.get(center as usize); let center = input.keyboard.get(center as usize);
let snap_data = SnapData::ignore(document, input, &ignore); let snap_data = SnapData::ignore(document, input, &ignore);
let config = SnapTypeConfiguration::default(); let config = SnapTypeConfiguration::default();
if ratio { if ratio {
let size = points_viewport[1] - points_viewport[0]; let size = document_points[1] - document_points[0];
let size = size.abs().max(size.abs().yx()) * size.signum(); let size = size.abs().max(size.abs().yx()) * size.signum();
points_viewport[1] = points_viewport[0] + size; document_points[1] = document_points[0] + size;
let end_document = document_to_viewport.inverse().transform_point2(points_viewport[1]); let end = document_points[1];
let constraint = SnapConstraint::Line { let constraint = SnapConstraint::Line {
origin: self.drag_start, origin: self.drag_start,
direction: end_document - self.drag_start, direction: end - self.drag_start,
}; };
if center { if center {
let snapped = self.snap_manager.constrained_snap(&snap_data, &SnapCandidatePoint::handle(end_document), constraint, config); let snapped = self.snap_manager.constrained_snap(&snap_data, &SnapCandidatePoint::handle(end), constraint, config);
let far = SnapCandidatePoint::handle(2. * self.drag_start - end_document); let far = SnapCandidatePoint::handle(2. * self.drag_start - end);
let snapped_far = self.snap_manager.constrained_snap(&snap_data, &far, constraint, config); let snapped_far = self.snap_manager.constrained_snap(&snap_data, &far, constraint, config);
let best = if snapped_far.other_snap_better(&snapped) { snapped } else { snapped_far }; let best = if snapped_far.other_snap_better(&snapped) { snapped } else { snapped_far };
points_viewport[0] = document_to_viewport.transform_point2(best.snapped_point_document); document_points[0] = best.snapped_point_document;
points_viewport[1] = document_to_viewport.transform_point2(self.drag_start * 2. - best.snapped_point_document); document_points[1] = self.drag_start * 2. - best.snapped_point_document;
self.snap_manager.update_indicator(best); self.snap_manager.update_indicator(best);
} else { } else {
let snapped = self.snap_manager.constrained_snap(&snap_data, &SnapCandidatePoint::handle(end_document), constraint, config); let snapped = self.snap_manager.constrained_snap(&snap_data, &SnapCandidatePoint::handle(end), constraint, config);
points_viewport[1] = document_to_viewport.transform_point2(snapped.snapped_point_document); document_points[1] = snapped.snapped_point_document;
self.snap_manager.update_indicator(snapped); self.snap_manager.update_indicator(snapped);
} }
} else if center { } else if center {
@ -84,24 +86,28 @@ impl Resize {
let opposite = 2. * self.drag_start - document_mouse; let opposite = 2. * self.drag_start - document_mouse;
let snapped_far = self.snap_manager.free_snap(&snap_data, &SnapCandidatePoint::handle(opposite), config); let snapped_far = self.snap_manager.free_snap(&snap_data, &SnapCandidatePoint::handle(opposite), config);
let best = if snapped_far.other_snap_better(&snapped) { snapped } else { snapped_far }; let best = if snapped_far.other_snap_better(&snapped) { snapped } else { snapped_far };
points_viewport[0] = document_to_viewport.transform_point2(best.snapped_point_document); document_points[0] = best.snapped_point_document;
points_viewport[1] = document_to_viewport.transform_point2(self.drag_start * 2. - best.snapped_point_document); document_points[1] = self.drag_start * 2. - best.snapped_point_document;
self.snap_manager.update_indicator(best); self.snap_manager.update_indicator(best);
} else { } else {
let snapped = self.snap_manager.free_snap(&snap_data, &SnapCandidatePoint::handle(document_mouse), config); let snapped = self.snap_manager.free_snap(&snap_data, &SnapCandidatePoint::handle(document_mouse), config);
points_viewport[1] = document_to_viewport.transform_point2(snapped.snapped_point_document); document_points[1] = snapped.snapped_point_document;
self.snap_manager.update_indicator(snapped); self.snap_manager.update_indicator(snapped);
} }
points_viewport document_points
} }
pub fn calculate_transform(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key, skip_rerender: bool) -> Option<Message> { pub fn calculate_transform(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key, skip_rerender: bool) -> Option<Message> {
let points_viewport = self.calculate_points(document, input, center, lock_ratio)?; let viewport_points = self.calculate_points(document, input, center, lock_ratio).map(|points| {
let document_to_viewport = document.metadata().document_to_viewport;
[document_to_viewport.transform_point2(points[0]), document_to_viewport.transform_point2(points[1])]
})?;
Some( Some(
GraphOperationMessage::TransformSet { GraphOperationMessage::TransformSet {
layer: self.layer?, layer: self.layer?,
transform: DAffine2::from_scale_angle_translation(points_viewport[1] - points_viewport[0], 0., points_viewport[0]), transform: DAffine2::from_scale_angle_translation(viewport_points[1] - viewport_points[0], 0., viewport_points[0]),
transform_in: TransformIn::Viewport, transform_in: TransformIn::Viewport,
skip_rerender, skip_rerender,
} }

View File

@ -236,11 +236,9 @@ impl Fsm for EllipseToolFsmState {
responses.add(GraphOperationMessage::TransformSet { responses.add(GraphOperationMessage::TransformSet {
layer, layer,
transform: DAffine2::from_translation((start + end) / 2.), transform: DAffine2::from_translation((start + end) / 2.),
transform_in: TransformIn::Viewport, transform_in: TransformIn::Local,
skip_rerender: false, skip_rerender: false,
}); });
responses.add(NodeGraphMessage::RunDocumentGraph);
} }
} }

View File

@ -279,8 +279,7 @@ impl Fsm for PolygonToolFsmState {
(PolygonToolFsmState::Drawing, PolygonToolMessage::PointerMove { center, lock_ratio }) => { (PolygonToolFsmState::Drawing, PolygonToolMessage::PointerMove { center, lock_ratio }) => {
if let Some([start, end]) = tool_data.data.calculate_points(document, input, center, lock_ratio) { if let Some([start, end]) = tool_data.data.calculate_points(document, input, center, lock_ratio) {
if let Some(layer) = tool_data.data.layer { if let Some(layer) = tool_data.data.layer {
// TODO: make the scale impact the polygon/star node - we need to determine how to allow the polygon node to make irregular shapes // TODO: We need to determine how to allow the polygon node to make irregular shapes
update_radius_sign(end, start, layer, document, responses); update_radius_sign(end, start, layer, document, responses);
let dimensions = (start - end).abs(); let dimensions = (start - end).abs();
@ -326,11 +325,9 @@ impl Fsm for PolygonToolFsmState {
responses.add(GraphOperationMessage::TransformSet { responses.add(GraphOperationMessage::TransformSet {
layer, layer,
transform: DAffine2::from_scale_angle_translation(scale, 0., (start + end) / 2.), transform: DAffine2::from_scale_angle_translation(scale, 0., (start + end) / 2.),
transform_in: TransformIn::Viewport, transform_in: TransformIn::Local,
skip_rerender: false, skip_rerender: false,
}); });
responses.add(NodeGraphMessage::RunDocumentGraph);
} }
} }

View File

@ -224,7 +224,6 @@ impl Fsm for RectangleToolFsmState {
(RectangleToolFsmState::Drawing, RectangleToolMessage::PointerMove { center, lock_ratio }) => { (RectangleToolFsmState::Drawing, RectangleToolMessage::PointerMove { center, lock_ratio }) => {
if let Some([start, end]) = shape_data.calculate_points(document, input, center, lock_ratio) { if let Some([start, end]) = shape_data.calculate_points(document, input, center, lock_ratio) {
if let Some(layer) = shape_data.layer { if let Some(layer) = shape_data.layer {
// TODO: make the scale impact the rect node
let Some(node_id) = graph_modification_utils::get_rectangle_id(layer, &document.network_interface) else { let Some(node_id) = graph_modification_utils::get_rectangle_id(layer, &document.network_interface) else {
return self; return self;
}; };
@ -240,11 +239,9 @@ impl Fsm for RectangleToolFsmState {
responses.add(GraphOperationMessage::TransformSet { responses.add(GraphOperationMessage::TransformSet {
layer, layer,
transform: DAffine2::from_translation((start + end) / 2.), transform: DAffine2::from_translation((start + end) / 2.),
transform_in: TransformIn::Viewport, transform_in: TransformIn::Local,
skip_rerender: false, skip_rerender: false,
}); });
responses.add(NodeGraphMessage::RunDocumentGraph);
} }
} }

View File

@ -504,7 +504,9 @@ impl Fsm for TextToolFsmState {
TextToolFsmState::Placing TextToolFsmState::Placing
} }
(Self::Placing | TextToolFsmState::Dragging, TextToolMessage::PointerMove { center, lock_ratio }) => { (Self::Placing | TextToolFsmState::Dragging, TextToolMessage::PointerMove { center, lock_ratio }) => {
tool_data.cached_resize_bounds = tool_data.resize.calculate_points_ignore_layer(document, input, center, lock_ratio); let document_points = tool_data.resize.calculate_points_ignore_layer(document, input, center, lock_ratio);
let document_to_viewport = document.metadata().document_to_viewport;
tool_data.cached_resize_bounds = [document_to_viewport.transform_point2(document_points[0]), document_to_viewport.transform_point2(document_points[1])];
responses.add(OverlaysMessage::Draw); responses.add(OverlaysMessage::Draw);