Fix many regressions introduced mostly in #1946 (#1986)

* Fix text tool

* Implement buffering to fix freehand tool

* Fix tools

* Fix clippy lints

* Small fixes

* Move vector modify back to Monitor nodes

* Code review

* Fix abort

* Fix svg import

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
adamgerhant
2024-09-26 15:37:03 -07:00
committed by GitHub
co-authored by Keavon Chambers
parent c738b4a1f9
commit 20470b566b
18 changed files with 152 additions and 91 deletions
@@ -196,6 +196,19 @@ impl ArtboardToolData {
location: position.round().as_ivec2(),
dimensions: size.round().as_ivec2(),
});
// TODO: Resize artboard children when resizing left/top edges so that they stay in the same viewport space
// let old_top_left = bounds.bounds[0].round().as_ivec2();
// let new_top_left = position.round().as_ivec2();
// let top_left_delta = new_top_left - old_top_left;
// if top_left_delta != IVec2::ZERO {
// responses.add(GraphOperationMessage::TransformChange {
// layer: self.selected_artboard.unwrap(),
// transform: DAffine2::from_translation((-top_left_delta).into()),
// transform_in: TransformIn::Local,
// skip_rerender: false,
// });
// }
}
}
@@ -206,6 +206,7 @@ impl Fsm for EllipseToolFsmState {
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId(generate_uuid()), nodes, document.new_layer_parent(true), responses);
responses.add(Message::StartBuffer);
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., input.mouse.position),
@@ -229,15 +229,11 @@ impl Fsm for FreehandToolFsmState {
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId(generate_uuid()), nodes, parent, responses);
responses.add(Message::StartBuffer);
tool_options.fill.apply_fill(layer, responses);
tool_options.stroke.apply_stroke(tool_data.weight, layer, responses);
tool_data.layer = Some(layer);
let transform = document.metadata().transform_to_viewport(parent);
let position = transform.inverse().transform_point2(input.mouse.position);
extend_path_with_next_segment(tool_data, position, responses);
FreehandToolFsmState::Drawing
}
(FreehandToolFsmState::Drawing, FreehandToolMessage::PointerMove) => {
@@ -188,6 +188,7 @@ impl Fsm for LineToolFsmState {
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId(generate_uuid()), nodes, document.new_layer_parent(false), responses);
responses.add(Message::StartBuffer);
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., input.mouse.position),
@@ -525,21 +525,11 @@ impl Fsm for PenToolFsmState {
tool_data.layer = Some(layer);
tool_data.next_point = position;
tool_data.next_handle_start = position;
} else {
// New path layer
let node_type = resolve_document_node_type("Path").expect("Path node does not exist");
let nodes = vec![(NodeId(0), node_type.default_node_template())];
let parent = document.new_layer_parent(true);
let layer = graph_modification_utils::new_custom(NodeId(generate_uuid()), nodes, parent, responses);
tool_options.fill.apply_fill(layer, responses);
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, responses);
tool_data.layer = Some(layer);
} else if let Some(layer) = tool_data.layer {
// Add the first point to a new layer
// Generate first point
let id = PointId::generate();
let transform = document.metadata().transform_to_document(parent);
let pos = transform.inverse().transform_point2(snapped.snapped_point_document);
let pos = document.metadata().transform_to_viewport(layer).inverse().transform_point2(viewport);
let modification_type = VectorModificationType::InsertPoint { id, position: pos };
responses.add(GraphOperationMessage::Vector { layer, modification_type });
tool_data.add_point(LastPoint {
@@ -550,9 +540,21 @@ impl Fsm for PenToolFsmState {
});
tool_data.next_point = pos;
tool_data.next_handle_start = pos;
} else {
// New path layer
let node_type = resolve_document_node_type("Path").expect("Path node does not exist");
let nodes = vec![(NodeId(0), node_type.default_node_template())];
let parent = document.new_layer_parent(true);
let layer = graph_modification_utils::new_custom(NodeId(generate_uuid()), nodes, parent, responses);
tool_options.fill.apply_fill(layer, responses);
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, responses);
tool_data.layer = Some(layer);
responses.add(Message::StartBuffer);
responses.add(PenToolMessage::DragStart);
return PenToolFsmState::Ready;
}
tool_data.handle_end = None;
// Enter the dragging handle state while the mouse is held down, allowing the user to move the mouse and position the handle
PenToolFsmState::DraggingHandle
}
@@ -265,6 +265,7 @@ impl Fsm for PolygonToolFsmState {
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId(generate_uuid()), nodes, document.new_layer_parent(false), responses);
responses.add(Message::StartBuffer);
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., input.mouse.position),
@@ -212,6 +212,7 @@ impl Fsm for RectangleToolFsmState {
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId(generate_uuid()), nodes, document.new_layer_parent(true), responses);
responses.add(Message::StartBuffer);
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., input.mouse.position),
@@ -205,14 +205,6 @@ impl Fsm for SplineToolFsmState {
responses.add(DocumentMessage::DeselectAllLayers);
let parent = document.new_layer_parent(true);
let transform = document.metadata().transform_to_viewport(parent);
let snapped_position = input.mouse.position;
let pos = transform.inverse().transform_point2(snapped_position);
tool_data.points.push(pos);
tool_data.next_point = pos;
tool_data.weight = tool_options.line_weight;
@@ -225,6 +217,8 @@ impl Fsm for SplineToolFsmState {
tool_options.stroke.apply_stroke(tool_data.weight, layer, responses);
tool_data.layer = Some(layer);
responses.add(Message::StartBuffer);
SplineToolFsmState::Drawing
}
(SplineToolFsmState::Drawing, SplineToolMessage::DragStop) => {
@@ -237,11 +231,9 @@ impl Fsm for SplineToolFsmState {
let transform = document.metadata().transform_to_viewport(layer);
let pos = transform.inverse().transform_point2(snapped_position);
if let Some(last_pos) = tool_data.points.last() {
if last_pos.distance(pos) > DRAG_THRESHOLD {
tool_data.points.push(pos);
tool_data.next_point = pos;
}
if tool_data.points.last().map_or(true, |last_pos| last_pos.distance(pos) > DRAG_THRESHOLD) {
tool_data.points.push(pos);
tool_data.next_point = pos;
}
update_spline(document, tool_data, true, responses);
@@ -213,11 +213,7 @@ struct TextToolData {
impl TextToolData {
/// Set the editing state of the currently modifying layer
fn set_editing(&self, editable: bool, font_cache: &FontCache, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
if let Some(node_id) = graph_modification_utils::get_fill_id(self.layer, &document.network_interface) {
responses.add(NodeGraphMessage::SetVisibility { node_id, visible: !editable });
}
fn set_editing(&self, editable: bool, font_cache: &FontCache, responses: &mut VecDeque<Message>) {
if let Some(editing_text) = self.editing_text.as_ref().filter(|_| editable) {
responses.add(FrontendMessage::DisplayEditableTextbox {
text: editing_text.text.clone(),
@@ -229,6 +225,8 @@ impl TextToolData {
});
} else {
responses.add(FrontendMessage::DisplayRemoveEditableTextbox);
// Clear all selected nodes when no longer editing
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: Vec::new() });
}
}
@@ -253,17 +251,23 @@ impl TextToolData {
}
if tool_state == TextToolFsmState::Editing {
self.set_editing(false, font_cache, document, responses);
self.set_editing(false, font_cache, responses);
}
self.layer = layer;
self.load_layer_text_node(document);
if self.load_layer_text_node(document).is_some() {
responses.add(DocumentMessage::AddTransaction);
responses.add(DocumentMessage::AddTransaction);
self.set_editing(true, font_cache, responses);
self.set_editing(true, font_cache, document, responses);
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![self.layer.to_node()] });
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![self.layer.to_node()] });
// Make the rendered text invisible while editing
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(graph_modification_utils::get_text_id(self.layer, &document.network_interface).unwrap(), 1),
input: NodeInput::value(TaggedValue::String("".to_string()), false),
});
responses.add(NodeGraphMessage::RunDocumentGraph);
};
}
fn interact(
@@ -294,6 +298,7 @@ impl TextToolData {
parent: document.new_layer_parent(true),
insert_index: 0,
});
responses.add(Message::StartBuffer);
responses.add(GraphOperationMessage::FillSet {
layer: self.layer,
fill: if editing_text.color.is_some() { Fill::Solid(editing_text.color.unwrap()) } else { Fill::None },
@@ -305,14 +310,15 @@ impl TextToolData {
skip_rerender: true,
});
self.set_editing(true, font_cache, document, responses);
self.set_editing(true, font_cache, responses);
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![self.layer.to_node()] });
responses.add(NodeGraphMessage::RunDocumentGraph);
TextToolFsmState::Editing
} else {
// Removing old text as editable
self.set_editing(false, font_cache, document, responses);
self.set_editing(false, font_cache, responses);
TextToolFsmState::Ready
}
@@ -404,7 +410,7 @@ impl Fsm for TextToolFsmState {
}
(state, TextToolMessage::Abort) => {
if state == TextToolFsmState::Editing {
tool_data.set_editing(false, font_cache, document, responses);
tool_data.set_editing(false, font_cache, responses);
}
TextToolFsmState::Ready
@@ -415,12 +421,13 @@ impl Fsm for TextToolFsmState {
TextToolFsmState::Editing
}
(TextToolFsmState::Editing, TextToolMessage::TextChange { new_text }) => {
tool_data.set_editing(false, font_cache, responses);
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(graph_modification_utils::get_text_id(tool_data.layer, &document.network_interface).unwrap(), 1),
input: NodeInput::value(TaggedValue::String(new_text), false),
});
tool_data.set_editing(false, font_cache, document, responses);
responses.add(NodeGraphMessage::RunDocumentGraph);
TextToolFsmState::Ready
}