diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index cfca24ae..6e887c25 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -257,6 +257,7 @@ impl MessageHandler { - let layer = self.document_legacy.layer(&layer_path).expect("Setting blob URL for invalid layer"); + let Ok(layer) = self.document_legacy.layer(&layer_path) else { + warn!("Setting blob URL for invalid layer"); + return; + }; // Revoke the old blob URL match &layer.data { @@ -830,10 +841,13 @@ impl MessageHandler panic!( - "Setting blob URL for invalid layer type, which must be an `Imaginate`, `NodeGraphFrame` or `Image`. Found: `{:?}`", - other - ), + other => { + warn!( + "Setting blob URL for invalid layer type, which must be an `Imaginate`, `NodeGraphFrame` or `Image`. Found: `{:?}`", + other + ); + return; + } } responses.push_back( diff --git a/editor/src/messages/portfolio/document/node_graph/graph_operation_message.rs b/editor/src/messages/portfolio/document/node_graph/graph_operation_message.rs index 957a892a..4e46b30c 100644 --- a/editor/src/messages/portfolio/document/node_graph/graph_operation_message.rs +++ b/editor/src/messages/portfolio/document/node_graph/graph_operation_message.rs @@ -11,15 +11,37 @@ pub type LayerIdentifier = Vec; #[impl_message(Message, DocumentMessage, GraphOperation)] #[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)] pub enum GraphOperationMessage { - FillSet { layer: LayerIdentifier, fill: Fill }, + FillSet { + layer: LayerIdentifier, + fill: Fill, + }, - StrokeSet { layer: LayerIdentifier, stroke: Stroke }, + StrokeSet { + layer: LayerIdentifier, + stroke: Stroke, + }, - TransformChange { layer: LayerIdentifier, transform: DAffine2, transform_in: TransformIn }, - TransformSet { layer: LayerIdentifier, transform: DAffine2, transform_in: TransformIn }, - TransformSetPivot { layer: LayerIdentifier, pivot: DVec2 }, + TransformChange { + layer: LayerIdentifier, + transform: DAffine2, + transform_in: TransformIn, + skip_rerender: bool, + }, + TransformSet { + layer: LayerIdentifier, + transform: DAffine2, + transform_in: TransformIn, + skip_rerender: bool, + }, + TransformSetPivot { + layer: LayerIdentifier, + pivot: DVec2, + }, - Vector { layer: LayerIdentifier, modification: VectorDataModification }, + Vector { + layer: LayerIdentifier, + modification: VectorDataModification, + }, } #[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)] diff --git a/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs index e515079c..38eac169 100644 --- a/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs @@ -63,7 +63,7 @@ impl<'a> ModifyInputsContext<'a> { } /// Changes the inputs of a specific node - fn modify_inputs(&mut self, name: &'static str, update_input: impl FnOnce(&mut Vec)) { + fn modify_inputs(&mut self, name: &'static str, skip_rerender: bool, update_input: impl FnOnce(&mut Vec)) { let existing_node_id = self.network.primary_flow().find(|(node, _)| node.name == name).map(|(_, id)| id); if let Some(node_id) = existing_node_id { self.modify_existing_node_inputs(node_id, update_input); @@ -74,15 +74,19 @@ impl<'a> ModifyInputsContext<'a> { self.node_graph.nested_path.clear(); self.responses.add(PropertiesPanelMessage::ResendActiveProperties); let layer_path = self.layer.to_vec(); - self.responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path }); + if !skip_rerender { + self.responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path }); + } else { + self.responses.add(DocumentMessage::FrameClear); + } if existing_node_id.is_none() { self.responses.add(NodeGraphMessage::SendGraph { should_rerender: false }); } } fn fill_set(&mut self, fill: Fill) { - self.modify_inputs("Fill", |inputs| { + self.modify_inputs("Fill", false, |inputs| { let fill_type = match fill { Fill::None => FillType::None, Fill::Solid(_) => FillType::Solid, @@ -104,7 +108,7 @@ impl<'a> ModifyInputsContext<'a> { } fn stroke_set(&mut self, stroke: Stroke) { - self.modify_inputs("Stroke", |inputs| { + self.modify_inputs("Stroke", false, |inputs| { inputs[1] = NodeInput::value(TaggedValue::Color(stroke.color.unwrap_or_default()), false); inputs[2] = NodeInput::value(TaggedValue::F64(stroke.weight), false); inputs[3] = NodeInput::value(TaggedValue::VecF32(stroke.dash_lengths), false); @@ -115,8 +119,8 @@ impl<'a> ModifyInputsContext<'a> { }); } - fn transform_change(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2) { - self.modify_inputs("Transform", |inputs| { + fn transform_change(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2, skip_rerender: bool) { + self.modify_inputs("Transform", skip_rerender, |inputs| { let layer_transform = transform_utils::get_current_transform(inputs); let to = match transform_in { TransformIn::Local => DAffine2::IDENTITY, @@ -128,8 +132,8 @@ impl<'a> ModifyInputsContext<'a> { }); } - fn transform_set(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2, bounds: LayerBounds) { - self.modify_inputs("Transform", |inputs| { + fn transform_set(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2, bounds: LayerBounds, skip_rerender: bool) { + self.modify_inputs("Transform", skip_rerender, |inputs| { let to = match transform_in { TransformIn::Local => DAffine2::IDENTITY, TransformIn::Scope { scope } => scope * parent_transform, @@ -142,7 +146,7 @@ impl<'a> ModifyInputsContext<'a> { } fn pivot_set(&mut self, new_pivot: DVec2, bounds: LayerBounds) { - self.modify_inputs("Transform", |inputs| { + self.modify_inputs("Transform", false, |inputs| { let layer_transform = transform_utils::get_current_transform(inputs); let old_pivot_transform = DAffine2::from_translation(bounds.local_pivot(transform_utils::get_current_normalized_pivot(inputs))); let new_pivot_transform = DAffine2::from_translation(bounds.local_pivot(new_pivot)); @@ -156,7 +160,7 @@ impl<'a> ModifyInputsContext<'a> { let [mut old_bounds_min, mut old_bounds_max] = [DVec2::ZERO, DVec2::ONE]; let [mut new_bounds_min, mut new_bounds_max] = [DVec2::ZERO, DVec2::ONE]; - self.modify_inputs("Path Generator", |inputs| { + self.modify_inputs("Path Generator", false, |inputs| { let [subpaths, mirror_angle_groups] = inputs.as_mut_slice() else { panic!("Path generator does not have subpath and mirror angle inputs"); }; @@ -180,7 +184,7 @@ impl<'a> ModifyInputsContext<'a> { [new_bounds_min, new_bounds_max] = transform_utils::nonzero_subpath_bounds(subpaths); }); - self.modify_inputs("Transform", |inputs| { + self.modify_inputs("Transform", false, |inputs| { let layer_transform = transform_utils::get_current_transform(inputs); let normalized_pivot = transform_utils::get_current_normalized_pivot(inputs); @@ -214,27 +218,37 @@ impl MessageHandler { + GraphOperationMessage::TransformChange { + layer, + transform, + transform_in, + skip_rerender, + } => { let parent_transform = document.multiply_transforms(&layer[..layer.len() - 1]).unwrap_or_default(); if let Some(mut modify_inputs) = ModifyInputsContext::new(&layer, document, node_graph, responses) { - modify_inputs.transform_change(transform, transform_in, parent_transform); - } else { - let transform = transform.to_cols_array(); - responses.add(match transform_in { - TransformIn::Local => Operation::TransformLayer { path: layer, transform }, - TransformIn::Scope { scope } => { - let scope = scope.to_cols_array(); - Operation::TransformLayerInScope { path: layer, transform, scope } - } - TransformIn::Viewport => Operation::TransformLayerInViewport { path: layer, transform }, - }); + modify_inputs.transform_change(transform, transform_in, parent_transform, skip_rerender); } + + let transform = transform.to_cols_array(); + responses.add(match transform_in { + TransformIn::Local => Operation::TransformLayer { path: layer, transform }, + TransformIn::Scope { scope } => { + let scope = scope.to_cols_array(); + Operation::TransformLayerInScope { path: layer, transform, scope } + } + TransformIn::Viewport => Operation::TransformLayerInViewport { path: layer, transform }, + }); } - GraphOperationMessage::TransformSet { layer, transform, transform_in } => { + GraphOperationMessage::TransformSet { + layer, + transform, + transform_in, + skip_rerender, + } => { let parent_transform = document.multiply_transforms(&layer[..layer.len() - 1]).unwrap_or_default(); let bounds = LayerBounds::new(document, &layer); if let Some(mut modify_inputs) = ModifyInputsContext::new(&layer, document, node_graph, responses) { - modify_inputs.transform_set(transform, transform_in, parent_transform, bounds); + modify_inputs.transform_set(transform, transform_in, parent_transform, bounds, skip_rerender); } let transform = transform.to_cols_array(); responses.add(match transform_in { diff --git a/editor/src/messages/portfolio/document/utility_types/transformation.rs b/editor/src/messages/portfolio/document/utility_types/transformation.rs index 9b657fd8..34c185fb 100644 --- a/editor/src/messages/portfolio/document/utility_types/transformation.rs +++ b/editor/src/messages/portfolio/document/utility_types/transformation.rs @@ -166,7 +166,7 @@ impl TransformOperation { self.apply_transform_operation(selected, snapping, axis); } - pub fn handle_typed(&mut self, typed: Option, selected: &mut Selected, snapping: bool) { + pub fn grs_typed(&mut self, typed: Option, selected: &mut Selected, snapping: bool) { match self { TransformOperation::None => (), TransformOperation::Grabbing(translation) => translation.typed_distance = typed, @@ -287,6 +287,7 @@ impl<'a> Selected<'a> { layer: layer_path.to_vec(), transform: new, transform_in: TransformIn::Local, + skip_rerender: true, }); } @@ -302,6 +303,7 @@ impl<'a> Selected<'a> { layer: layer.to_vec(), transform, transform_in: TransformIn::Local, + skip_rerender: false, }); } } diff --git a/editor/src/messages/tool/common_functionality/resize.rs b/editor/src/messages/tool/common_functionality/resize.rs index 4290e3ad..3db810ac 100644 --- a/editor/src/messages/tool/common_functionality/resize.rs +++ b/editor/src/messages/tool/common_functionality/resize.rs @@ -34,35 +34,36 @@ impl Resize { &mut self, responses: &mut VecDeque, document: &DocumentMessageHandler, + ipp: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key, - ipp: &InputPreprocessorMessageHandler, + skip_rerender: bool, ) -> Option { - if let Some(path) = &self.path { - let mut start = self.viewport_drag_start(document); + let Some(path) = &self.path else { + return None; + }; - let stop = self.snap_manager.snap_position(responses, document, ipp.mouse.position); + let mut start = self.viewport_drag_start(document); + let stop = self.snap_manager.snap_position(responses, document, ipp.mouse.position); - let mut size = stop - start; - if ipp.keyboard.get(lock_ratio as usize) { - size = size.abs().max(size.abs().yx()) * size.signum(); - } - if ipp.keyboard.get(center as usize) { - start -= size; - size *= 2.; - } - - Some( - GraphOperationMessage::TransformSet { - layer: path.to_vec(), - transform: DAffine2::from_scale_angle_translation(size, 0., start), - transform_in: TransformIn::Viewport, - } - .into(), - ) - } else { - None + let mut size = stop - start; + if ipp.keyboard.get(lock_ratio as usize) { + size = size.abs().max(size.abs().yx()) * size.signum(); } + if ipp.keyboard.get(center as usize) { + start -= size; + size *= 2.; + } + + Some( + GraphOperationMessage::TransformSet { + layer: path.to_vec(), + transform: DAffine2::from_scale_angle_translation(size, 0., start), + transform_in: TransformIn::Viewport, + skip_rerender, + } + .into(), + ) } pub fn cleanup(&mut self, responses: &mut VecDeque) { diff --git a/editor/src/messages/tool/tool_messages/ellipse_tool.rs b/editor/src/messages/tool/tool_messages/ellipse_tool.rs index 9de56b6b..5d290862 100644 --- a/editor/src/messages/tool/tool_messages/ellipse_tool.rs +++ b/editor/src/messages/tool/tool_messages/ellipse_tool.rs @@ -151,7 +151,7 @@ impl Fsm for EllipseToolFsmState { Drawing } (state, Resize { center, lock_ratio }) => { - if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) { + if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) { responses.push_back(message); } diff --git a/editor/src/messages/tool/tool_messages/frame_tool.rs b/editor/src/messages/tool/tool_messages/frame_tool.rs index 49dc36c9..37adf4e7 100644 --- a/editor/src/messages/tool/tool_messages/frame_tool.rs +++ b/editor/src/messages/tool/tool_messages/frame_tool.rs @@ -113,39 +113,39 @@ impl Fsm for NodeGraphToolFsmState { match (self, event) { (Ready, DragStart) => { shape_data.start(responses, document, input, render_data); - responses.push_back(DocumentMessage::StartTransaction.into()); + responses.add(DocumentMessage::StartTransaction); shape_data.path = Some(document.get_path_for_new_layer()); - responses.push_back(DocumentMessage::DeselectAllLayers.into()); + responses.add(DocumentMessage::DeselectAllLayers); let network = node_graph::new_image_network(8, 0); - responses.push_back( - Operation::AddNodeGraphFrame { - path: shape_data.path.clone().unwrap(), - insert_index: -1, - transform: DAffine2::ZERO.to_cols_array(), - network, - } - .into(), - ); + responses.add(Operation::AddNodeGraphFrame { + path: shape_data.path.clone().unwrap(), + insert_index: -1, + transform: DAffine2::ZERO.to_cols_array(), + network, + }); Drawing } (state, Resize { center, lock_ratio }) => { - if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) { - responses.push_back(message); - } + let message = shape_data.calculate_transform(responses, document, input, center, lock_ratio, true); + responses.try_add(message); state } (Drawing, DragStop) => { + if let Some(layer_path) = &shape_data.path { + responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() }); + } + input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses); shape_data.cleanup(responses); Ready } (Drawing, Abort) => { - responses.push_back(DocumentMessage::AbortTransaction.into()); + responses.add(DocumentMessage::AbortTransaction); shape_data.cleanup(responses); @@ -168,10 +168,10 @@ impl Fsm for NodeGraphToolFsmState { NodeGraphToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]), }; - responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into()); + responses.add(FrontendMessage::UpdateInputHints { hint_data }); } fn update_cursor(&self, responses: &mut VecDeque) { - responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into()); + responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }); } } diff --git a/editor/src/messages/tool/tool_messages/freehand_tool.rs b/editor/src/messages/tool/tool_messages/freehand_tool.rs index d08e11fb..0810be27 100644 --- a/editor/src/messages/tool/tool_messages/freehand_tool.rs +++ b/editor/src/messages/tool/tool_messages/freehand_tool.rs @@ -230,5 +230,6 @@ fn add_polyline(data: &FreehandToolData, tool_data: &DocumentToolData, responses layer: layer_path, transform: DAffine2::from_translation(position), transform_in: TransformIn::Local, + skip_rerender: false, }); } diff --git a/editor/src/messages/tool/tool_messages/imaginate_tool.rs b/editor/src/messages/tool/tool_messages/imaginate_tool.rs index 7ded7c55..3a98fd50 100644 --- a/editor/src/messages/tool/tool_messages/imaginate_tool.rs +++ b/editor/src/messages/tool/tool_messages/imaginate_tool.rs @@ -113,9 +113,9 @@ impl Fsm for ImaginateToolFsmState { match (self, event) { (Ready, DragStart) => { shape_data.start(responses, document, input, render_data); - responses.push_back(DocumentMessage::StartTransaction.into()); + responses.add(DocumentMessage::StartTransaction); shape_data.path = Some(document.get_path_for_new_layer()); - responses.push_back(DocumentMessage::DeselectAllLayers.into()); + responses.add(DocumentMessage::DeselectAllLayers); use graph_craft::document::*; @@ -149,34 +149,34 @@ impl Fsm for ImaginateToolFsmState { ); // Add the node graph frame layer to the document - responses.push_back( - Operation::AddNodeGraphFrame { - path: shape_data.path.clone().unwrap(), - insert_index: -1, - transform: DAffine2::ZERO.to_cols_array(), - network, - } - .into(), - ); - responses.push_back(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id }.into()); + responses.add(Operation::AddNodeGraphFrame { + path: shape_data.path.clone().unwrap(), + insert_index: -1, + transform: DAffine2::ZERO.to_cols_array(), + network, + }); + responses.add(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id }); Drawing } (state, Resize { center, lock_ratio }) => { - if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) { - responses.push_back(message); - } + let message = shape_data.calculate_transform(responses, document, input, center, lock_ratio, true); + responses.try_add(message); state } (Drawing, DragStop) => { + if let Some(layer_path) = &shape_data.path { + responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() }); + } + input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses); shape_data.cleanup(responses); Ready } (Drawing, Abort) => { - responses.push_back(DocumentMessage::AbortTransaction.into()); + responses.add(DocumentMessage::AbortTransaction); shape_data.cleanup(responses); @@ -199,10 +199,10 @@ impl Fsm for ImaginateToolFsmState { ImaginateToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]), }; - responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into()); + responses.add(FrontendMessage::UpdateInputHints { hint_data }); } fn update_cursor(&self, responses: &mut VecDeque) { - responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into()); + responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }); } } diff --git a/editor/src/messages/tool/tool_messages/line_tool.rs b/editor/src/messages/tool/tool_messages/line_tool.rs index f3e134d0..9320a7a6 100644 --- a/editor/src/messages/tool/tool_messages/line_tool.rs +++ b/editor/src/messages/tool/tool_messages/line_tool.rs @@ -256,6 +256,7 @@ fn generate_transform(tool_data: &mut LineToolData, lock_angle: bool, snap_angle layer: tool_data.path.clone().unwrap(), transform: glam::DAffine2::from_scale_angle_translation(DVec2::new(line_length, 1.), angle, start), transform_in: TransformIn::Viewport, + skip_rerender: false, } .into() } diff --git a/editor/src/messages/tool/tool_messages/rectangle_tool.rs b/editor/src/messages/tool/tool_messages/rectangle_tool.rs index d5638759..dd18489e 100644 --- a/editor/src/messages/tool/tool_messages/rectangle_tool.rs +++ b/editor/src/messages/tool/tool_messages/rectangle_tool.rs @@ -133,7 +133,7 @@ impl Fsm for RectangleToolFsmState { Drawing } (state, Resize { center, lock_ratio }) => { - if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) { + if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) { responses.push_back(message); } diff --git a/editor/src/messages/tool/tool_messages/select_tool.rs b/editor/src/messages/tool/tool_messages/select_tool.rs index 9a6ed2f3..bcceaf4a 100644 --- a/editor/src/messages/tool/tool_messages/select_tool.rs +++ b/editor/src/messages/tool/tool_messages/select_tool.rs @@ -338,6 +338,7 @@ impl SelectToolData { fn start_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque) { responses.push_back(DocumentMessage::DeselectAllLayers.into()); + // Take the selected layers and store them in a separate list. self.not_duplicated_layers = Some(self.layers_dragging.clone()); // Duplicate each previously selected layer and select the new ones. @@ -348,6 +349,7 @@ impl SelectToolData { layer: layer_path.clone(), transform: DAffine2::from_translation(self.drag_start - self.drag_current), transform_in: TransformIn::Viewport, + skip_rerender: true, } .into(), ); @@ -365,26 +367,24 @@ impl SelectToolData { let layer_metadata = *document.layer_metadata(layer_path); *layer_path.last_mut().unwrap() = generate_uuid(); - responses.push_back( - Operation::InsertLayer { - layer: Box::new(layer), - destination_path: layer_path.clone(), - insert_index: -1, - } - .into(), - ); + responses.add(Operation::InsertLayer { + layer: Box::new(layer), + destination_path: layer_path.clone(), + insert_index: -1, + }); + responses.add(DocumentMessage::UpdateLayerMetadata { + layer_path: layer_path.clone(), + layer_metadata, + }); + } - responses.push_back( - DocumentMessage::UpdateLayerMetadata { - layer_path: layer_path.clone(), - layer_metadata, - } - .into(), - ); + // Since the selected layers have now moved back to their original transforms before the drag began, we rerender them to be displayed as if they weren't touched. + for layer_path in self.not_duplicated_layers.iter().flatten() { + responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() }); } } - /// Removes the duplicated layers. Called when Alt is released and the layers have been duplicated. + /// Removes the duplicated layers. Called when Alt is released and the layers have previously been duplicated. fn stop_duplicates(&mut self, responses: &mut VecDeque) { let originals = match self.not_duplicated_layers.take() { Some(x) => x, @@ -405,6 +405,7 @@ impl SelectToolData { layer: layer_path.clone(), transform: DAffine2::from_translation(self.drag_current - self.drag_start), transform_in: TransformIn::Viewport, + skip_rerender: true, } .into(), ); @@ -624,6 +625,7 @@ impl Fsm for SelectToolFsmState { layer: path.to_vec(), transform: DAffine2::from_translation(mouse_delta + closest_move), transform_in: TransformIn::Viewport, + skip_rerender: true, } .into(), ); @@ -729,15 +731,20 @@ impl Fsm for SelectToolFsmState { Ready } (Dragging, Enter) => { + rerender_selected_layers(tool_data, responses); + let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON { true => DocumentMessage::Undo, false => DocumentMessage::CommitTransaction, }; tool_data.snap_manager.cleanup(responses); responses.push_front(response.into()); + Ready } (Dragging, DragStop { remove_from_selection }) => { + rerender_selected_layers(tool_data, responses); + // Deselect layer if not snap dragging if !tool_data.is_dragging && input.keyboard.get(remove_from_selection as usize) && tool_data.layer_selected_on_start.is_none() { let quad = tool_data.selection_quad(); @@ -760,9 +767,12 @@ impl Fsm for SelectToolFsmState { responses.push_back(DocumentMessage::CommitTransaction.into()); tool_data.snap_manager.cleanup(responses); + Ready } (ResizingBounds, DragStop { .. } | Enter) => { + rerender_selected_layers(tool_data, responses); + let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON { true => DocumentMessage::Undo, false => DocumentMessage::CommitTransaction, @@ -778,6 +788,8 @@ impl Fsm for SelectToolFsmState { Ready } (RotatingBounds, DragStop { .. } | Enter) => { + rerender_selected_layers(tool_data, responses); + let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON { true => DocumentMessage::Undo, false => DocumentMessage::CommitTransaction, @@ -838,6 +850,8 @@ impl Fsm for SelectToolFsmState { Ready } (Dragging, Abort) => { + rerender_selected_layers(tool_data, responses); + tool_data.snap_manager.cleanup(responses); responses.push_back(DocumentMessage::Undo.into()); @@ -951,6 +965,18 @@ impl Fsm for SelectToolFsmState { } } +fn rerender_selected_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque) { + for layer_path in &tool_data.layers_dragging { + responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() }); + } +} + +fn rerender_duplicated_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque) { + for layer_path in tool_data.not_duplicated_layers.iter().flatten() { + responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() }); + } +} + // TODO: Majorly clean up these next five functions fn drag_shallowest_manipulation( diff --git a/editor/src/messages/tool/tool_messages/shape_tool.rs b/editor/src/messages/tool/tool_messages/shape_tool.rs index 90651602..04a68e2a 100644 --- a/editor/src/messages/tool/tool_messages/shape_tool.rs +++ b/editor/src/messages/tool/tool_messages/shape_tool.rs @@ -172,7 +172,7 @@ impl Fsm for ShapeToolFsmState { Drawing } (state, Resize { center, lock_ratio }) => { - if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) { + if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) { responses.push_back(message); } diff --git a/editor/src/messages/tool/tool_messages/spline_tool.rs b/editor/src/messages/tool/tool_messages/spline_tool.rs index 3abcb1b9..2806357b 100644 --- a/editor/src/messages/tool/tool_messages/spline_tool.rs +++ b/editor/src/messages/tool/tool_messages/spline_tool.rs @@ -274,5 +274,6 @@ fn add_spline(tool_data: &SplineToolData, global_tool_data: &DocumentToolData, s layer: layer_path, transform: glam::DAffine2::from_translation(position), transform_in: TransformIn::Local, + skip_rerender: false, }) } diff --git a/editor/src/messages/tool/tool_messages/text_tool.rs b/editor/src/messages/tool/tool_messages/text_tool.rs index 6446cd38..9c85a3a2 100644 --- a/editor/src/messages/tool/tool_messages/text_tool.rs +++ b/editor/src/messages/tool/tool_messages/text_tool.rs @@ -330,6 +330,7 @@ impl Fsm for TextToolFsmState { layer: tool_data.layer_path.clone(), transform, transform_in: TransformIn::Viewport, + skip_rerender: false, } .into(), ); 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 21c3db92..b416e69a 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 @@ -72,6 +72,9 @@ impl<'a> MessageHandler> for TransformL responses.add(ToolMessage::UpdateHints); responses.add(BroadcastEvent::DocumentIsDirty); + for layer_path in document.selected_layers() { + responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() }); + } } BeginGrab => { if let TransformOperation::Grabbing(_) = self.transform_operation { @@ -194,10 +197,10 @@ impl<'a> MessageHandler> for TransformL let layer_paths = document.selected_visible_layers().map(|layer_path| layer_path.to_vec()).collect(); shape_editor.set_selected_layers(layer_paths); } - TypeBackspace => self.transform_operation.handle_typed(self.typing.type_backspace(), &mut selected, self.snap), - TypeDecimalPoint => self.transform_operation.handle_typed(self.typing.type_decimal_point(), &mut selected, self.snap), - TypeDigit { digit } => self.transform_operation.handle_typed(self.typing.type_number(digit), &mut selected, self.snap), - TypeNegate => self.transform_operation.handle_typed(self.typing.type_negate(), &mut selected, self.snap), + TypeBackspace => self.transform_operation.grs_typed(self.typing.type_backspace(), &mut selected, self.snap), + TypeDecimalPoint => self.transform_operation.grs_typed(self.typing.type_decimal_point(), &mut selected, self.snap), + TypeDigit { digit } => self.transform_operation.grs_typed(self.typing.type_number(digit), &mut selected, self.snap), + TypeNegate => self.transform_operation.grs_typed(self.typing.type_negate(), &mut selected, self.snap), } }