mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-29 23:38:11 +08:00
Make the Path tool only allow selecting points that are visible (#2668)
* Fix only visible points selection in point selection * Fix comments * Remove bug from box selection and lasso * Code review * Fix comment --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
f6e592da5b
commit
b564579362
@@ -379,6 +379,7 @@ struct PathToolData {
|
||||
alt_dragging_from_anchor: bool,
|
||||
angle_locked: bool,
|
||||
temporary_colinear_handles: bool,
|
||||
frontier_handles_info: Option<HashMap<SegmentId, Vec<PointId>>>,
|
||||
adjacent_anchor_offset: Option<DVec2>,
|
||||
}
|
||||
|
||||
@@ -451,6 +452,7 @@ impl PathToolData {
|
||||
lasso_select: bool,
|
||||
handle_drag_from_anchor: bool,
|
||||
drag_zero_handle: bool,
|
||||
path_overlay_mode: PathOverlayMode,
|
||||
) -> PathToolFsmState {
|
||||
self.double_click_handled = false;
|
||||
self.opposing_handle_lengths = None;
|
||||
@@ -466,8 +468,14 @@ impl PathToolData {
|
||||
let old_selection = shape_editor.selected_points().cloned().collect::<Vec<_>>();
|
||||
|
||||
// Check if the point is already selected; if not, select the first point within the threshold (in pixels)
|
||||
if let Some((already_selected, mut selection_info)) = shape_editor.get_point_selection_state(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD) {
|
||||
log::info!("entered the part where tool identifies a near point");
|
||||
// Don't select the points which are not shown currently in PathOverlayMode
|
||||
if let Some((already_selected, mut selection_info)) = shape_editor.get_point_selection_state(
|
||||
&document.network_interface,
|
||||
input.mouse.position,
|
||||
SELECTION_THRESHOLD,
|
||||
path_overlay_mode,
|
||||
self.frontier_handles_info.clone(),
|
||||
) {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
|
||||
self.last_clicked_point_was_selected = already_selected;
|
||||
@@ -475,7 +483,14 @@ impl PathToolData {
|
||||
// If the point is already selected and shift (`extend_selection`) is used, keep the selection unchanged.
|
||||
// Otherwise, select the first point within the threshold.
|
||||
if !(already_selected && extend_selection) {
|
||||
if let Some(updated_selection_info) = shape_editor.change_point_selection(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD, extend_selection) {
|
||||
if let Some(updated_selection_info) = shape_editor.change_point_selection(
|
||||
&document.network_interface,
|
||||
input.mouse.position,
|
||||
SELECTION_THRESHOLD,
|
||||
extend_selection,
|
||||
path_overlay_mode,
|
||||
self.frontier_handles_info.clone(),
|
||||
) {
|
||||
selection_info = updated_selection_info;
|
||||
}
|
||||
}
|
||||
@@ -1055,14 +1070,16 @@ impl Fsm for PathToolFsmState {
|
||||
match tool_options.path_overlay_mode {
|
||||
PathOverlayMode::AllHandles => {
|
||||
path_overlays(document, DrawHandles::All, shape_editor, &mut overlay_context);
|
||||
tool_data.frontier_handles_info = None;
|
||||
}
|
||||
PathOverlayMode::SelectedPointHandles => {
|
||||
let selected_segments = selected_segments(document, shape_editor);
|
||||
let selected_segments = selected_segments(&document.network_interface, shape_editor);
|
||||
|
||||
path_overlays(document, DrawHandles::SelectedAnchors(selected_segments), shape_editor, &mut overlay_context);
|
||||
tool_data.frontier_handles_info = None;
|
||||
}
|
||||
PathOverlayMode::FrontierHandles => {
|
||||
let selected_segments = selected_segments(document, shape_editor);
|
||||
let selected_segments = selected_segments(&document.network_interface, shape_editor);
|
||||
let selected_points = shape_editor.selected_points();
|
||||
let selected_anchors = selected_points
|
||||
.filter_map(|point_id| if let ManipulatorPointId::Anchor(p) = point_id { Some(*p) } else { None })
|
||||
@@ -1090,13 +1107,18 @@ impl Fsm for PathToolFsmState {
|
||||
for (point, attached_segments) in selected_segments_by_point {
|
||||
if attached_segments.len() == 1 {
|
||||
segment_endpoints.entry(attached_segments[0]).or_default().push(point);
|
||||
} else if !selected_anchors.contains(&point) {
|
||||
}
|
||||
// Handle the edge case where a point, although not explicitly selected, is shared by two segments.
|
||||
else if !selected_anchors.contains(&point) {
|
||||
segment_endpoints.entry(attached_segments[0]).or_default().push(point);
|
||||
segment_endpoints.entry(attached_segments[1]).or_default().push(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Caching segment endpoints for use in point selection logic
|
||||
tool_data.frontier_handles_info = Some(segment_endpoints.clone());
|
||||
|
||||
// Now frontier anchors can be sent for rendering overlays
|
||||
path_overlays(document, DrawHandles::FrontierHandles(segment_endpoints), shape_editor, &mut overlay_context);
|
||||
}
|
||||
@@ -1198,7 +1220,17 @@ impl Fsm for PathToolFsmState {
|
||||
tool_data.selection_mode = None;
|
||||
tool_data.lasso_polygon.clear();
|
||||
|
||||
tool_data.mouse_down(shape_editor, document, input, responses, extend_selection, lasso_select, handle_drag_from_anchor, drag_zero_handle)
|
||||
tool_data.mouse_down(
|
||||
shape_editor,
|
||||
document,
|
||||
input,
|
||||
responses,
|
||||
extend_selection,
|
||||
lasso_select,
|
||||
handle_drag_from_anchor,
|
||||
drag_zero_handle,
|
||||
tool_options.path_overlay_mode,
|
||||
)
|
||||
}
|
||||
(
|
||||
PathToolFsmState::Drawing { selection_shape },
|
||||
@@ -1353,7 +1385,13 @@ impl Fsm for PathToolFsmState {
|
||||
|
||||
// If there is a point nearby, then remove the overlay
|
||||
if shape_editor
|
||||
.find_nearest_point_indices(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD)
|
||||
.find_nearest_visible_point_indices(
|
||||
&document.network_interface,
|
||||
input.mouse.position,
|
||||
SELECTION_THRESHOLD,
|
||||
tool_options.path_overlay_mode,
|
||||
tool_data.frontier_handles_info.clone(),
|
||||
)
|
||||
.is_some()
|
||||
{
|
||||
tool_data.segment = None;
|
||||
@@ -1447,9 +1485,21 @@ impl Fsm for PathToolFsmState {
|
||||
match selection_shape {
|
||||
SelectionShapeType::Box => {
|
||||
let bbox = [tool_data.drag_start_pos, previous_mouse];
|
||||
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), selection_change);
|
||||
shape_editor.select_all_in_shape(
|
||||
&document.network_interface,
|
||||
SelectionShape::Box(bbox),
|
||||
selection_change,
|
||||
tool_options.path_overlay_mode,
|
||||
tool_data.frontier_handles_info.clone(),
|
||||
);
|
||||
}
|
||||
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Lasso(&tool_data.lasso_polygon), selection_change),
|
||||
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(
|
||||
&document.network_interface,
|
||||
SelectionShape::Lasso(&tool_data.lasso_polygon),
|
||||
selection_change,
|
||||
tool_options.path_overlay_mode,
|
||||
tool_data.frontier_handles_info.clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1495,9 +1545,21 @@ impl Fsm for PathToolFsmState {
|
||||
match selection_shape {
|
||||
SelectionShapeType::Box => {
|
||||
let bbox = [tool_data.drag_start_pos, previous_mouse];
|
||||
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), select_kind);
|
||||
shape_editor.select_all_in_shape(
|
||||
&document.network_interface,
|
||||
SelectionShape::Box(bbox),
|
||||
select_kind,
|
||||
tool_options.path_overlay_mode,
|
||||
tool_data.frontier_handles_info.clone(),
|
||||
);
|
||||
}
|
||||
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Lasso(&tool_data.lasso_polygon), select_kind),
|
||||
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(
|
||||
&document.network_interface,
|
||||
SelectionShape::Lasso(&tool_data.lasso_polygon),
|
||||
select_kind,
|
||||
tool_options.path_overlay_mode,
|
||||
tool_data.frontier_handles_info.clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
@@ -1508,7 +1570,14 @@ impl Fsm for PathToolFsmState {
|
||||
(_, PathToolMessage::DragStop { extend_selection, .. }) => {
|
||||
let extend_selection = input.keyboard.get(extend_selection as usize);
|
||||
let drag_occurred = tool_data.drag_start_pos.distance(input.mouse.position) > DRAG_THRESHOLD;
|
||||
let nearest_point = shape_editor.find_nearest_point_indices(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD);
|
||||
// TODO: Here we want only visible points to be considered
|
||||
let nearest_point = shape_editor.find_nearest_visible_point_indices(
|
||||
&document.network_interface,
|
||||
input.mouse.position,
|
||||
SELECTION_THRESHOLD,
|
||||
tool_options.path_overlay_mode,
|
||||
tool_data.frontier_handles_info.clone(),
|
||||
);
|
||||
|
||||
if let Some((layer, nearest_point)) = nearest_point {
|
||||
if !drag_occurred && extend_selection {
|
||||
|
||||
Reference in New Issue
Block a user