From 6c0881b56f023f9d3d21d65ee80d52c947077108 Mon Sep 17 00:00:00 2001 From: 0SlowPoke0 Date: Thu, 9 Jan 2025 10:06:18 +0530 Subject: [PATCH] minor improvements and fixes --- .../src/messages/tool/tool_message_handler.rs | 10 +- .../messages/tool/tool_messages/path_tool.rs | 14 +-- .../transform_layer_message_handler.rs | 95 +++++++++++++++++++ node-graph/gcore/src/vector/vector_data.rs | 7 ++ 4 files changed, 110 insertions(+), 16 deletions(-) diff --git a/editor/src/messages/tool/tool_message_handler.rs b/editor/src/messages/tool/tool_message_handler.rs index ca855b90d7..2663e3f6b2 100644 --- a/editor/src/messages/tool/tool_message_handler.rs +++ b/editor/src/messages/tool/tool_message_handler.rs @@ -76,7 +76,7 @@ impl MessageHandler> for ToolMessageHandler { self.tool_is_active = true; // Send the old and new tools a transition to their FSM Abort states - let mut send_abort_to_tool = |tool_type, update_hints_and_cursor: bool| { + let mut send_abort_to_tool = |old_tool: ToolType, new_tool: ToolType, update_hints_and_cursor: bool| { if let Some(tool) = tool_data.tools.get_mut(&tool_type) { let mut data = ToolActionHandlerData { document, @@ -101,9 +101,13 @@ impl MessageHandler> for ToolMessageHandler { tool.process_message(ToolMessage::UpdateCursor, responses, &mut data); } } + if matches!(old_tool, ToolType::Path | ToolType::Select) { + responses.add(TransformLayerMessage::CancelTransformOperation); + } }; - send_abort_to_tool(tool_type, true); - send_abort_to_tool(old_tool, false); + + send_abort_to_tool(old_tool, tool_type, true); + send_abort_to_tool(old_tool, old_tool, false); // Unsubscribe old tool from the broadcaster tool_data.tools.get(&tool_type).unwrap().deactivate(responses); diff --git a/editor/src/messages/tool/tool_messages/path_tool.rs b/editor/src/messages/tool/tool_messages/path_tool.rs index 3bb5cc763f..8f6ae8fd74 100644 --- a/editor/src/messages/tool/tool_messages/path_tool.rs +++ b/editor/src/messages/tool/tool_messages/path_tool.rs @@ -645,19 +645,7 @@ impl Fsm for PathToolFsmState { self } (Self::InsertPoint, PathToolMessage::Escape | PathToolMessage::Delete | PathToolMessage::RightClick) => tool_data.end_insertion(shape_editor, responses, InsertEndKind::Abort), - (Self::InsertPoint, PathToolMessage::GRS { key: propagate }) => { - // MAYBE: use `InputMapperMessage::KeyDown(..)` instead - match propagate { - // TODO: Don't use `Key::G` directly, instead take it as a variable from the input mappings list like in all other places - Key::KeyG => responses.add(TransformLayerMessage::BeginGrab), - // TODO: Don't use `Key::R` directly, instead take it as a variable from the input mappings list like in all other places - Key::KeyR => responses.add(TransformLayerMessage::BeginRotate), - // TODO: Don't use `Key::S` directly, instead take it as a variable from the input mappings list like in all other places - Key::KeyS => responses.add(TransformLayerMessage::BeginScale), - _ => warn!("Unexpected GRS key"), - } - tool_data.end_insertion(shape_editor, responses, InsertEndKind::Abort) - } + (Self::InsertPoint, PathToolMessage::GRS { key: _ }) => PathToolFsmState::InsertPoint, // Mouse down ( _, diff --git a/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs b/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs index 0581aa9da0..4f16d9c90b 100644 --- a/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs +++ b/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs @@ -43,6 +43,7 @@ type TransformData<'a> = (&'a DocumentMessageHandler, &'a InputPreprocessorMessa impl MessageHandler> for TransformLayerMessageHandler { fn process_message(&mut self, message: TransformLayerMessage, responses: &mut VecDeque, (document, input, tool_data, shape_editor): TransformData) { let using_path_tool = tool_data.active_tool_type == ToolType::Path; + let using_select_tool = tool_data.active_tool_type == ToolType::Select; // TODO: Add support for transforming layer not in the document network let selected_layers = document @@ -120,6 +121,17 @@ impl MessageHandler> for TransformLayer responses.add(NodeGraphMessage::RunDocumentGraph); } TransformLayerMessage::BeginGrab => { + if !(using_path_tool || using_select_tool) { + return; + } + let points = shape_editor.selected_points(); + let selected_points: Vec<&ManipulatorPointId> = points.collect(); + + if using_path_tool && selected_points.is_empty() { + responses.add(TransformLayerMessage::CancelTransformOperation); + return; + } + if let TransformOperation::Grabbing(_) = self.transform_operation { return; } @@ -136,6 +148,56 @@ impl MessageHandler> for TransformLayer selected.original_transforms.clear(); } TransformLayerMessage::BeginRotate => { + if !(using_path_tool || using_select_tool) { + return; + } + let Some(&layer) = selected_layers.first() else { + return; + }; + let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { + return; + }; + let points = shape_editor.selected_points(); + let selected_points: Vec<&ManipulatorPointId> = points.collect(); + + if using_path_tool && selected_points.is_empty() { + responses.add(TransformLayerMessage::CancelTransformOperation); + return; + } + + if selected_points.len() == 1 { + if let Some(point) = selected_points.first() { + match point { + ManipulatorPointId::Anchor(_) => { + if let Some([handle1, handle2]) = point.get_handle_pair(&vector_data) { + if (handle1.get_handle_length(&vector_data) == 0.0 && handle2.get_handle_length(&vector_data) == 0.0) + || (handle1.get_handle_length(&vector_data) == f64::MAX && handle2.get_handle_length(&vector_data) == f64::MAX) + { + self.transform_operation = TransformOperation::None; + + responses.add(TransformLayerMessage::CancelTransformOperation); + return; + } + } + } + _ => { + let handle_position = point.get_position(&vector_data); + let anchor_position = point.get_anchor_position(&vector_data); + + if let (Some(handle_pos), Some(anchor_pos)) = (handle_position, anchor_position) { + // Calculate the distance between the handle and anchor + let distance = (handle_pos - anchor_pos).length(); + + // If the distance is zero, return early + if distance == 0.0 { + return; + } + } + } + } + } + } + if let TransformOperation::Rotating(_) = self.transform_operation { return; } @@ -152,6 +214,39 @@ impl MessageHandler> for TransformLayer selected.original_transforms.clear(); } TransformLayerMessage::BeginScale => { + if !(using_path_tool || using_select_tool) { + return; + } + let Some(&layer) = selected_layers.first() else { + return; + }; + let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { + return; + }; + + let points = shape_editor.selected_points(); + let selected_points: Vec<&ManipulatorPointId> = points.collect(); + + if using_path_tool && selected_points.is_empty() { + responses.add(TransformLayerMessage::CancelTransformOperation); + return; + } + + if selected_points.len() == 1 { + if let Some(point) = selected_points.first() { + if let ManipulatorPointId::Anchor(_) = point { + if let Some([handle1, handle2]) = point.get_handle_pair(&vector_data) { + if (handle1.get_handle_length(&vector_data) == 0.0 && handle2.get_handle_length(&vector_data) == 0.0) + || (handle1.get_handle_length(&vector_data) == f64::MAX && handle2.get_handle_length(&vector_data) == f64::MAX) + { + responses.add(TransformLayerMessage::CancelTransformOperation); + return; + } + } + } + } + } + if let TransformOperation::Scaling(_) = self.transform_operation { return; } diff --git a/node-graph/gcore/src/vector/vector_data.rs b/node-graph/gcore/src/vector/vector_data.rs index 61928fb862..adece92744 100644 --- a/node-graph/gcore/src/vector/vector_data.rs +++ b/node-graph/gcore/src/vector/vector_data.rs @@ -403,6 +403,13 @@ impl HandleId { } } + pub fn get_handle_length(self, vector_data: &VectorData) -> f64 { + let anchor_position = self.to_manipulator_point().get_anchor_position(&vector_data).unwrap(); + let handle_position = self.to_manipulator_point().get_position(&vector_data); + let handle_length = handle_position.map(|pos| (pos - anchor_position).length()).unwrap_or(f64::MAX); + handle_length + } + /// Set the handle's position relative to the anchor which is the start anchor for the primary handle and end anchor for the end handle. #[must_use] pub fn set_relative_position(self, relative_position: DVec2) -> VectorModificationType {