Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion editor/src/messages/tool/tool_messages/path_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2125,16 +2125,37 @@ impl Fsm for PathToolFsmState {
}

let break_molding = input.keyboard.get(break_colinear_molding as usize);
let lock_direction = input.keyboard.get(snap_angle as usize);

// Logic for molding segment
if let Some(segment) = &mut tool_data.segment
&& let Some(molding_segment_handles) = tool_data.molding_info
{
// While the lock direction modifier is held, constrain the drag to whichever screen axis it has travelled
// further along. The axis is stored in `snapping_axis` so the drag overlay draws the same X/Y guide lines
// through the grab point as it does when dragging points.
let mouse_position = match lock_direction {
true => {
let delta = input.mouse.position - tool_data.drag_start_pos;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Shift molding does not fully constrain the segment when click position differs from the curve's closest point: mold_handle_positions subtracts the Bezier grab point, but this projection uses cursor-down position. Project around segment.closest_point_to_viewport() (and use that same origin for the guide) so the constrained delta's perpendicular component is zero.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At editor/src/messages/tool/tool_messages/path_tool.rs, line 2139:

<comment>Shift molding does not fully constrain the segment when click position differs from the curve's closest point: `mold_handle_positions` subtracts the Bezier grab point, but this projection uses cursor-down position. Project around `segment.closest_point_to_viewport()` (and use that same origin for the guide) so the constrained delta's perpendicular component is zero.</comment>

<file context>
@@ -2131,13 +2131,32 @@ impl Fsm for PathToolFsmState {
+					// through the grab point as it does when dragging points.
+					let mouse_position = match lock_direction {
+						true => {
+							let delta = input.mouse.position - tool_data.drag_start_pos;
+							let axis = if delta.x.abs() >= delta.y.abs() { Axis::X } else { Axis::Y };
+							tool_data.snapping_axis = Some(axis);
</file context>

let axis = if delta.x.abs() >= delta.y.abs() { Axis::X } else { Axis::Y };
tool_data.snapping_axis = Some(axis);

match axis {
Axis::Y => DVec2::new(tool_data.drag_start_pos.x, input.mouse.position.y),
Axis::X | Axis::Both => DVec2::new(input.mouse.position.x, tool_data.drag_start_pos.y),
}
}
false => {
tool_data.snapping_axis = None;
input.mouse.position
}
};

tool_data.temporary_adjacent_handles_while_molding = segment.mold_handle_positions(
document,
responses,
molding_segment_handles,
input.mouse.position,
mouse_position,
break_molding,
tool_data.temporary_adjacent_handles_while_molding,
);
Expand Down Expand Up @@ -2389,6 +2410,7 @@ impl Fsm for PathToolFsmState {
tool_data.molding_segment = false;
tool_data.temporary_adjacent_handles_while_molding = None;
tool_data.angle_locked = false;
tool_data.snapping_axis = None;
responses.add(DocumentMessage::AbortTransaction);
tool_data.snap_manager.cleanup(responses);
PathToolFsmState::Ready
Expand Down Expand Up @@ -2511,6 +2533,7 @@ impl Fsm for PathToolFsmState {
tool_data.molding_info = None;
tool_data.molding_segment = false;
tool_data.temporary_adjacent_handles_while_molding = None;
tool_data.snapping_axis = None;

if segment_dissolved || point_inserted {
responses.add(DocumentMessage::EndTransaction);
Expand Down Expand Up @@ -3639,6 +3662,8 @@ fn update_dynamic_hints(

let mut molding_hints = vec![HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()])];

molding_hints.push(HintGroup(vec![HintInfo::keys([Key::Shift], "Lock Direction")]));

if molding_disable_possible {
molding_hints.push(HintGroup(vec![HintInfo::keys([Key::Alt], "Break Colinear Handles")]));
}
Expand Down