From 87e550de17edbe3449ade70275028606d1d92474 Mon Sep 17 00:00:00 2001 From: 0HyperCube <78500760+0HyperCube@users.noreply.github.com> Date: Wed, 28 Dec 2022 21:07:10 +0000 Subject: [PATCH] Only open the node graph panel after drawing a new frame to avoid layout shift interruption (#924) * Store drag start as document position * Don't open graph whilst drawing * Rename to is_drawing_node_graph_frame Co-authored-by: Keavon Chambers --- .../document/document_message_handler.rs | 3 +- .../document/node_graph/node_graph_message.rs | 3 ++ .../node_graph/node_graph_message_handler.rs | 39 +++++++++++++++++-- .../tool/common_functionality/resize.rs | 13 +++++-- .../src/messages/tool/tool_message_handler.rs | 3 ++ .../tool/tool_messages/ellipse_tool.rs | 2 +- .../tool/tool_messages/imaginate_tool.rs | 6 ++- .../tool_messages/node_graph_frame_tool.rs | 5 ++- .../tool/tool_messages/rectangle_tool.rs | 2 +- .../messages/tool/tool_messages/shape_tool.rs | 2 +- 10 files changed, 66 insertions(+), 12 deletions(-) diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 3be6f50a..cd446e58 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -175,7 +175,8 @@ impl MessageHandler { - self.node_graph_handler.process_message(message, (&mut self.document_legacy, ipp), responses); + let selected_layers = &mut self.layer_metadata.iter().filter_map(|(path, data)| data.selected.then_some(path.as_slice())); + self.node_graph_handler.process_message(message, (&mut self.document_legacy, selected_layers), responses); } // Messages diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs index 53d81162..e6eb0d93 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs @@ -56,6 +56,9 @@ pub enum NodeGraphMessage { SelectNodes { nodes: Vec, }, + SetDrawing { + new_drawing: bool, + }, SetInputValue { node: NodeId, input_index: usize, diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index 6b9f487b..a86ecba5 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -4,8 +4,9 @@ use crate::messages::layout::utility_types::widgets::button_widgets::{Breadcrumb use crate::messages::prelude::*; use document_legacy::document::Document; -use document_legacy::layers::layer_info::LayerDataType; +use document_legacy::layers::layer_info::{LayerDataType, LayerDataTypeDiscriminant}; use document_legacy::layers::nodegraph_layer::NodeGraphFrameLayer; +use document_legacy::LayerId; use graph_craft::document::value::TaggedValue; use graph_craft::document::{DocumentNode, DocumentNodeImplementation, DocumentNodeMetadata, NodeId, NodeInput, NodeNetwork}; @@ -104,6 +105,9 @@ pub struct NodeGraphMessageHandler { pub selected_nodes: Vec, #[serde(skip)] pub widgets: [LayoutGroup; 2], + /// Do not allow the node graph window to open or close whilst the user is drawing a node graph frame + #[serde(skip)] + pub is_drawing_node_graph_frame: bool, } impl NodeGraphMessageHandler { @@ -388,12 +392,17 @@ impl NodeGraphMessageHandler { } } -impl MessageHandler for NodeGraphMessageHandler { +impl MessageHandler)> for NodeGraphMessageHandler { #[remain::check] - fn process_message(&mut self, message: NodeGraphMessage, (document, _ipp): (&mut Document, &InputPreprocessorMessageHandler), responses: &mut VecDeque) { + fn process_message(&mut self, message: NodeGraphMessage, (document, selected): (&mut Document, &mut dyn Iterator), responses: &mut VecDeque) { #[remain::sorted] match message { NodeGraphMessage::CloseNodeGraph => { + // Don't close when drawing a node graph frame + if self.is_drawing_node_graph_frame { + return; + } + if let Some(_old_layer_path) = self.layer_path.take() { responses.push_back(FrontendMessage::UpdateNodeGraphVisibility { visible: false }.into()); responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into()); @@ -607,6 +616,11 @@ impl MessageHandler { + // Don't open when drawing a node graph frame + if self.is_drawing_node_graph_frame { + return; + } + if let Some(_old_layer_path) = self.layer_path.replace(layer_path) { // TODO: Necessary cleanup of old node graph } @@ -671,6 +685,25 @@ impl MessageHandler { + let selected: Vec<_> = selected.collect(); + // Check if we stopped drawing a node graph frame + if self.is_drawing_node_graph_frame && !new_drawing { + // Check if we should open or close the node graph + if selected.len() == 1 + && document + .layer(selected[0]) + .ok() + .filter(|layer| LayerDataTypeDiscriminant::from(&layer.data) == LayerDataTypeDiscriminant::NodeGraphFrame) + .is_some() + { + responses.push_back(NodeGraphMessage::OpenNodeGraph { layer_path: selected[0].to_vec() }.into()); + } else { + responses.push_back(NodeGraphMessage::CloseNodeGraph.into()); + } + } + self.is_drawing_node_graph_frame = new_drawing + } NodeGraphMessage::SetInputValue { node, input_index, value } => { if let Some(network) = self.get_active_network_mut(document) { if let Some(node) = network.nodes.get_mut(&node) { diff --git a/editor/src/messages/tool/common_functionality/resize.rs b/editor/src/messages/tool/common_functionality/resize.rs index c942c14d..8261a527 100644 --- a/editor/src/messages/tool/common_functionality/resize.rs +++ b/editor/src/messages/tool/common_functionality/resize.rs @@ -11,7 +11,7 @@ use glam::{DAffine2, DVec2, Vec2Swizzles}; #[derive(Clone, Debug, Default)] pub struct Resize { - pub drag_start: ViewportPosition, + drag_start: ViewportPosition, pub path: Option>, snap_manager: SnapManager, } @@ -21,7 +21,14 @@ impl Resize { pub fn start(&mut self, responses: &mut VecDeque, document: &DocumentMessageHandler, mouse_position: DVec2, font_cache: &FontCache) { self.snap_manager.start_snap(document, document.bounding_boxes(None, None, font_cache), true, true); self.snap_manager.add_all_document_handles(document, &[], &[], &[]); - self.drag_start = self.snap_manager.snap_position(responses, document, mouse_position); + let root_transform = document.document_legacy.root.transform; + self.drag_start = root_transform.inverse().transform_point2(self.snap_manager.snap_position(responses, document, mouse_position)); + } + + /// Calculate the drag start position in viewport space. + pub fn viewport_drag_start(&self, document: &DocumentMessageHandler) -> DVec2 { + let root_transform = document.document_legacy.root.transform; + root_transform.transform_point2(self.drag_start) } pub fn calculate_transform( @@ -33,7 +40,7 @@ impl Resize { ipp: &InputPreprocessorMessageHandler, ) -> Option { if let Some(path) = &self.path { - let mut start = self.drag_start; + let mut start = self.viewport_drag_start(document); let stop = self.snap_manager.snap_position(responses, document, ipp.mouse.position); diff --git a/editor/src/messages/tool/tool_message_handler.rs b/editor/src/messages/tool/tool_message_handler.rs index f8c928c4..cede64b4 100644 --- a/editor/src/messages/tool/tool_message_handler.rs +++ b/editor/src/messages/tool/tool_message_handler.rs @@ -105,6 +105,9 @@ impl MessageHandler { let tool_data = &mut self.tool_state.tool_data; diff --git a/editor/src/messages/tool/tool_messages/ellipse_tool.rs b/editor/src/messages/tool/tool_messages/ellipse_tool.rs index c04ace36..dc52d6ed 100644 --- a/editor/src/messages/tool/tool_messages/ellipse_tool.rs +++ b/editor/src/messages/tool/tool_messages/ellipse_tool.rs @@ -159,7 +159,7 @@ impl Fsm for EllipseToolFsmState { state } (Drawing, DragStop) => { - match shape_data.drag_start.distance(input.mouse.position) <= DRAG_THRESHOLD { + match shape_data.viewport_drag_start(document).distance(input.mouse.position) <= DRAG_THRESHOLD { true => responses.push_back(DocumentMessage::AbortTransaction.into()), false => responses.push_back(DocumentMessage::CommitTransaction.into()), } diff --git a/editor/src/messages/tool/tool_messages/imaginate_tool.rs b/editor/src/messages/tool/tool_messages/imaginate_tool.rs index ad54f961..94163a5e 100644 --- a/editor/src/messages/tool/tool_messages/imaginate_tool.rs +++ b/editor/src/messages/tool/tool_messages/imaginate_tool.rs @@ -135,6 +135,7 @@ impl Fsm for ImaginateToolFsmState { (Ready, DragStart) => { shape_data.start(responses, document, input.mouse.position, font_cache); responses.push_back(DocumentMessage::StartTransaction.into()); + responses.push_back(NodeGraphMessage::SetDrawing { new_drawing: true }.into()); shape_data.path = Some(document.get_path_for_new_layer()); responses.push_back(DocumentMessage::DeselectAllLayers.into()); @@ -221,11 +222,12 @@ impl Fsm for ImaginateToolFsmState { state } (Drawing, DragStop) => { - match shape_data.drag_start.distance(input.mouse.position) <= DRAG_THRESHOLD { + match shape_data.viewport_drag_start(document).distance(input.mouse.position) <= DRAG_THRESHOLD { true => responses.push_back(DocumentMessage::AbortTransaction.into()), false => responses.push_back(DocumentMessage::CommitTransaction.into()), } + responses.push_back(NodeGraphMessage::SetDrawing { new_drawing: false }.into()); shape_data.cleanup(responses); Ready @@ -233,6 +235,8 @@ impl Fsm for ImaginateToolFsmState { (Drawing, Abort) => { responses.push_back(DocumentMessage::AbortTransaction.into()); + responses.push_back(NodeGraphMessage::SetDrawing { new_drawing: false }.into()); + shape_data.cleanup(responses); Ready diff --git a/editor/src/messages/tool/tool_messages/node_graph_frame_tool.rs b/editor/src/messages/tool/tool_messages/node_graph_frame_tool.rs index 1d194180..57baa178 100644 --- a/editor/src/messages/tool/tool_messages/node_graph_frame_tool.rs +++ b/editor/src/messages/tool/tool_messages/node_graph_frame_tool.rs @@ -134,6 +134,7 @@ impl Fsm for NodeGraphToolFsmState { (Ready, DragStart) => { shape_data.start(responses, document, input.mouse.position, font_cache); responses.push_back(DocumentMessage::StartTransaction.into()); + responses.push_back(NodeGraphMessage::SetDrawing { new_drawing: true }.into()); shape_data.path = Some(document.get_path_for_new_layer()); responses.push_back(DocumentMessage::DeselectAllLayers.into()); @@ -186,17 +187,19 @@ impl Fsm for NodeGraphToolFsmState { state } (Drawing, DragStop) => { - match shape_data.drag_start.distance(input.mouse.position) <= DRAG_THRESHOLD { + match shape_data.viewport_drag_start(document).distance(input.mouse.position) <= DRAG_THRESHOLD { true => responses.push_back(DocumentMessage::AbortTransaction.into()), false => responses.push_back(DocumentMessage::CommitTransaction.into()), } + responses.push_back(NodeGraphMessage::SetDrawing { new_drawing: false }.into()); shape_data.cleanup(responses); Ready } (Drawing, Abort) => { responses.push_back(DocumentMessage::AbortTransaction.into()); + responses.push_back(NodeGraphMessage::SetDrawing { new_drawing: false }.into()); shape_data.cleanup(responses); diff --git a/editor/src/messages/tool/tool_messages/rectangle_tool.rs b/editor/src/messages/tool/tool_messages/rectangle_tool.rs index 7052044e..61046f7a 100644 --- a/editor/src/messages/tool/tool_messages/rectangle_tool.rs +++ b/editor/src/messages/tool/tool_messages/rectangle_tool.rs @@ -158,7 +158,7 @@ impl Fsm for RectangleToolFsmState { state } (Drawing, DragStop) => { - match shape_data.drag_start.distance(input.mouse.position) <= DRAG_THRESHOLD { + match shape_data.viewport_drag_start(document).distance(input.mouse.position) <= DRAG_THRESHOLD { true => responses.push_back(DocumentMessage::AbortTransaction.into()), false => responses.push_back(DocumentMessage::CommitTransaction.into()), } diff --git a/editor/src/messages/tool/tool_messages/shape_tool.rs b/editor/src/messages/tool/tool_messages/shape_tool.rs index 1ae93860..65f48e73 100644 --- a/editor/src/messages/tool/tool_messages/shape_tool.rs +++ b/editor/src/messages/tool/tool_messages/shape_tool.rs @@ -201,7 +201,7 @@ impl Fsm for ShapeToolFsmState { state } (Drawing, DragStop) => { - match shape_data.drag_start.distance(input.mouse.position) <= DRAG_THRESHOLD { + match shape_data.viewport_drag_start(document).distance(input.mouse.position) <= DRAG_THRESHOLD { true => responses.push_back(DocumentMessage::AbortTransaction.into()), false => responses.push_back(DocumentMessage::CommitTransaction.into()), }