Skip to content
Merged
Show file tree
Hide file tree
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
53 changes: 17 additions & 36 deletions editor/src/messages/tool/common_functionality/shape_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,20 +863,6 @@ impl ShapeState {
self.selected_shape_state.get(&layer).map(|state| &state.selected_segments)
}

pub fn move_primary(&self, segment: SegmentId, delta: DVec2, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>) {
responses.add(GraphOperationMessage::Vector {
layer,
modification_type: VectorModificationType::ApplyPrimaryDelta { segment, delta },
});
}

pub fn move_end(&self, segment: SegmentId, delta: DVec2, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>) {
responses.add(GraphOperationMessage::Vector {
layer,
modification_type: VectorModificationType::ApplyEndDelta { segment, delta },
});
}

pub fn move_anchor(&self, point: PointId, vector: &VectorGeometry, delta: DVec2, layer: LayerNodeIdentifier, selected: Option<&SelectedLayerState>, responses: &mut VecDeque<Message>) {
// Move anchor
responses.add(GraphOperationMessage::Vector {
Expand All @@ -894,7 +880,10 @@ impl ShapeState {
}

let relative_position = handle - point_to_dvec2(path_segment.start()) + delta;
let modification_type = VectorModificationType::SetPrimaryHandle { segment, relative_position };
let modification_type = VectorModificationType::SetHandlePosition {
handle: HandleId::primary(segment),
relative_position,
};

responses.add(GraphOperationMessage::Vector { layer, modification_type });
}
Expand All @@ -919,24 +908,20 @@ impl ShapeState {
let transform = network_interface.document_metadata().transform_to_document_if_feeds(layer, network_interface).inverse();
let position = transform.transform_point2(new_position);
let current_position = vector.position_of(*point)?;
let delta = position - current_position;

match *point {
ManipulatorPointId::Anchor(point) => self.move_anchor(point, &vector, delta, layer, None, responses),
ManipulatorPointId::PrimaryHandle(segment) => {
self.move_primary(segment, delta, layer, responses);
if let Some(handle) = point.as_handle()
&& let Some(handles) = vector.colinear_pair_containing(handle)
{
let modification_type = VectorModificationType::SetG1Continuous { handles, enabled: false };
responses.add(GraphOperationMessage::Vector { layer, modification_type });
}
}
ManipulatorPointId::EndHandle(segment) => {
self.move_end(segment, delta, layer, responses);
if let Some(handle) = point.as_handle()
&& let Some(handles) = vector.colinear_pair_containing(handle)
{
ManipulatorPointId::Anchor(anchor) => self.move_anchor(anchor, &vector, position - current_position, layer, None, responses),
ManipulatorPointId::PrimaryHandle(_) | ManipulatorPointId::EndHandle(_) => {
let handle = point.as_handle()?;

// Set by its offset from the anchor, since a delta has no stored offset to add onto until the Path node edits this handle
let relative_position = position - vector.anchor_position_of(*point)?;
responses.add(GraphOperationMessage::Vector {
layer,
modification_type: handle.set_relative_position(relative_position),
});

if let Some(handles) = vector.colinear_pair_containing(handle) {
let modification_type = VectorModificationType::SetG1Continuous { handles, enabled: false };
responses.add(GraphOperationMessage::Vector { layer, modification_type });
}
Expand Down Expand Up @@ -1587,11 +1572,7 @@ impl ShapeState {
responses.add(GraphOperationMessage::Vector { layer, modification_type });

// Update segment
let HandleId { ty, segment } = handle;
let modification_type = match ty {
graphene_std::vector::misc::HandleType::Primary => VectorModificationType::SetStartPoint { segment, id },
graphene_std::vector::misc::HandleType::End => VectorModificationType::SetEndPoint { segment, id },
};
let modification_type = VectorModificationType::SetEndpoint { handle, id };

responses.add(GraphOperationMessage::Vector { layer, modification_type });
}
Expand Down
32 changes: 32 additions & 0 deletions editor/src/messages/tool/tool_messages/path_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4113,4 +4113,36 @@ mod test_path_tool {

assert_eq!(pasted.colinear_pairs().len(), 2, "the pasted copy of the smooth anchor should be smooth too");
}

// The ellipse's handles come from its generator, so the first typed position is the Path node's first edit to the handle
#[tokio::test]
async fn a_typed_handle_position_moves_the_handle_there() {
let mut editor = EditorTestUtils::create();
editor.new_document().await;
editor.draw_ellipse(100., 100., 300., 200.).await;
let layer = editor.get_selected_layer().await.expect("the drawn ellipse should be selected");

let handle_in_document = |editor: &EditorTestUtils, handle: ManipulatorPointId| {
let document = editor.active_document();
let vector = document.network_interface.compute_modified_vector(layer).expect("the ellipse should have a vector");
let to_document = document.metadata().transform_to_document_if_feeds(layer, &document.network_interface);
to_document.transform_point2(vector.position_of(handle).expect("the handle should exist"))
};

let segment = {
let document = editor.active_document();
let vector = document.network_interface.compute_modified_vector(layer).expect("the ellipse should have a vector");
vector.segment_ids()[0]
};
let handle = ManipulatorPointId::PrimaryHandle(segment);
let before = handle_in_document(&editor, handle);

editor.select_tool(ToolType::Path).await;
editor.editor.dispatcher.message_handlers.tool_message_handler.shape_editor.select_point_by_layer_and_id(handle, layer);
editor.handle_message(PathToolMessage::SelectedPointUpdated).await;
editor.handle_message(PathToolMessage::SelectedPointXChanged { new_x: before.x + 5. }).await;

let after = handle_in_document(&editor, handle);
assert!(after.distance(before + DVec2::new(5., 0.)) < 1e-6, "the handle moved from {before} to {after}");
}
}
10 changes: 8 additions & 2 deletions editor/src/messages/tool/tool_messages/pen_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,18 @@ impl PenToolData {
}
TargetHandle::PriorInHandle(segment) => {
let relative_position = delta - anchor_pos;
let modification_type = VectorModificationType::SetEndHandle { segment, relative_position };
let modification_type = VectorModificationType::SetHandlePosition {
handle: HandleId::end(segment),
relative_position,
};
responses.add(GraphOperationMessage::Vector { layer, modification_type });
}
TargetHandle::PriorOutHandle(segment) => {
let relative_position = delta - anchor_pos;
let modification_type = VectorModificationType::SetPrimaryHandle { segment, relative_position };
let modification_type = VectorModificationType::SetHandlePosition {
handle: HandleId::primary(segment),
relative_position,
};
responses.add(GraphOperationMessage::Vector { layer, modification_type });
}
TargetHandle::None => {}
Expand Down
4 changes: 0 additions & 4 deletions node-graph/libraries/vector-types/src/vector/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,6 @@ impl WorkingVector {

vector.set_smooth_at_indices(paths, smooth_anchors, true);
}

pub fn resolve_id(&self, id: PointId) -> Option<usize> {
self.point_ids.iter().position(|&check_id| check_id == id)
}
}

// TODO: Eventually remove this document upgrade code
Expand Down
Loading
Loading