Disable the Path tool's "Colinear Handles" checkbox when no interior anchors are selected (#2339)
* disable "Colinear Handles" checkbox when only endpoint or its handle is selected * small refactor * ignore endpoints when calculating multiple selected points colinearity --------- Co-authored-by: indierusty <priyaayadav@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
381dcbf17f
commit
0a91dd2141
|
|
@ -575,7 +575,7 @@ impl ShapeState {
|
|||
Some(())
|
||||
}
|
||||
|
||||
/// Iterates over the selected manipulator groups, returning whether their handles have mixed, colinear, or free angles.
|
||||
/// Iterates over the selected manipulator groups exluding endpoints, returning whether their handles have mixed, colinear, or free angles.
|
||||
/// If there are no points selected this function returns mixed.
|
||||
pub fn selected_manipulator_angles(&self, network_interface: &NodeNetworkInterface) -> ManipulatorAngle {
|
||||
// This iterator contains a bool indicating whether or not selected points' manipulator groups have colinear handles.
|
||||
|
|
@ -583,7 +583,13 @@ impl ShapeState {
|
|||
.selected_shape_state
|
||||
.iter()
|
||||
.map(|(&layer, selection_state)| (network_interface.compute_modified_vector(layer), selection_state))
|
||||
.flat_map(|(data, selection_state)| selection_state.selected_points.iter().map(move |&point| data.as_ref().is_some_and(|data| data.colinear(point))));
|
||||
.flat_map(|(data, selection_state)| {
|
||||
selection_state.selected_points.iter().filter_map(move |&point| {
|
||||
let Some(data) = &data else { return None };
|
||||
let Some(_) = point.get_handle_pair(&data) else { return None }; // ignores the endpoints.
|
||||
Some(data.colinear(point))
|
||||
})
|
||||
});
|
||||
|
||||
let Some(first_is_colinear) = points_colinear_status.next() else { return ManipulatorAngle::Mixed };
|
||||
if points_colinear_status.any(|point| first_is_colinear != point) {
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ impl LayoutHolder for PathTool {
|
|||
// TODO: Remove `unwrap_or_default` once checkboxes are capable of displaying a mixed state
|
||||
.unwrap_or_default();
|
||||
let colinear_handle_checkbox = CheckboxInput::new(colinear_handles_state)
|
||||
.disabled(self.tool_data.selection_status.is_none())
|
||||
.disabled(!self.tool_data.can_toggle_colinearity)
|
||||
.on_update(|&CheckboxInput { checked, .. }| {
|
||||
if checked {
|
||||
PathToolMessage::ManipulatorMakeHandlesColinear.into()
|
||||
|
|
@ -186,7 +186,7 @@ impl LayoutHolder for PathTool {
|
|||
.tooltip(colinear_handles_tooltip)
|
||||
.widget_holder();
|
||||
let colinear_handles_label = TextLabel::new("Colinear Handles")
|
||||
.disabled(self.tool_data.selection_status.is_none())
|
||||
.disabled(!self.tool_data.can_toggle_colinearity)
|
||||
.tooltip(colinear_handles_tooltip)
|
||||
.widget_holder();
|
||||
|
||||
|
|
@ -359,7 +359,10 @@ struct PathToolData {
|
|||
opposing_handle_lengths: Option<OpposingHandleLengths>,
|
||||
/// Describes information about the selected point(s), if any, across one or multiple shapes and manipulator point types (anchor or handle).
|
||||
/// The available information varies depending on whether `None`, `One`, or `Multiple` points are currently selected.
|
||||
/// NOTE: It must be updated using `update_selection_status` to ensure `can_toggle_colinearity` stays synchronized with the current selection.
|
||||
selection_status: SelectionStatus,
|
||||
/// `true` if we can change the current selection to colinear or not.
|
||||
can_toggle_colinearity: bool,
|
||||
segment: Option<ClosestSegment>,
|
||||
snap_cache: SnapCache,
|
||||
double_click_handled: bool,
|
||||
|
|
@ -415,6 +418,20 @@ impl PathToolData {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_selection_status(&mut self, shape_editor: &mut ShapeState, document: &DocumentMessageHandler) {
|
||||
let selection_status = get_selection_status(&document.network_interface, shape_editor);
|
||||
|
||||
self.can_toggle_colinearity = match &selection_status {
|
||||
SelectionStatus::None => false,
|
||||
SelectionStatus::One(single_selected_point) => {
|
||||
let vector_data = document.network_interface.compute_modified_vector(single_selected_point.layer).unwrap();
|
||||
single_selected_point.id.get_handle_pair(&vector_data).is_some()
|
||||
}
|
||||
SelectionStatus::Multiple(_) => true,
|
||||
};
|
||||
self.selection_status = selection_status;
|
||||
}
|
||||
|
||||
fn start_insertion(&mut self, responses: &mut VecDeque<Message>, segment: ClosestSegment) -> PathToolFsmState {
|
||||
if self.segment.is_some() {
|
||||
warn!("Segment was `Some(..)` before `start_insertion`")
|
||||
|
|
@ -1302,7 +1319,7 @@ impl Fsm for PathToolFsmState {
|
|||
point_select_state: shape_editor.get_dragging_state(&document.network_interface),
|
||||
colinear,
|
||||
};
|
||||
tool_data.selection_status = get_selection_status(&document.network_interface, shape_editor);
|
||||
tool_data.update_selection_status(shape_editor, document);
|
||||
self
|
||||
}
|
||||
(_, PathToolMessage::ManipulatorMakeHandlesColinear) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue