diff --git a/editor/src/viewport_tools/tools/artboard_tool.rs b/editor/src/viewport_tools/tools/artboard_tool.rs index 8fb5aa676..71fc038da 100644 --- a/editor/src/viewport_tools/tools/artboard_tool.rs +++ b/editor/src/viewport_tools/tools/artboard_tool.rs @@ -127,19 +127,18 @@ impl Fsm for ArtboardToolFsmState { if let ToolMessage::Artboard(event) = event { match (self, event) { (ArtboardToolFsmState::Ready | ArtboardToolFsmState::ResizingBounds | ArtboardToolFsmState::Dragging, ArtboardToolMessage::DocumentIsDirty) => { - let mut buffer = Vec::new(); match ( tool_data.selected_board.map(|path| document.artboard_bounding_box_and_transform(&[path], font_cache)).unwrap_or(None), tool_data.bounding_box_overlays.take(), ) { - (None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(&mut buffer), + (None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(responses), (Some((bounds, transform)), paths) => { - let mut bounding_box_overlays = paths.unwrap_or_else(|| BoundingBoxOverlays::new(&mut buffer)); + let mut bounding_box_overlays = paths.unwrap_or_else(|| BoundingBoxOverlays::new(responses)); bounding_box_overlays.bounds = bounds; bounding_box_overlays.transform = transform; - bounding_box_overlays.transform(&mut buffer); + bounding_box_overlays.transform(responses); tool_data.bounding_box_overlays = Some(bounding_box_overlays); @@ -154,7 +153,6 @@ impl Fsm for ArtboardToolFsmState { } _ => {} }; - buffer.into_iter().rev().for_each(|message| responses.push_front(message)); self } (ArtboardToolFsmState::Ready, ArtboardToolMessage::PointerDown) => { diff --git a/editor/src/viewport_tools/tools/select_tool.rs b/editor/src/viewport_tools/tools/select_tool.rs index 65112b0c6..512fb05f9 100644 --- a/editor/src/viewport_tools/tools/select_tool.rs +++ b/editor/src/viewport_tools/tools/select_tool.rs @@ -36,6 +36,8 @@ pub enum SelectToolMessage { Abort, #[remain::unsorted] DocumentIsDirty, + #[remain::unsorted] + SelectionChanged, // Tool-specific messages Align { @@ -275,7 +277,7 @@ impl ToolTransition for SelectTool { SignalToMessageMap { document_dirty: Some(SelectToolMessage::DocumentIsDirty.into()), tool_abort: Some(SelectToolMessage::Abort.into()), - selection_changed: None, + selection_changed: Some(SelectToolMessage::SelectionChanged.into()), } } } @@ -339,25 +341,22 @@ impl Fsm for SelectToolFsmState { use SelectToolMessage::*; if let ToolMessage::Select(event) = event { - log::debug!("self: {:?}, even: {:?}", self, event); match (self, event) { - (_, DocumentIsDirty) => { - let mut buffer = Vec::new(); + (_, DocumentIsDirty | SelectionChanged) => { match (document.selected_visible_layers_bounding_box(font_cache), tool_data.bounding_box_overlays.take()) { - (None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(&mut buffer), + (None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(responses), (Some(bounds), paths) => { - let mut bounding_box_overlays = paths.unwrap_or_else(|| BoundingBoxOverlays::new(&mut buffer)); + let mut bounding_box_overlays = paths.unwrap_or_else(|| BoundingBoxOverlays::new(responses)); bounding_box_overlays.bounds = bounds; bounding_box_overlays.transform = DAffine2::IDENTITY; - bounding_box_overlays.transform(&mut buffer); + bounding_box_overlays.transform(responses); tool_data.bounding_box_overlays = Some(bounding_box_overlays); } (_, _) => {} }; - buffer.into_iter().rev().for_each(|message| responses.push_front(message)); tool_data.path_outlines.update_selected(document.selected_visible_layers(), document, responses, font_cache); tool_data.path_outlines.intersect_test_hovered(input, document, responses, font_cache); @@ -394,7 +393,6 @@ impl Fsm for SelectToolFsmState { tool_data.drag_start = input.mouse.position; tool_data.drag_current = input.mouse.position; - let mut buffer = Vec::new(); let dragging_bounds = if let Some(bounding_box) = &mut tool_data.bounding_box_overlays { let edges = bounding_box.check_selected_edges(input.mouse.position); @@ -448,7 +446,7 @@ impl Fsm for SelectToolFsmState { RotatingBounds } else if selected.iter().any(|path| intersection.contains(path)) { - buffer.push(DocumentMessage::StartTransaction.into()); + responses.push_back(DocumentMessage::StartTransaction.into()); tool_data.layers_dragging = selected; tool_data @@ -458,14 +456,14 @@ impl Fsm for SelectToolFsmState { Dragging } else { if !input.keyboard.get(add_to_selection as usize) { - buffer.push(DocumentMessage::DeselectAllLayers.into()); + responses.push_back(DocumentMessage::DeselectAllLayers.into()); tool_data.layers_dragging.clear(); } if let Some(intersection) = intersection.pop() { selected = vec![intersection]; - buffer.push(DocumentMessage::AddSelectedLayers { additional_layers: selected.clone() }.into()); - buffer.push(DocumentMessage::StartTransaction.into()); + responses.push_back(DocumentMessage::AddSelectedLayers { additional_layers: selected.clone() }.into()); + responses.push_back(DocumentMessage::StartTransaction.into()); tool_data.layers_dragging.append(&mut selected); tool_data .snap_handler @@ -473,11 +471,10 @@ impl Fsm for SelectToolFsmState { Dragging } else { - tool_data.drag_box_overlay_layer = Some(add_bounding_box(&mut buffer)); + tool_data.drag_box_overlay_layer = Some(add_bounding_box(responses)); DrawingBox } }; - buffer.into_iter().rev().for_each(|message| responses.push_front(message)); state } diff --git a/editor/src/viewport_tools/tools/shared/transformation_cage.rs b/editor/src/viewport_tools/tools/shared/transformation_cage.rs index 82f7edfc3..6485abcf2 100644 --- a/editor/src/viewport_tools/tools/shared/transformation_cage.rs +++ b/editor/src/viewport_tools/tools/shared/transformation_cage.rs @@ -137,7 +137,7 @@ impl SelectedEdges { } /// Create a viewport relative bounding box overlay with no transform handles -pub fn add_bounding_box(responses: &mut Vec) -> Vec { +pub fn add_bounding_box(responses: &mut VecDeque) -> Vec { let path = vec![generate_uuid()]; let operation = Operation::AddRect { @@ -146,13 +146,13 @@ pub fn add_bounding_box(responses: &mut Vec) -> Vec { style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Fill::None), insert_index: -1, }; - responses.push(DocumentMessage::Overlays(operation.into()).into()); + responses.push_back(DocumentMessage::Overlays(operation.into()).into()); path } /// Add the transform handle overlay -fn add_transform_handles(responses: &mut Vec) -> [Vec; 8] { +fn add_transform_handles(responses: &mut VecDeque) -> [Vec; 8] { const EMPTY_VEC: Vec = Vec::new(); let mut transform_handle_paths = [EMPTY_VEC; 8]; @@ -165,7 +165,7 @@ fn add_transform_handles(responses: &mut Vec) -> [Vec; 8] { style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 2.0)), Fill::solid(Color::WHITE)), insert_index: -1, }; - responses.push(DocumentMessage::Overlays(operation.into()).into()); + responses.push_back(DocumentMessage::Overlays(operation.into()).into()); *item = current_path; } @@ -211,10 +211,10 @@ pub struct BoundingBoxOverlays { impl BoundingBoxOverlays { #[must_use] - pub fn new(buffer: &mut Vec) -> Self { + pub fn new(responses: &mut VecDeque) -> Self { Self { - bounding_box: add_bounding_box(buffer), - transform_handles: add_transform_handles(buffer), + bounding_box: add_bounding_box(responses), + transform_handles: add_transform_handles(responses), ..Default::default() } } @@ -236,10 +236,10 @@ impl BoundingBoxOverlays { } /// Update the position of the bounding box and transform handles - pub fn transform(&mut self, buffer: &mut Vec) { + pub fn transform(&mut self, responses: &mut VecDeque) { let transform = transform_from_box(self.bounds[0], self.bounds[1], self.transform).to_cols_array(); let path = self.bounding_box.clone(); - buffer.push(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()).into()); + responses.push_back(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()).into()); // Helps push values that end in approximately half, plus or minus some floating point imprecision, towards the same side of the round() function const BIAS: f64 = 0.0001; @@ -249,7 +249,7 @@ impl BoundingBoxOverlays { let translation = (position - (scale / 2.) - 0.5 + BIAS).round(); let transform = DAffine2::from_scale_angle_translation(scale, 0., translation).to_cols_array(); let path = path.clone(); - buffer.push(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()).into()); + responses.push_back(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()).into()); } } @@ -314,9 +314,9 @@ impl BoundingBoxOverlays { } /// Removes the overlays - pub fn delete(self, buffer: &mut impl Extend) { - buffer.extend([DocumentMessage::Overlays(Operation::DeleteLayer { path: self.bounding_box }.into()).into()]); - buffer.extend( + pub fn delete(self, responses: &mut VecDeque) { + responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: self.bounding_box }.into()).into()); + responses.extend( self.transform_handles .iter() .map(|path| DocumentMessage::Overlays(Operation::DeleteLayer { path: path.clone() }.into()).into()),