mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 11:48:12 +08:00
Add segment editing mode to the Path tool (#2712)
* Segment select mode upto dragging * Lasso select for segment editing * Formatting * Compatibility with point selection mode * Add delete segment support and drawing from inside of shape * Add GRS support for selected segments * Cleanup and add dynamic hints * Fix double click behaviour and overlays * Format code * Fix merge * Fix Lint * Fix formatting * Fix lasso bug * Code review --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
a4fbea9193
commit
391ed34a30
@@ -124,8 +124,19 @@ pub fn path_overlays(document: &DocumentMessageHandler, draw_handles: DrawHandle
|
||||
overlay_context.outline_vector(&vector_data, transform);
|
||||
}
|
||||
|
||||
// Get the selected segments and then add a bold line overlay on them
|
||||
for (segment_id, bezier, _, _) in vector_data.segment_bezier_iter() {
|
||||
let Some(selected_shape_state) = shape_editor.selected_shape_state.get_mut(&layer) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if selected_shape_state.is_segment_selected(segment_id) {
|
||||
overlay_context.outline_select_bezier(bezier, transform);
|
||||
}
|
||||
}
|
||||
|
||||
let selected = shape_editor.selected_shape_state.get(&layer);
|
||||
let is_selected = |point: ManipulatorPointId| selected.is_some_and(|selected| selected.is_selected(point));
|
||||
let is_selected = |point: ManipulatorPointId| selected.is_some_and(|selected| selected.is_point_selected(point));
|
||||
|
||||
if display_handles {
|
||||
let opposite_handles_data: Vec<(PointId, SegmentId)> = shape_editor.selected_points().filter_map(|point_id| vector_data.adjacent_segment(point_id)).collect();
|
||||
@@ -187,7 +198,7 @@ pub fn path_endpoint_overlays(document: &DocumentMessageHandler, shape_editor: &
|
||||
//let document_to_viewport = document.navigation_handler.calculate_offset_transform(overlay_context.size / 2., &document.document_ptz);
|
||||
let transform = document.metadata().transform_to_viewport(layer);
|
||||
let selected = shape_editor.selected_shape_state.get(&layer);
|
||||
let is_selected = |selected: Option<&SelectedLayerState>, point: ManipulatorPointId| selected.is_some_and(|selected| selected.is_selected(point));
|
||||
let is_selected = |selected: Option<&SelectedLayerState>, point: ManipulatorPointId| selected.is_some_and(|selected| selected.is_point_selected(point));
|
||||
|
||||
for point in vector_data.extendable_points(preferences.vector_meshes) {
|
||||
let Some(position) = vector_data.point_domain.position_from_id(point) else { continue };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::utility_functions::overlay_canvas_context;
|
||||
use crate::consts::{
|
||||
COLOR_OVERLAY_BLUE, COLOR_OVERLAY_GREEN, COLOR_OVERLAY_RED, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, COMPASS_ROSE_ARROW_SIZE, COMPASS_ROSE_HOVER_RING_DIAMETER, COMPASS_ROSE_MAIN_RING_DIAMETER,
|
||||
COMPASS_ROSE_RING_INNER_DIAMETER, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
|
||||
COLOR_OVERLAY_BLUE, COLOR_OVERLAY_BLUE_50, COLOR_OVERLAY_GREEN, COLOR_OVERLAY_RED, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, COMPASS_ROSE_ARROW_SIZE, COMPASS_ROSE_HOVER_RING_DIAMETER,
|
||||
COMPASS_ROSE_MAIN_RING_DIAMETER, COMPASS_ROSE_RING_INNER_DIAMETER, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
|
||||
};
|
||||
use crate::messages::prelude::Message;
|
||||
use bezier_rs::{Bezier, Subpath};
|
||||
@@ -581,6 +581,35 @@ impl OverlayContext {
|
||||
self.end_dpi_aware_transform();
|
||||
}
|
||||
|
||||
/// Used by the path tool segment mode in order to show the selected segments.
|
||||
pub fn outline_select_bezier(&mut self, bezier: Bezier, transform: DAffine2) {
|
||||
self.start_dpi_aware_transform();
|
||||
|
||||
self.render_context.begin_path();
|
||||
self.bezier_command(bezier, transform, true);
|
||||
self.render_context.set_stroke_style_str(COLOR_OVERLAY_BLUE);
|
||||
self.render_context.set_line_width(4.);
|
||||
self.render_context.stroke();
|
||||
|
||||
self.render_context.set_line_width(1.);
|
||||
|
||||
self.end_dpi_aware_transform();
|
||||
}
|
||||
|
||||
pub fn outline_overlay_bezier(&mut self, bezier: Bezier, transform: DAffine2) {
|
||||
self.start_dpi_aware_transform();
|
||||
|
||||
self.render_context.begin_path();
|
||||
self.bezier_command(bezier, transform, true);
|
||||
self.render_context.set_stroke_style_str(COLOR_OVERLAY_BLUE_50);
|
||||
self.render_context.set_line_width(4.);
|
||||
self.render_context.stroke();
|
||||
|
||||
self.render_context.set_line_width(1.);
|
||||
|
||||
self.end_dpi_aware_transform();
|
||||
}
|
||||
|
||||
fn bezier_command(&self, bezier: Bezier, transform: DAffine2, move_to: bool) {
|
||||
self.start_dpi_aware_transform();
|
||||
|
||||
|
||||
@@ -88,6 +88,18 @@ impl OriginalTransforms {
|
||||
let Some(selected_points) = shape_editor.selected_points_in_layer(layer) else {
|
||||
continue;
|
||||
};
|
||||
let Some(selected_segments) = shape_editor.selected_segments_in_layer(layer) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut selected_points = selected_points.clone();
|
||||
|
||||
for (segment_id, _, start, end) in vector_data.segment_bezier_iter() {
|
||||
if selected_segments.contains(&segment_id) {
|
||||
selected_points.insert(ManipulatorPointId::Anchor(start));
|
||||
selected_points.insert(ManipulatorPointId::Anchor(end));
|
||||
}
|
||||
}
|
||||
|
||||
// Anchors also move their handles
|
||||
let anchor_ids = selected_points.iter().filter_map(|point| point.as_anchor());
|
||||
|
||||
Reference in New Issue
Block a user