Skip to content

Commit 59ac1cd

Browse files
committed
Fix deselecting user selection when anchors are disabled
1 parent b7fb453 commit 59ac1cd

File tree

3 files changed

+65
-10
lines changed

3 files changed

+65
-10
lines changed

editor/src/messages/tool/common_functionality/shape_editor.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub enum ManipulatorAngle {
4242
#[derive(Clone, Debug, Default)]
4343
pub struct SelectedLayerState {
4444
selected_points: HashSet<ManipulatorPointId>,
45+
ignore_handles: bool,
46+
ignore_anchors: bool,
4547
}
4648

4749
impl SelectedLayerState {
@@ -52,11 +54,23 @@ impl SelectedLayerState {
5254
self.selected_points.contains(&point)
5355
}
5456
pub fn select_point(&mut self, point: ManipulatorPointId) {
57+
if (point.as_handle().is_some() && self.ignore_handles) || (point.as_anchor().is_some() && self.ignore_anchors) {
58+
return;
59+
}
5560
self.selected_points.insert(point);
5661
}
5762
pub fn deselect_point(&mut self, point: ManipulatorPointId) {
63+
if (point.as_handle().is_some() && self.ignore_handles) || (point.as_anchor().is_some() && self.ignore_anchors) {
64+
return;
65+
}
5866
self.selected_points.remove(&point);
5967
}
68+
pub fn set_handles_status(&mut self, ignore: bool) {
69+
self.ignore_handles = ignore;
70+
}
71+
pub fn set_anchors_status(&mut self, ignore: bool) {
72+
self.ignore_anchors = ignore;
73+
}
6074
pub fn clear_points(&mut self) {
6175
self.selected_points.clear();
6276
}
@@ -496,13 +510,37 @@ impl ShapeState {
496510
}
497511
}
498512

513+
pub fn mark_selected_anchors(&mut self) {
514+
for state in self.selected_shape_state.values_mut() {
515+
state.set_anchors_status(false);
516+
}
517+
}
518+
519+
pub fn mark_selected_handles(&mut self) {
520+
for state in self.selected_shape_state.values_mut() {
521+
state.set_handles_status(false);
522+
}
523+
}
524+
525+
pub fn ignore_selected_anchors(&mut self) {
526+
for state in self.selected_shape_state.values_mut() {
527+
state.set_anchors_status(true);
528+
}
529+
}
530+
531+
pub fn ignore_selected_handles(&mut self) {
532+
for state in self.selected_shape_state.values_mut() {
533+
state.set_handles_status(true);
534+
}
535+
}
536+
499537
/// Deselects all the anchors across every selected layer.
500538
pub fn deselect_all_anchors(&mut self) {
501539
for (_, state) in self.selected_shape_state.iter_mut() {
502540
let selected_anchor_points: Vec<ManipulatorPointId> = state
503541
.selected_points
504542
.iter()
505-
.filter(|selected_point| matches!(selected_point, ManipulatorPointId::Anchor(_)))
543+
.filter(|selected_point| selected_point.as_anchor().is_some())
506544
.cloned()
507545
.collect();
508546

@@ -518,7 +556,7 @@ impl ShapeState {
518556
let selected_handle_points: Vec<ManipulatorPointId> = state
519557
.selected_points
520558
.iter()
521-
.filter(|selected_point| matches!(selected_point, ManipulatorPointId::PrimaryHandle(_) | ManipulatorPointId::EndHandle(_)))
559+
.filter(|selected_point| selected_point.as_handle().is_some())
522560
.cloned()
523561
.collect();
524562

@@ -636,7 +674,7 @@ impl ShapeState {
636674
Some(())
637675
}
638676

639-
/// Iterates over the selected manipulator groups exluding endpoints, returning whether their handles have mixed, colinear, or free angles.
677+
/// Iterates over the selected manipulator groups excluding endpoints, returning whether their handles have mixed, colinear, or free angles.
640678
/// If there are no points selected this function returns mixed.
641679
pub fn selected_manipulator_angles(&self, network_interface: &NodeNetworkInterface) -> ManipulatorAngle {
642680
// This iterator contains a bool indicating whether or not selected points' manipulator groups have colinear handles.

editor/src/messages/tool/tool_messages/path_tool.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,10 +1015,16 @@ impl Fsm for PathToolFsmState {
10151015
let display_anchors = overlay_context.visibility_settings.anchors();
10161016
let display_handles = overlay_context.visibility_settings.handles();
10171017
if !display_handles {
1018-
shape_editor.deselect_all_handles();
1018+
shape_editor.ignore_selected_handles();
1019+
}
1020+
else {
1021+
shape_editor.mark_selected_handles();
10191022
}
10201023
if !display_anchors {
1021-
shape_editor.deselect_all_anchors();
1024+
shape_editor.ignore_selected_anchors();
1025+
}
1026+
else {
1027+
shape_editor.mark_selected_anchors();
10221028
}
10231029

10241030
// TODO: find the segment ids of which the selected points are a part of

editor/src/messages/tool/tool_messages/select_tool.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ impl Fsm for SelectToolFsmState {
852852
let is_over_pivot = tool_data.pivot.is_over(mouse_position);
853853

854854
let show_compass = bounds.is_some_and(|quad| quad.all_sides_at_least_width(COMPASS_ROSE_HOVER_RING_DIAMETER) && quad.contains(mouse_position));
855-
/// If bounding box is some, compass_rose_state.can_grab() && show_compass is evaluated else compass_rose_state.can_grab() is evaluated
855+
// If bounding box is some, compass_rose_state.can_grab() && show_compass is evaluated else compass_rose_state.can_grab() is evaluated
856856
let can_grab_compass_rose = compass_rose_state.can_grab() && (show_compass || bounds.is_none());
857857
let is_flat_layer = tool_data
858858
.bounding_box_manager
@@ -916,7 +916,9 @@ impl Fsm for SelectToolFsmState {
916916
// Dragging the selected layers around to transform them
917917
else if can_grab_compass_rose || intersection.is_some_and(|intersection| selected.iter().any(|selected_layer| intersection.starts_with(*selected_layer, document.metadata()))) {
918918
responses.add(DocumentMessage::StartTransaction);
919-
919+
debug!("Starting drag on the layers!");
920+
debug!("can_grab_compass_rose: {:?} ---> compass_rose_state.can_grab(): {:?}, show_compass: {:?}", can_grab_compass_rose, compass_rose_state.can_grab(), show_compass);
921+
920922
if input.keyboard.key(select_deepest) || tool_data.nested_selection_behavior == NestedSelectionBehavior::Deepest {
921923
tool_data.select_single_layer = intersection;
922924
} else {
@@ -1024,9 +1026,18 @@ impl Fsm for SelectToolFsmState {
10241026

10251027
let mouse_delta = snap_drag(start, current, tool_data.axis_align, axis, snap_data, &mut tool_data.snap_manager, &tool_data.snap_candidates);
10261028
let mouse_delta = match axis {
1027-
Axis::X => mouse_delta.project_onto(e0),
1028-
Axis::Y => mouse_delta.project_onto(e0.perp()),
1029-
Axis::None => mouse_delta,
1029+
Axis::X => {
1030+
debug!("The axis is on X!");
1031+
mouse_delta.project_onto(e0)
1032+
},
1033+
Axis::Y => {
1034+
debug!("The axis is on Y!");
1035+
mouse_delta.project_onto(e0.perp())
1036+
},
1037+
Axis::None => {
1038+
debug!("The axis is on both X and Y!");
1039+
mouse_delta
1040+
},
10301041
};
10311042

10321043
// TODO: Cache the result of `shallowest_unique_layers` to avoid this heavy computation every frame of movement, see https://github.com/GraphiteEditor/Graphite/pull/481

0 commit comments

Comments
 (0)