mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-06 15:08:12 +08:00
Fix wires on document change and errors on hidden nodes (#2897)
* Fix wires on document change and errors on hidden nodes * Code cleanup
This commit is contained in:
@@ -182,8 +182,6 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
device_pixel_ratio,
|
device_pixel_ratio,
|
||||||
} = context;
|
} = context;
|
||||||
|
|
||||||
let selected_nodes_bounding_box_viewport = self.network_interface.selected_nodes_bounding_box_viewport(&self.breadcrumb_network_path);
|
|
||||||
let selected_visible_layers_bounding_box_viewport = self.selected_visible_layers_bounding_box_viewport();
|
|
||||||
match message {
|
match message {
|
||||||
// Sub-messages
|
// Sub-messages
|
||||||
DocumentMessage::Navigation(message) => {
|
DocumentMessage::Navigation(message) => {
|
||||||
@@ -191,11 +189,6 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
network_interface: &mut self.network_interface,
|
network_interface: &mut self.network_interface,
|
||||||
breadcrumb_network_path: &self.breadcrumb_network_path,
|
breadcrumb_network_path: &self.breadcrumb_network_path,
|
||||||
ipp,
|
ipp,
|
||||||
selection_bounds: if self.graph_view_overlay_open {
|
|
||||||
selected_nodes_bounding_box_viewport
|
|
||||||
} else {
|
|
||||||
selected_visible_layers_bounding_box_viewport
|
|
||||||
},
|
|
||||||
document_ptz: &mut self.document_ptz,
|
document_ptz: &mut self.document_ptz,
|
||||||
graph_view_overlay_open: self.graph_view_overlay_open,
|
graph_view_overlay_open: self.graph_view_overlay_open,
|
||||||
preferences,
|
preferences,
|
||||||
@@ -259,7 +252,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
AlignAxis::X => DVec2::X,
|
AlignAxis::X => DVec2::X,
|
||||||
AlignAxis::Y => DVec2::Y,
|
AlignAxis::Y => DVec2::Y,
|
||||||
};
|
};
|
||||||
let Some(combined_box) = self.selected_visible_layers_bounding_box_viewport() else {
|
let Some(combined_box) = self.network_interface.selected_layers_artwork_bounding_box_viewport() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -486,7 +479,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
FlipAxis::X => DVec2::new(-1., 1.),
|
FlipAxis::X => DVec2::new(-1., 1.),
|
||||||
FlipAxis::Y => DVec2::new(1., -1.),
|
FlipAxis::Y => DVec2::new(1., -1.),
|
||||||
};
|
};
|
||||||
if let Some([min, max]) = self.selected_visible_and_unlock_layers_bounding_box_viewport() {
|
if let Some([min, max]) = self.network_interface.selected_unlocked_layers_bounding_box_viewport() {
|
||||||
let center = (max + min) / 2.;
|
let center = (max + min) / 2.;
|
||||||
let bbox_trans = DAffine2::from_translation(-center);
|
let bbox_trans = DAffine2::from_translation(-center);
|
||||||
let mut added_transaction = false;
|
let mut added_transaction = false;
|
||||||
@@ -506,7 +499,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
}
|
}
|
||||||
DocumentMessage::RotateSelectedLayers { degrees } => {
|
DocumentMessage::RotateSelectedLayers { degrees } => {
|
||||||
// Get the bounding box of selected layers in viewport space
|
// Get the bounding box of selected layers in viewport space
|
||||||
if let Some([min, max]) = self.selected_visible_and_unlock_layers_bounding_box_viewport() {
|
if let Some([min, max]) = self.network_interface.selected_unlocked_layers_bounding_box_viewport() {
|
||||||
// Calculate the center of the bounding box to use as rotation pivot
|
// Calculate the center of the bounding box to use as rotation pivot
|
||||||
let center = (max + min) / 2.;
|
let center = (max + min) / 2.;
|
||||||
// Transform that moves pivot point to origin
|
// Transform that moves pivot point to origin
|
||||||
@@ -1063,13 +1056,13 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
self.selected_layers_reorder(relative_index_offset, responses);
|
self.selected_layers_reorder(relative_index_offset, responses);
|
||||||
}
|
}
|
||||||
DocumentMessage::ClipLayer { id } => {
|
DocumentMessage::ClipLayer { id } => {
|
||||||
let layer = LayerNodeIdentifier::new(id, &self.network_interface, &[]);
|
let layer = LayerNodeIdentifier::new(id, &self.network_interface);
|
||||||
|
|
||||||
responses.add(DocumentMessage::AddTransaction);
|
responses.add(DocumentMessage::AddTransaction);
|
||||||
responses.add(GraphOperationMessage::ClipModeToggle { layer });
|
responses.add(GraphOperationMessage::ClipModeToggle { layer });
|
||||||
}
|
}
|
||||||
DocumentMessage::SelectLayer { id, ctrl, shift } => {
|
DocumentMessage::SelectLayer { id, ctrl, shift } => {
|
||||||
let layer = LayerNodeIdentifier::new(id, &self.network_interface, &[]);
|
let layer = LayerNodeIdentifier::new(id, &self.network_interface);
|
||||||
|
|
||||||
let mut nodes = vec![];
|
let mut nodes = vec![];
|
||||||
|
|
||||||
@@ -1266,7 +1259,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
responses.add(OverlaysMessage::Draw);
|
responses.add(OverlaysMessage::Draw);
|
||||||
}
|
}
|
||||||
DocumentMessage::ToggleLayerExpansion { id, recursive } => {
|
DocumentMessage::ToggleLayerExpansion { id, recursive } => {
|
||||||
let layer = LayerNodeIdentifier::new(id, &self.network_interface, &[]);
|
let layer = LayerNodeIdentifier::new(id, &self.network_interface);
|
||||||
let metadata = self.metadata();
|
let metadata = self.metadata();
|
||||||
|
|
||||||
let is_collapsed = self.collapsed.0.contains(&layer);
|
let is_collapsed = self.collapsed.0.contains(&layer);
|
||||||
@@ -1323,7 +1316,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||||||
self.network_interface.document_network().nodes.contains_key(node_id))
|
self.network_interface.document_network().nodes.contains_key(node_id))
|
||||||
.filter_map(|(node_id, click_targets)| {
|
.filter_map(|(node_id, click_targets)| {
|
||||||
self.network_interface.is_layer(&node_id, &[]).then(|| {
|
self.network_interface.is_layer(&node_id, &[]).then(|| {
|
||||||
let layer = LayerNodeIdentifier::new(node_id, &self.network_interface, &[]);
|
let layer = LayerNodeIdentifier::new(node_id, &self.network_interface);
|
||||||
(layer, click_targets)
|
(layer, click_targets)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1708,31 +1701,6 @@ impl DocumentMessageHandler {
|
|||||||
.last()
|
.last()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the combined bounding box of the click targets of the selected visible layers in viewport space
|
|
||||||
pub fn selected_visible_layers_bounding_box_viewport(&self) -> Option<[DVec2; 2]> {
|
|
||||||
self.network_interface
|
|
||||||
.selected_nodes()
|
|
||||||
.selected_visible_layers(&self.network_interface)
|
|
||||||
.filter_map(|layer| self.metadata().bounding_box_viewport(layer))
|
|
||||||
.reduce(graphene_std::renderer::Quad::combine_bounds)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn selected_visible_and_unlock_layers_bounding_box_viewport(&self) -> Option<[DVec2; 2]> {
|
|
||||||
self.network_interface
|
|
||||||
.selected_nodes()
|
|
||||||
.selected_visible_and_unlocked_layers(&self.network_interface)
|
|
||||||
.filter_map(|layer| self.metadata().bounding_box_viewport(layer))
|
|
||||||
.reduce(graphene_std::renderer::Quad::combine_bounds)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn selected_visible_and_unlock_layers_bounding_box_document(&self) -> Option<[DVec2; 2]> {
|
|
||||||
self.network_interface
|
|
||||||
.selected_nodes()
|
|
||||||
.selected_visible_and_unlocked_layers(&self.network_interface)
|
|
||||||
.map(|layer| self.metadata().nonzero_bounding_box(layer))
|
|
||||||
.reduce(graphene_std::renderer::Quad::combine_bounds)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn document_network(&self) -> &NodeNetwork {
|
pub fn document_network(&self) -> &NodeNetwork {
|
||||||
self.network_interface.document_network()
|
self.network_interface.document_network()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -119,7 +119,7 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageContext<'_>> for
|
|||||||
let primary_input = artboard.inputs.first().expect("Artboard should have a primary input").clone();
|
let primary_input = artboard.inputs.first().expect("Artboard should have a primary input").clone();
|
||||||
if let NodeInput::Node { node_id, .. } = &primary_input {
|
if let NodeInput::Node { node_id, .. } = &primary_input {
|
||||||
if network_interface.is_layer(node_id, &[]) && !network_interface.is_artboard(node_id, &[]) {
|
if network_interface.is_layer(node_id, &[]) && !network_interface.is_artboard(node_id, &[]) {
|
||||||
network_interface.move_layer_to_stack(LayerNodeIdentifier::new(*node_id, network_interface, &[]), artboard_layer, 0, &[]);
|
network_interface.move_layer_to_stack(LayerNodeIdentifier::new(*node_id, network_interface), artboard_layer, 0, &[]);
|
||||||
} else {
|
} else {
|
||||||
network_interface.disconnect_input(&InputConnector::node(artboard_layer.to_node(), 0), &[]);
|
network_interface.disconnect_input(&InputConnector::node(artboard_layer.to_node(), 0), &[]);
|
||||||
network_interface.set_input(&InputConnector::node(id, 0), primary_input, &[]);
|
network_interface.set_input(&InputConnector::node(id, 0), primary_input, &[]);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ impl<'a> ModifyInputsContext<'a> {
|
|||||||
pub fn create_layer(&mut self, new_id: NodeId) -> LayerNodeIdentifier {
|
pub fn create_layer(&mut self, new_id: NodeId) -> LayerNodeIdentifier {
|
||||||
let new_merge_node = resolve_document_node_type("Merge").expect("Merge node").default_node_template();
|
let new_merge_node = resolve_document_node_type("Merge").expect("Merge node").default_node_template();
|
||||||
self.network_interface.insert_node(new_id, new_merge_node, &[]);
|
self.network_interface.insert_node(new_id, new_merge_node, &[]);
|
||||||
LayerNodeIdentifier::new(new_id, self.network_interface, &[])
|
LayerNodeIdentifier::new(new_id, self.network_interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an artboard as the primary export for the document network
|
/// Creates an artboard as the primary export for the document network
|
||||||
@@ -138,7 +138,7 @@ impl<'a> ModifyInputsContext<'a> {
|
|||||||
Some(NodeInput::value(TaggedValue::Bool(artboard.clip), false)),
|
Some(NodeInput::value(TaggedValue::Bool(artboard.clip), false)),
|
||||||
]);
|
]);
|
||||||
self.network_interface.insert_node(new_id, artboard_node_template, &[]);
|
self.network_interface.insert_node(new_id, artboard_node_template, &[]);
|
||||||
LayerNodeIdentifier::new(new_id, self.network_interface, &[])
|
LayerNodeIdentifier::new(new_id, self.network_interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_boolean_data(&mut self, operation: graphene_std::path_bool::BooleanOperation, layer: LayerNodeIdentifier) {
|
pub fn insert_boolean_data(&mut self, operation: graphene_std::path_bool::BooleanOperation, layer: LayerNodeIdentifier) {
|
||||||
@@ -236,7 +236,7 @@ impl<'a> ModifyInputsContext<'a> {
|
|||||||
self.layer_node.or_else(|| {
|
self.layer_node.or_else(|| {
|
||||||
let export_node = self.network_interface.document_network().exports.first().and_then(|export| export.as_node())?;
|
let export_node = self.network_interface.document_network().exports.first().and_then(|export| export.as_node())?;
|
||||||
if self.network_interface.is_layer(&export_node, &[]) {
|
if self.network_interface.is_layer(&export_node, &[]) {
|
||||||
Some(LayerNodeIdentifier::new(export_node, self.network_interface, &[]))
|
Some(LayerNodeIdentifier::new(export_node, self.network_interface))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ pub struct NavigationMessageContext<'a> {
|
|||||||
pub network_interface: &'a mut NodeNetworkInterface,
|
pub network_interface: &'a mut NodeNetworkInterface,
|
||||||
pub breadcrumb_network_path: &'a [NodeId],
|
pub breadcrumb_network_path: &'a [NodeId],
|
||||||
pub ipp: &'a InputPreprocessorMessageHandler,
|
pub ipp: &'a InputPreprocessorMessageHandler,
|
||||||
pub selection_bounds: Option<[DVec2; 2]>,
|
|
||||||
pub document_ptz: &'a mut PTZ,
|
pub document_ptz: &'a mut PTZ,
|
||||||
pub graph_view_overlay_open: bool,
|
pub graph_view_overlay_open: bool,
|
||||||
pub preferences: &'a PreferencesMessageHandler,
|
pub preferences: &'a PreferencesMessageHandler,
|
||||||
@@ -39,7 +38,6 @@ impl MessageHandler<NavigationMessage, NavigationMessageContext<'_>> for Navigat
|
|||||||
network_interface,
|
network_interface,
|
||||||
breadcrumb_network_path,
|
breadcrumb_network_path,
|
||||||
ipp,
|
ipp,
|
||||||
selection_bounds,
|
|
||||||
document_ptz,
|
document_ptz,
|
||||||
graph_view_overlay_open,
|
graph_view_overlay_open,
|
||||||
preferences,
|
preferences,
|
||||||
@@ -386,9 +384,16 @@ impl MessageHandler<NavigationMessage, NavigationMessageContext<'_>> for Navigat
|
|||||||
responses.add(DocumentMessage::PTZUpdate);
|
responses.add(DocumentMessage::PTZUpdate);
|
||||||
responses.add(NodeGraphMessage::SetGridAlignedEdges);
|
responses.add(NodeGraphMessage::SetGridAlignedEdges);
|
||||||
}
|
}
|
||||||
|
// Fully zooms in on the selected
|
||||||
NavigationMessage::FitViewportToSelection => {
|
NavigationMessage::FitViewportToSelection => {
|
||||||
|
let selection_bounds = if graph_view_overlay_open {
|
||||||
|
network_interface.selected_nodes_bounding_box_viewport(breadcrumb_network_path)
|
||||||
|
} else {
|
||||||
|
network_interface.selected_layers_artwork_bounding_box_viewport()
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(bounds) = selection_bounds {
|
if let Some(bounds) = selection_bounds {
|
||||||
let Some(ptz) = get_ptz_mut(document_ptz, network_interface, graph_view_overlay_open, breadcrumb_network_path) else {
|
let Some(ptz) = get_ptz(document_ptz, network_interface, graph_view_overlay_open, breadcrumb_network_path) else {
|
||||||
log::error!("Could not get node graph PTZ in FitViewportToSelection");
|
log::error!("Could not get node graph PTZ in FitViewportToSelection");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1387,6 +1387,11 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
if node_bbox[1].x >= document_bbox[0].x && node_bbox[0].x <= document_bbox[1].x && node_bbox[1].y >= document_bbox[0].y && node_bbox[0].y <= document_bbox[1].y {
|
if node_bbox[1].x >= document_bbox[0].x && node_bbox[0].x <= document_bbox[1].x && node_bbox[1].y >= document_bbox[0].y && node_bbox[0].y <= document_bbox[1].y {
|
||||||
nodes.push(*node_id);
|
nodes.push(*node_id);
|
||||||
}
|
}
|
||||||
|
for error in &self.node_graph_errors {
|
||||||
|
if error.node_path.contains(node_id) {
|
||||||
|
nodes.push(*node_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.add(FrontendMessage::UpdateVisibleNodes { nodes });
|
responses.add(FrontendMessage::UpdateVisibleNodes { nodes });
|
||||||
@@ -2399,19 +2404,19 @@ impl NodeGraphMessageHandler {
|
|||||||
let mut ancestors_of_selected = HashSet::new();
|
let mut ancestors_of_selected = HashSet::new();
|
||||||
let mut descendants_of_selected = HashSet::new();
|
let mut descendants_of_selected = HashSet::new();
|
||||||
for selected_layer in &selected_layers {
|
for selected_layer in &selected_layers {
|
||||||
for ancestor in LayerNodeIdentifier::new(*selected_layer, network_interface, &[]).ancestors(network_interface.document_metadata()) {
|
for ancestor in LayerNodeIdentifier::new(*selected_layer, network_interface).ancestors(network_interface.document_metadata()) {
|
||||||
if ancestor != LayerNodeIdentifier::ROOT_PARENT && ancestor.to_node() != *selected_layer {
|
if ancestor != LayerNodeIdentifier::ROOT_PARENT && ancestor.to_node() != *selected_layer {
|
||||||
ancestors_of_selected.insert(ancestor.to_node());
|
ancestors_of_selected.insert(ancestor.to_node());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for descendant in LayerNodeIdentifier::new(*selected_layer, network_interface, &[]).descendants(network_interface.document_metadata()) {
|
for descendant in LayerNodeIdentifier::new(*selected_layer, network_interface).descendants(network_interface.document_metadata()) {
|
||||||
descendants_of_selected.insert(descendant.to_node());
|
descendants_of_selected.insert(descendant.to_node());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (&node_id, node_metadata) in &network_interface.document_network_metadata().persistent_metadata.node_metadata {
|
for (&node_id, node_metadata) in &network_interface.document_network_metadata().persistent_metadata.node_metadata {
|
||||||
if node_metadata.persistent_metadata.is_layer() {
|
if node_metadata.persistent_metadata.is_layer() {
|
||||||
let layer = LayerNodeIdentifier::new(node_id, network_interface, &[]);
|
let layer = LayerNodeIdentifier::new(node_id, network_interface);
|
||||||
|
|
||||||
let children_allowed =
|
let children_allowed =
|
||||||
// The layer has other layers as children along the secondary input's horizontal flow
|
// The layer has other layers as children along the secondary input's horizontal flow
|
||||||
|
|||||||
@@ -250,12 +250,8 @@ impl LayerNodeIdentifier {
|
|||||||
|
|
||||||
/// Construct a [`LayerNodeIdentifier`], debug asserting that it is a layer node. This should only be used in the document network since the structure is not loaded in nested networks.
|
/// Construct a [`LayerNodeIdentifier`], debug asserting that it is a layer node. This should only be used in the document network since the structure is not loaded in nested networks.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn new(node_id: NodeId, network_interface: &NodeNetworkInterface, network_path: &[NodeId]) -> Self {
|
pub fn new(node_id: NodeId, network_interface: &NodeNetworkInterface) -> Self {
|
||||||
debug_assert!(
|
debug_assert!(network_interface.is_layer(&node_id, &[]), "Layer identifier constructed from non-layer node {node_id}",);
|
||||||
network_interface.is_layer(&node_id, network_path),
|
|
||||||
"Layer identifier constructed from non-layer node {node_id}: {:#?}",
|
|
||||||
network_interface.nested_network(network_path).unwrap().nodes.get(&node_id)
|
|
||||||
);
|
|
||||||
Self::new_unchecked(node_id)
|
Self::new_unchecked(node_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,12 +203,12 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first downstream layer(inclusive) from a node. If the node is a layer, it will return itself.
|
/// Returns the first downstream layer(inclusive) from a node. If the node is a layer, it will return itself.
|
||||||
pub fn downstream_layer(&mut self, node_id: &NodeId, network_path: &[NodeId]) -> Option<LayerNodeIdentifier> {
|
pub fn downstream_layer_for_chain_node(&mut self, node_id: &NodeId, network_path: &[NodeId]) -> Option<NodeId> {
|
||||||
let mut id = *node_id;
|
let mut id = *node_id;
|
||||||
while !self.is_layer(&id, network_path) {
|
while !self.is_layer(&id, network_path) {
|
||||||
id = self.outward_wires(network_path)?.get(&OutputConnector::node(id, 0))?.first()?.node_id()?;
|
id = self.outward_wires(network_path)?.get(&OutputConnector::node(id, 0))?.first()?.node_id()?;
|
||||||
}
|
}
|
||||||
Some(LayerNodeIdentifier::new(id, self, network_path))
|
Some(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all downstream layers (inclusive) from a node. If the node is a layer, it will return itself.
|
/// Returns all downstream layers (inclusive) from a node. If the node is a layer, it will return itself.
|
||||||
@@ -388,8 +388,8 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a chain node does not have a selected downstream layer, then set the position to absolute
|
// If a chain node does not have a selected downstream layer, then set the position to absolute
|
||||||
let downstream_layer = self.downstream_layer(node_id, network_path);
|
let downstream_layer = self.downstream_layer_for_chain_node(node_id, network_path);
|
||||||
if downstream_layer.is_none_or(|downstream_layer| new_ids.keys().all(|key| *key != downstream_layer.to_node())) {
|
if downstream_layer.is_none_or(|downstream_layer| new_ids.keys().all(|key| *key != downstream_layer)) {
|
||||||
let Some(position) = self.position(node_id, network_path) else {
|
let Some(position) = self.position(node_id, network_path) else {
|
||||||
log::error!("Could not get position in create_node_template");
|
log::error!("Could not get position in create_node_template");
|
||||||
return None;
|
return None;
|
||||||
@@ -1244,7 +1244,7 @@ impl NodeNetworkInterface {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.is_some_and(|reference| reference == "Artboard" && self.connected_to_output(node_id, &[]) && self.is_layer(node_id, &[]))
|
.is_some_and(|reference| reference == "Artboard" && self.connected_to_output(node_id, &[]) && self.is_layer(node_id, &[]))
|
||||||
{
|
{
|
||||||
Some(LayerNodeIdentifier::new(*node_id, self, &[]))
|
Some(LayerNodeIdentifier::new(*node_id, self))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -3025,7 +3025,7 @@ impl NodeNetworkInterface {
|
|||||||
|
|
||||||
// Helper functions for mutable getters
|
// Helper functions for mutable getters
|
||||||
impl NodeNetworkInterface {
|
impl NodeNetworkInterface {
|
||||||
pub fn upstream_chain_nodes(&mut self, network_path: &[NodeId]) -> Vec<NodeId> {
|
pub fn upstream_chain_nodes(&self, network_path: &[NodeId]) -> Vec<NodeId> {
|
||||||
let Some(selected_nodes) = self.selected_nodes_in_nested_network(network_path) else {
|
let Some(selected_nodes) = self.selected_nodes_in_nested_network(network_path) else {
|
||||||
log::error!("Could not get selected nodes in upstream_chain_nodes");
|
log::error!("Could not get selected nodes in upstream_chain_nodes");
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
@@ -3156,7 +3156,7 @@ impl NodeNetworkInterface {
|
|||||||
self.document_metadata.document_to_viewport = transform;
|
self.document_metadata.document_to_viewport = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_eligible_to_be_layer(&mut self, node_id: &NodeId, network_path: &[NodeId]) -> bool {
|
pub fn is_eligible_to_be_layer(&self, node_id: &NodeId, network_path: &[NodeId]) -> bool {
|
||||||
let Some(node) = self.document_node(node_id, network_path) else {
|
let Some(node) = self.document_node(node_id, network_path) else {
|
||||||
log::error!("Could not get node {node_id} in is_eligible_to_be_layer");
|
log::error!("Could not get node {node_id} in is_eligible_to_be_layer");
|
||||||
return false;
|
return false;
|
||||||
@@ -3362,6 +3362,24 @@ impl NodeNetworkInterface {
|
|||||||
.map(|[a, b]| [node_graph_to_viewport.transform_point2(a), node_graph_to_viewport.transform_point2(b)])
|
.map(|[a, b]| [node_graph_to_viewport.transform_point2(a), node_graph_to_viewport.transform_point2(b)])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn selected_layers_artwork_bounding_box_viewport(&self) -> Option<[DVec2; 2]> {
|
||||||
|
self.selected_nodes()
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.filter(|node| self.is_layer(&node, &[]))
|
||||||
|
.filter_map(|layer| self.document_metadata.bounding_box_viewport(LayerNodeIdentifier::new(*layer, self)))
|
||||||
|
.reduce(Quad::combine_bounds)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn selected_unlocked_layers_bounding_box_viewport(&self) -> Option<[DVec2; 2]> {
|
||||||
|
self.selected_nodes()
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.filter(|node| self.is_layer(&node, &[]) && !self.is_layer(&node, &[]))
|
||||||
|
.filter_map(|layer| self.document_metadata.bounding_box_viewport(LayerNodeIdentifier::new(*layer, self)))
|
||||||
|
.reduce(Quad::combine_bounds)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the combined bounding box of the click targets of the selected nodes in the node graph in layer space
|
/// Get the combined bounding box of the click targets of the selected nodes in the node graph in layer space
|
||||||
pub fn selected_nodes_bounding_box(&mut self, network_path: &[NodeId]) -> Option<[DVec2; 2]> {
|
pub fn selected_nodes_bounding_box(&mut self, network_path: &[NodeId]) -> Option<[DVec2; 2]> {
|
||||||
let Some(selected_nodes) = self.selected_nodes_in_nested_network(network_path) else {
|
let Some(selected_nodes) = self.selected_nodes_in_nested_network(network_path) else {
|
||||||
@@ -3451,7 +3469,7 @@ impl NodeNetworkInterface {
|
|||||||
|
|
||||||
let Some(first_root_layer) = self
|
let Some(first_root_layer) = self
|
||||||
.upstream_flow_back_from_nodes(vec![root_node.node_id], &[], FlowType::PrimaryFlow)
|
.upstream_flow_back_from_nodes(vec![root_node.node_id], &[], FlowType::PrimaryFlow)
|
||||||
.find_map(|node_id| if self.is_layer(&node_id, &[]) { Some(LayerNodeIdentifier::new(node_id, self, &[])) } else { None })
|
.find_map(|node_id| if self.is_layer(&node_id, &[]) { Some(LayerNodeIdentifier::new(node_id, self)) } else { None })
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -3467,7 +3485,7 @@ impl NodeNetworkInterface {
|
|||||||
if horizontal_root_node_id == first_root_layer.to_node() {
|
if horizontal_root_node_id == first_root_layer.to_node() {
|
||||||
for current_node_id in horizontal_flow_iter {
|
for current_node_id in horizontal_flow_iter {
|
||||||
if self.is_layer(¤t_node_id, &[]) {
|
if self.is_layer(¤t_node_id, &[]) {
|
||||||
let current_layer_node = LayerNodeIdentifier::new(current_node_id, self, &[]);
|
let current_layer_node = LayerNodeIdentifier::new(current_node_id, self);
|
||||||
if !self.document_metadata.structure.contains_key(¤t_layer_node) {
|
if !self.document_metadata.structure.contains_key(¤t_layer_node) {
|
||||||
if current_node_id == first_root_layer.to_node() {
|
if current_node_id == first_root_layer.to_node() {
|
||||||
awaiting_primary_flow.push((current_node_id, LayerNodeIdentifier::ROOT_PARENT));
|
awaiting_primary_flow.push((current_node_id, LayerNodeIdentifier::ROOT_PARENT));
|
||||||
@@ -3484,7 +3502,7 @@ impl NodeNetworkInterface {
|
|||||||
// Skip the horizontal_root_node_id node
|
// Skip the horizontal_root_node_id node
|
||||||
for current_node_id in horizontal_flow_iter.skip(1) {
|
for current_node_id in horizontal_flow_iter.skip(1) {
|
||||||
if self.is_layer(¤t_node_id, &[]) {
|
if self.is_layer(¤t_node_id, &[]) {
|
||||||
let current_layer_node = LayerNodeIdentifier::new(current_node_id, self, &[]);
|
let current_layer_node = LayerNodeIdentifier::new(current_node_id, self);
|
||||||
if !self.document_metadata.structure.contains_key(¤t_layer_node) {
|
if !self.document_metadata.structure.contains_key(¤t_layer_node) {
|
||||||
awaiting_primary_flow.push((current_node_id, parent_layer_node));
|
awaiting_primary_flow.push((current_node_id, parent_layer_node));
|
||||||
children.push((parent_layer_node, current_layer_node));
|
children.push((parent_layer_node, current_layer_node));
|
||||||
@@ -3505,7 +3523,7 @@ impl NodeNetworkInterface {
|
|||||||
for current_node_id in primary_flow_iter.skip(1) {
|
for current_node_id in primary_flow_iter.skip(1) {
|
||||||
if self.is_layer(¤t_node_id, &[]) {
|
if self.is_layer(¤t_node_id, &[]) {
|
||||||
// Create a new layer for the top of each stack, and add it as a child to the previous parent
|
// Create a new layer for the top of each stack, and add it as a child to the previous parent
|
||||||
let current_layer_node = LayerNodeIdentifier::new(current_node_id, self, &[]);
|
let current_layer_node = LayerNodeIdentifier::new(current_node_id, self);
|
||||||
if !self.document_metadata.structure.contains_key(¤t_layer_node) {
|
if !self.document_metadata.structure.contains_key(¤t_layer_node) {
|
||||||
children.push(current_layer_node);
|
children.push(current_layer_node);
|
||||||
|
|
||||||
@@ -3568,7 +3586,7 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stack.extend(self_network_metadata.persistent_metadata.node_metadata.keys().map(|node_id| {
|
stack.extend(self_network_metadata.persistent_metadata.node_metadata.keys().map(|node_id| {
|
||||||
let mut current_path = path.clone();
|
let mut current_path: Vec<NodeId> = path.clone();
|
||||||
current_path.push(*node_id);
|
current_path.push(*node_id);
|
||||||
current_path
|
current_path
|
||||||
}));
|
}));
|
||||||
@@ -5087,8 +5105,8 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
self.unload_upstream_node_click_targets(vec![*node_id], network_path);
|
self.unload_upstream_node_click_targets(vec![*node_id], network_path);
|
||||||
// Reload click target of the layer which encapsulate the chain
|
// Reload click target of the layer which encapsulate the chain
|
||||||
if let Some(downstream_layer) = self.downstream_layer(node_id, network_path) {
|
if let Some(downstream_layer) = self.downstream_layer_for_chain_node(node_id, network_path) {
|
||||||
self.unload_node_click_targets(&downstream_layer.to_node(), network_path);
|
self.unload_node_click_targets(&downstream_layer, network_path);
|
||||||
}
|
}
|
||||||
self.unload_all_nodes_bounding_box(network_path);
|
self.unload_all_nodes_bounding_box(network_path);
|
||||||
}
|
}
|
||||||
@@ -5205,7 +5223,7 @@ impl NodeNetworkInterface {
|
|||||||
|
|
||||||
/// node_id is the first chain node, not the layer
|
/// node_id is the first chain node, not the layer
|
||||||
fn set_upstream_chain_to_absolute(&mut self, node_id: &NodeId, network_path: &[NodeId]) {
|
fn set_upstream_chain_to_absolute(&mut self, node_id: &NodeId, network_path: &[NodeId]) {
|
||||||
let Some(downstream_layer) = self.downstream_layer(node_id, network_path) else {
|
let Some(downstream_layer) = self.downstream_layer_for_chain_node(node_id, network_path) else {
|
||||||
log::error!("Could not get downstream layer in set_upstream_chain_to_absolute");
|
log::error!("Could not get downstream layer in set_upstream_chain_to_absolute");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -5218,7 +5236,7 @@ impl NodeNetworkInterface {
|
|||||||
if self.is_chain(upstream_id, network_path) {
|
if self.is_chain(upstream_id, network_path) {
|
||||||
self.set_absolute_position(upstream_id, previous_position, network_path);
|
self.set_absolute_position(upstream_id, previous_position, network_path);
|
||||||
// Reload click target of the layer which used to encapsulate the chain
|
// Reload click target of the layer which used to encapsulate the chain
|
||||||
self.unload_node_click_targets(&downstream_layer.to_node(), network_path);
|
self.unload_node_click_targets(&downstream_layer, network_path);
|
||||||
}
|
}
|
||||||
// If there is an upstream layer then stop breaking the chain
|
// If there is an upstream layer then stop breaking the chain
|
||||||
else {
|
else {
|
||||||
@@ -5297,8 +5315,8 @@ impl NodeNetworkInterface {
|
|||||||
// Deselect chain nodes upstream from a selected layer
|
// Deselect chain nodes upstream from a selected layer
|
||||||
if self.is_chain(selected_node, network_path)
|
if self.is_chain(selected_node, network_path)
|
||||||
&& self
|
&& self
|
||||||
.downstream_layer(selected_node, network_path)
|
.downstream_layer_for_chain_node(selected_node, network_path)
|
||||||
.is_some_and(|downstream_layer| node_ids.contains(&downstream_layer.to_node()))
|
.is_some_and(|downstream_layer| node_ids.contains(&downstream_layer))
|
||||||
{
|
{
|
||||||
node_ids.remove(selected_node);
|
node_ids.remove(selected_node);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -789,6 +789,8 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||||||
responses.add(DocumentMessage::GraphViewOverlay { open: node_graph_open });
|
responses.add(DocumentMessage::GraphViewOverlay { open: node_graph_open });
|
||||||
if node_graph_open {
|
if node_graph_open {
|
||||||
responses.add(NodeGraphMessage::UpdateGraphBarRight);
|
responses.add(NodeGraphMessage::UpdateGraphBarRight);
|
||||||
|
responses.add(NodeGraphMessage::UnloadWires);
|
||||||
|
responses.add(NodeGraphMessage::SendWires)
|
||||||
} else {
|
} else {
|
||||||
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1323,7 +1323,7 @@ mod test_transform_layer {
|
|||||||
let document = editor.active_document_mut();
|
let document = editor.active_document_mut();
|
||||||
let group_children = document.network_interface.downstream_layers(&group_layer.to_node(), &[]);
|
let group_children = document.network_interface.downstream_layers(&group_layer.to_node(), &[]);
|
||||||
if !group_children.is_empty() {
|
if !group_children.is_empty() {
|
||||||
Some(LayerNodeIdentifier::new(group_children[0], &document.network_interface, &[]))
|
Some(LayerNodeIdentifier::new(group_children[0], &document.network_interface))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user