Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions editor/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl DispatcherMessageHandlers {
/// The last occurrence of the message in the message queue is sufficient to ensure correct behavior.
/// In addition, these messages do not change any state in the backend (aside from caches).
const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::NodeGraph(NodeGraphMessageDiscriminant::SendGraph))),
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::PropertiesPanel(
PropertiesPanelMessageDiscriminant::Refresh,
))),
Expand Down
35 changes: 15 additions & 20 deletions editor/src/messages/frontend/frontend_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ use super::utility_types::{DocumentDetails, MouseCursorIcon, OpenDocument};
use crate::messages::app_window::app_window_message_handler::AppWindowPlatform;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::utility_types::{
BoxSelection, ContextMenuInformation, FrontendClickTargets, FrontendGraphInput, FrontendGraphOutput, FrontendNode, FrontendNodeType, Transform,
BoxSelection, ContextMenuInformation, FrontendClickTargets, FrontendGraphInput, FrontendGraphOutput, FrontendNodeToRender, FrontendNodeType, FrontendXY, Transform,
};
use crate::messages::portfolio::document::utility_types::nodes::{JsRawBuffer, LayerPanelEntry, RawBuffer};
use crate::messages::portfolio::document::utility_types::wires::{WirePath, WirePathUpdate};
use crate::messages::prelude::*;
use crate::messages::tool::utility_types::HintData;
use glam::IVec2;
use graph_craft::document::NodeId;
use graphene_std::raster::Image;
use graphene_std::raster::color::Color;
Expand Down Expand Up @@ -133,18 +132,14 @@ pub enum FrontendMessage {
exports: Vec<Option<FrontendGraphInput>>,
/// The primary import location.
#[serde(rename = "importPosition")]
import_position: IVec2,
import_position: FrontendXY,
/// The primary export location.
#[serde(rename = "exportPosition")]
export_position: IVec2,
export_position: FrontendXY,
/// The document network does not have an add import or export button.
#[serde(rename = "addImportExport")]
add_import_export: bool,
},
UpdateInSelectedNetwork {
#[serde(rename = "inSelectedNetwork")]
in_selected_network: bool,
},
UpdateBox {
#[serde(rename = "box")]
box_selection: Option<BoxSelection>,
Expand Down Expand Up @@ -185,10 +180,6 @@ pub enum FrontendMessage {
UpdateLayerWidths {
#[serde(rename = "layerWidths")]
layer_widths: HashMap<NodeId, u32>,
#[serde(rename = "chainWidths")]
chain_widths: HashMap<NodeId, u32>,
#[serde(rename = "hasLeftInputWire")]
has_left_input_wire: HashMap<NodeId, bool>,
},
UpdateDialogButtons {
#[serde(rename = "layoutTarget")]
Expand Down Expand Up @@ -253,9 +244,6 @@ pub enum FrontendMessage {
#[serde(rename = "setColorChoice")]
set_color_choice: Option<String>,
},
UpdateGraphFadeArtwork {
percentage: f64,
},
UpdateInputHints {
#[serde(rename = "hintData")]
hint_data: HintData,
Expand Down Expand Up @@ -283,8 +271,18 @@ pub enum FrontendMessage {
UpdateMouseCursor {
cursor: MouseCursorIcon,
},
UpdateNodeGraphNodes {
nodes: Vec<FrontendNode>,
UpdateNodeGraphRender {
#[serde(rename = "nodesToRender")]
nodes_to_render: Vec<FrontendNodeToRender>,
open: bool,
opacity: f64,
#[serde(rename = "inSelectedNetwork")]
in_selected_network: bool,
// Displays a dashed border around the node
#[serde(rename = "previewedNode")]
previewed_node: Option<NodeId>,
#[serde(rename = "nativeNodeGraphRender")]
native_node_graph_render: bool,
},
UpdateVisibleNodes {
nodes: Vec<NodeId>,
Expand All @@ -298,9 +296,6 @@ pub enum FrontendMessage {
layout_target: LayoutTarget,
diff: Vec<WidgetDiff>,
},
UpdateNodeGraphSelection {
selected: Vec<NodeId>,
},
UpdateNodeGraphTransform {
transform: Transform,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,9 +561,6 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
self.graph_view_overlay_open = open;

responses.add(FrontendMessage::UpdateGraphViewOverlay { open });
responses.add(FrontendMessage::UpdateGraphFadeArtwork {
percentage: self.graph_fade_artwork_percentage,
});

// Update the tilt menu bar buttons to be disabled when the graph is open
responses.add(MenuBarMessage::SendLayout);
Expand All @@ -579,12 +576,13 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
responses.add(NavigationMessage::CanvasTiltSet { angle_radians: 0. });
responses.add(NodeGraphMessage::SetGridAlignedEdges);
responses.add(NodeGraphMessage::UpdateGraphBarRight);
responses.add(NodeGraphMessage::SendGraph);
responses.add(NodeGraphMessage::UpdateHints);
} else {
responses.add(ToolMessage::ActivateTool { tool_type: *current_tool });
responses.add(OverlaysMessage::Draw); // Redraw overlays when graph is closed
}

responses.add(NodeGraphMessage::SendGraph);
}
DocumentMessage::GraphViewOverlayToggle => {
responses.add(DocumentMessage::GraphViewOverlay { open: !self.graph_view_overlay_open });
Expand Down Expand Up @@ -1191,7 +1189,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
}
responses.add(PropertiesPanelMessage::Refresh);
responses.add(NodeGraphMessage::UpdateLayerPanel);
responses.add(NodeGraphMessage::UpdateInSelectedNetwork);
responses.add(NodeGraphMessage::SendGraph);
}
DocumentMessage::SetBlendModeForSelectedLayers { blend_mode } => {
for layer in self.network_interface.selected_nodes().selected_layers_except_artboards(&self.network_interface) {
Expand All @@ -1200,7 +1198,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
}
DocumentMessage::SetGraphFadeArtwork { percentage } => {
self.graph_fade_artwork_percentage = percentage;
responses.add(FrontendMessage::UpdateGraphFadeArtwork { percentage });
responses.add(NodeGraphMessage::SendGraph);
}
DocumentMessage::SetNodePinned { node_id, pinned } => {
responses.add(DocumentMessage::AddTransaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ pub enum NodeGraphMessage {
TogglePreviewImpl {
node_id: NodeId,
},
ToggleNativeNodeGraphRender,
SetImportExportName {
name: String,
index: ImportOrExport,
Expand Down Expand Up @@ -231,7 +232,5 @@ pub enum NodeGraphMessage {
},
UpdateActionButtons,
UpdateGraphBarRight,
UpdateInSelectedNetwork,
UpdateHints,
SendSelectedNodes,
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use super::utility_types::{BoxSelection, ContextMenuInformation, DragStart, FrontendNode};
use super::utility_types::{BoxSelection, ContextMenuInformation, DragStart};
use super::{document_node_definitions, node_properties};
use crate::consts::GRID_SIZE;
use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::document_message_handler::navigation_controls;
use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext;
use crate::messages::portfolio::document::node_graph::document_node_definitions::NodePropertiesContext;
use crate::messages::portfolio::document::node_graph::utility_types::{ContextMenuData, Direction, FrontendGraphDataType};
use crate::messages::portfolio::document::node_graph::utility_types::{ContextMenuData, Direction, FrontendGraphDataType, FrontendXY};
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::misc::GroupFolderType;
use crate::messages::portfolio::document::utility_types::network_interface::{
Expand Down Expand Up @@ -93,8 +93,8 @@ pub struct NodeGraphMessageHandler {
end_index: Option<usize>,
/// Used to keep track of what nodes are sent to the front end so that only visible ones are sent to the frontend
frontend_nodes: Vec<NodeId>,
/// Used to keep track of what wires are sent to the front end so the old ones can be removed
frontend_wires: HashSet<(NodeId, usize)>,
/// Disables rendering nodes in Svelte
native_node_graph_render: bool,
}

/// NodeGraphMessageHandler always modifies the network which the selected nodes are in. No GraphOperationMessages should be added here, since those messages will always affect the document network.
Expand Down Expand Up @@ -192,7 +192,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
responses.add(MenuBarMessage::SendLayout);
responses.add(NodeGraphMessage::UpdateLayerPanel);
responses.add(PropertiesPanelMessage::Refresh);
responses.add(NodeGraphMessage::SendSelectedNodes);
responses.add(NodeGraphMessage::SendGraph);
responses.add(ArtboardToolMessage::UpdateSelectedArtboard);
responses.add(DocumentMessage::DocumentStructureChanged);
responses.add(OverlaysMessage::Draw);
Expand Down Expand Up @@ -1633,24 +1633,26 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
responses.add(NodeGraphMessage::UpdateLayerPanel);
responses.add(DocumentMessage::DocumentStructureChanged);
responses.add(PropertiesPanelMessage::Refresh);
if breadcrumb_network_path == selection_network_path && graph_view_overlay_open {
let nodes = self.collect_nodes(network_interface, breadcrumb_network_path);
self.frontend_nodes = nodes.iter().map(|node| node.id).collect();
responses.add(FrontendMessage::UpdateNodeGraphNodes { nodes });
responses.add(NodeGraphMessage::UpdateVisibleNodes);
responses.add(NodeGraphMessage::UpdateActionButtons);
let nodes_to_render = network_interface.collect_nodes(&self.node_graph_errors, breadcrumb_network_path);
self.frontend_nodes = nodes_to_render.iter().map(|node| node.metadata.node_id).collect();
let previewed_node = network_interface.previewed_node(breadcrumb_network_path);
responses.add(FrontendMessage::UpdateNodeGraphRender {
nodes_to_render,
open: graph_view_overlay_open,
opacity: graph_fade_artwork_percentage,
in_selected_network: selection_network_path == breadcrumb_network_path,
previewed_node,
native_node_graph_render: self.native_node_graph_render,
});
responses.add(NodeGraphMessage::UpdateVisibleNodes);

let (layer_widths, chain_widths, has_left_input_wire) = network_interface.collect_layer_widths(breadcrumb_network_path);
let layer_widths = network_interface.collect_layer_widths(breadcrumb_network_path);

responses.add(NodeGraphMessage::UpdateImportsExports);
responses.add(FrontendMessage::UpdateLayerWidths {
layer_widths,
chain_widths,
has_left_input_wire,
});
responses.add(NodeGraphMessage::SendSelectedNodes);
responses.add(NodeGraphMessage::SendWires);
self.update_node_graph_hints(responses);
}
responses.add(NodeGraphMessage::UpdateImportsExports);
responses.add(FrontendMessage::UpdateLayerWidths { layer_widths });
responses.add(NodeGraphMessage::SendWires);
self.update_node_graph_hints(responses);
}
NodeGraphMessage::SetGridAlignedEdges => {
if graph_view_overlay_open {
Expand Down Expand Up @@ -1799,6 +1801,10 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
NodeGraphMessage::TogglePreviewImpl { node_id } => {
network_interface.toggle_preview(node_id, selection_network_path);
}
NodeGraphMessage::ToggleNativeNodeGraphRender => {
self.native_node_graph_render = !self.native_node_graph_render;
responses.add(NodeGraphMessage::SendGraph);
}
NodeGraphMessage::ToggleSelectedLocked => {
let Some(selected_nodes) = network_interface.selected_nodes_in_nested_network(selection_network_path) else {
log::error!("Could not get selected nodes in NodeGraphMessage::ToggleSelectedLocked");
Expand Down Expand Up @@ -1956,6 +1962,15 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
return;
};

let import_position = FrontendXY {
x: import_position.x,
y: import_position.y,
};
let export_position = FrontendXY {
x: export_position.x,
y: export_position.y,
};

// Do not show the add import or add export button in the document network;
let add_import_export = !breadcrumb_network_path.is_empty();

Expand Down Expand Up @@ -2000,22 +2015,9 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
self.update_graph_bar_right(graph_fade_artwork_percentage, network_interface, breadcrumb_network_path, navigation_handler);
self.send_node_bar_layout(responses);
}
NodeGraphMessage::UpdateInSelectedNetwork => responses.add(FrontendMessage::UpdateInSelectedNetwork {
in_selected_network: selection_network_path == breadcrumb_network_path,
}),
NodeGraphMessage::UpdateHints => {
self.update_node_graph_hints(responses);
}
NodeGraphMessage::SendSelectedNodes => {
let Some(selected_nodes) = network_interface.selected_nodes_in_nested_network(breadcrumb_network_path) else {
log::error!("Could not get selected nodes in NodeGraphMessage::SendSelectedNodes");
return;
};
responses.add(NodeGraphMessage::UpdateActionButtons);
responses.add(FrontendMessage::UpdateNodeGraphSelection {
selected: selected_nodes.selected_nodes().cloned().collect::<Vec<_>>(),
});
}
}
let Some(selected_nodes) = network_interface.selected_nodes_in_nested_network(selection_network_path) else {
log::error!("Could not get selected nodes in NodeGraphMessageHandler");
Expand Down Expand Up @@ -2499,94 +2501,6 @@ impl NodeGraphMessageHandler {
added_wires
}

fn collect_nodes(&self, network_interface: &mut NodeNetworkInterface, breadcrumb_network_path: &[NodeId]) -> Vec<FrontendNode> {
let Some(network) = network_interface.nested_network(breadcrumb_network_path) else {
log::error!("Could not get nested network when collecting nodes");
return Vec::new();
};
let mut nodes = Vec::new();
for (node_id, visible) in network.nodes.iter().map(|(node_id, node)| (*node_id, node.visible)).collect::<Vec<_>>() {
let node_id_path = [breadcrumb_network_path, &[node_id]].concat();

let primary_input_connector = InputConnector::node(node_id, 0);

let primary_input = if network_interface
.input_from_connector(&primary_input_connector, breadcrumb_network_path)
.is_some_and(|input| input.is_exposed())
{
network_interface.frontend_input_from_connector(&primary_input_connector, breadcrumb_network_path)
} else {
None
};
let exposed_inputs = (1..network_interface.number_of_inputs(&node_id, breadcrumb_network_path))
.filter_map(|input_index| network_interface.frontend_input_from_connector(&InputConnector::node(node_id, input_index), breadcrumb_network_path))
.collect();

let primary_output = network_interface.frontend_output_from_connector(&OutputConnector::node(node_id, 0), breadcrumb_network_path);

let exposed_outputs = (1..network_interface.number_of_outputs(&node_id, breadcrumb_network_path))
.filter_map(|output_index| network_interface.frontend_output_from_connector(&OutputConnector::node(node_id, output_index), breadcrumb_network_path))
.collect();
let (primary_output_connected_to_layer, primary_input_connected_to_layer) = if network_interface.is_layer(&node_id, breadcrumb_network_path) {
(
network_interface.primary_output_connected_to_layer(&node_id, breadcrumb_network_path),
network_interface.primary_input_connected_to_layer(&node_id, breadcrumb_network_path),
)
} else {
(false, false)
};

let is_export = network_interface
.input_from_connector(&InputConnector::Export(0), breadcrumb_network_path)
.is_some_and(|export| export.as_node().is_some_and(|export_node_id| node_id == export_node_id));
let is_root_node = network_interface.root_node(breadcrumb_network_path).is_some_and(|root_node| root_node.node_id == node_id);

let Some(position) = network_interface.position(&node_id, breadcrumb_network_path) else {
log::error!("Could not get position for node: {node_id}");
continue;
};
let previewed = is_export && !is_root_node;

let locked = network_interface.is_locked(&node_id, breadcrumb_network_path);

let errors = self
.node_graph_errors
.iter()
.find(|error| error.node_path == node_id_path)
.map(|error| format!("{:?}", error.error.clone()))
.or_else(|| {
if self.node_graph_errors.iter().any(|error| error.node_path.starts_with(&node_id_path)) {
Some("Node graph type error within this node".to_string())
} else {
None
}
});

nodes.push(FrontendNode {
id: node_id,
is_layer: network_interface
.node_metadata(&node_id, breadcrumb_network_path)
.is_some_and(|node_metadata| node_metadata.persistent_metadata.is_layer()),
can_be_layer: network_interface.is_eligible_to_be_layer(&node_id, breadcrumb_network_path),
reference: network_interface.reference(&node_id, breadcrumb_network_path).cloned().unwrap_or_default(),
display_name: network_interface.display_name(&node_id, breadcrumb_network_path),
primary_input,
exposed_inputs,
primary_output,
exposed_outputs,
primary_output_connected_to_layer,
primary_input_connected_to_layer,
position,
previewed,
visible,
locked,
errors,
});
}

nodes
}

fn collect_subgraph_names(network_interface: &mut NodeNetworkInterface, breadcrumb_network_path: &[NodeId]) -> Option<Vec<String>> {
let mut current_network_path = vec![];
let mut current_network = network_interface.nested_network(&current_network_path).unwrap();
Expand Down Expand Up @@ -2758,7 +2672,7 @@ impl Default for NodeGraphMessageHandler {
reordering_import: None,
end_index: None,
frontend_nodes: Vec::new(),
frontend_wires: HashSet::new(),
native_node_graph_render: false,
}
}
}
Expand Down
Loading
Loading