Add Path tool options for editing X/Y point coordinates (#1404)

* implement path point selector in toolbar

* Transform point to art board space

* fix handle adjustment space

* remove unused branches

* tidy comments

* make function names more descriptive, add guards, fix comments

* add auxillary message for layout update

* change trace to warn, remove unneccessary messages, fix rustfmt

* rustfmt

* support handles

* style and dimensions corrections

* Code review

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
mobile-bungalow
2023-08-29 21:41:01 -07:00
committed by GitHub
co-authored by Keavon Chambers
parent 5944186870
commit 48fdaddc37
2 changed files with 138 additions and 1 deletions
@@ -27,6 +27,9 @@ impl SelectedLayerState {
pub fn clear_points(&mut self) {
self.selected_points.clear();
}
pub fn selected_points_count(&self) -> usize {
self.selected_points.len()
}
}
pub type SelectedShapeState = HashMap<Vec<LayerId>, SelectedLayerState>;
#[derive(Debug, Default)]
@@ -148,6 +151,42 @@ impl ShapeState {
self.selected_shape_state.values().flat_map(|state| &state.selected_points)
}
/// Moves a control point to a `new_position` in document space.
/// Returns `Some(())` if successful and `None` otherwise.
pub fn reposition_control_point(&self, point: &ManipulatorPointId, responses: &mut VecDeque<Message>, document: &Document, new_position: DVec2, layer_path: &[u64]) -> Option<()> {
let layer = document.layer(layer_path).ok()?;
let vector_data = layer.as_vector_data()?;
let transform = layer.transform.inverse();
let position = transform.transform_point2(new_position - layer.pivot);
let group = vector_data.manipulator_from_id(point.group)?;
let delta = position - point.manipulator_type.get_position(group)?;
if point.manipulator_type.is_handle() {
responses.add(GraphOperationMessage::Vector {
layer: layer_path.to_vec(),
modification: VectorDataModification::SetManipulatorHandleMirroring { id: group.id, mirror_angle: false },
});
}
let mut move_point = |point: ManipulatorPointId| {
let Some(position) = point.manipulator_type.get_position(group) else {
return;
};
responses.add(GraphOperationMessage::Vector {
layer: layer_path.to_vec(),
modification: VectorDataModification::SetManipulatorPosition { point, position: (position + delta) },
});
};
move_point(*point);
if !point.manipulator_type.is_handle() {
move_point(ManipulatorPointId::new(point.group, SelectedType::InHandle));
move_point(ManipulatorPointId::new(point.group, SelectedType::OutHandle));
}
Some(())
}
/// Move the selected points by dragging the mouse.
pub fn move_selected_points(&self, document: &Document, delta: DVec2, mirror_distance: bool, responses: &mut VecDeque<Message>) {
for (layer_path, state) in &self.selected_shape_state {