Skip to content
Merged
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
15 changes: 5 additions & 10 deletions editor/src/messages/portfolio/document/document_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::messages::portfolio::document::overlays::utility_types::{OverlaysType
use crate::messages::portfolio::document::properties_panel::properties_panel_message_handler::PropertiesPanelMessageContext;
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis, PTZ};
use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, NodeTemplate, OutputConnector};
use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, NodeTemplate};
use crate::messages::portfolio::document::utility_types::nodes::RawBuffer;
use crate::messages::portfolio::utility_types::PanelType;
use crate::messages::portfolio::utility_types::PersistentData;
Expand Down Expand Up @@ -2819,16 +2819,11 @@ impl DocumentMessageHandler {
.tooltip("Add an operation to the end of this layer's chain of nodes")
.disabled(!has_selection || has_multiple_selection)
.popover_layout({
// Showing only compatible types
// Showing only compatible types for the layer based on the output type of the node upstream from its horizontal input
let compatible_type = selected_layer.and_then(|layer| {
let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, &self.network_interface);
let node_type = graph_layer.horizontal_layer_flow().nth(1);
if let Some(node_id) = node_type {
let (output_type, _) = self.network_interface.output_type(&OutputConnector::node(node_id, 0), &self.selection_network_path);
Some(format!("type:{}", output_type.nested_type()))
} else {
None
}
self.network_interface
.upstream_output_connector(&InputConnector::node(layer.to_node(), 1), &[])
.and_then(|upstream_output| self.network_interface.output_type(&upstream_output, &[]).add_node_string())
});

let mut node_chooser = NodeCatalog::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ use crate::messages::portfolio::document::utility_types::nodes::CollapsedLayers;
use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::graph_modification_utils::get_clip_mode;
use glam::{DAffine2, DVec2, IVec2};
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput};
use graphene_std::Color;
use graphene_std::renderer::Quad;
use graphene_std::renderer::convert_usvg_path::convert_usvg_path;
use graphene_std::table::Table;
use graphene_std::text::{Font, TypesettingConfig};
use graphene_std::vector::style::{Fill, Gradient, GradientStops, GradientType, PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};

Expand Down Expand Up @@ -140,10 +142,18 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageContext<'_>> for
skip_rerender: true,
});
}

// Set the bottom input of the artboard back to artboard
let bottom_input = NodeInput::value(TaggedValue::Artboard(Table::new()), true);
network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), 0), bottom_input, &[]);
} else {
// We have some non layers (e.g. just a rectangle node). We disconnect the bottom input and connect it to the left input.
network_interface.disconnect_input(&InputConnector::node(artboard_layer.to_node(), 0), &[]);
network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), 1), primary_input, &[]);

// Set the bottom input of the artboard back to artboard
let bottom_input = NodeInput::value(TaggedValue::Artboard(Table::new()), true);
network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), 0), bottom_input, &[]);
}
}
responses.add_front(NodeGraphMessage::SelectedNodesSet { nodes: vec![id] });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ impl<'a> ModifyInputsContext<'a> {
// If inserting a 'Path' node, insert a 'Flatten Path' node if the type is `Graphic`.
// TODO: Allow the 'Path' node to operate on table data by utilizing the reference (index or ID?) for each row.
if node_definition.identifier == "Path" {
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]).0.nested_type().clone();
if layer_input_type == concrete!(Table<Graphic>) {
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]);
if layer_input_type.compiled_nested_type() == Some(&concrete!(Table<Graphic>)) {
let Some(flatten_path_definition) = resolve_document_node_type("Flatten Path") else {
log::error!("Flatten Path does not exist in ModifyInputsContext::existing_node_id");
return None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,37 @@ use graphene_std::registry::*;
use graphene_std::*;
use std::collections::HashSet;

/// Traverses a document node template and metadata in parallel to link the protonodes to their reference
fn traverse_node(node: &DocumentNode, node_metadata: &mut DocumentNodePersistentMetadata) {
match &node.implementation {
DocumentNodeImplementation::Network(node_network) => {
for (nested_node_id, nested_node) in node_network.nodes.iter() {
let nested_metadata = node_metadata
.network_metadata
.as_mut()
.expect("Network node must have network metadata")
.persistent_metadata
.node_metadata
.get_mut(nested_node_id)
.expect("Network metadata must have corresponding node id");
traverse_node(nested_node, &mut nested_metadata.persistent_metadata);
}
}
DocumentNodeImplementation::ProtoNode(proto_node_identifier) => {
if let Some(metadata) = NODE_METADATA.lock().unwrap().get(proto_node_identifier) {
node_metadata.reference = Some(metadata.display_name.to_string());
}
}
DocumentNodeImplementation::Extract => {}
}
}

pub(super) fn post_process_nodes(mut custom: Vec<DocumentNodeDefinition>) -> Vec<DocumentNodeDefinition> {
// Link the protonodes with custom networks to their reference
for node in custom.iter_mut() {
traverse_node(&node.node_template.document_node, &mut node.node_template.persistent_node_metadata);
}

// Remove struct generics
for DocumentNodeDefinition { node_template, .. } in custom.iter_mut() {
let NodeTemplate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,19 @@ use crate::messages::portfolio::document::node_graph::utility_types::{ContextMen
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::{
self, FlowType, InputConnector, NodeNetworkInterface, NodeTemplate, NodeTypePersistentMetadata, OutputConnector, Previewing, TypeSource,
self, FlowType, InputConnector, NodeNetworkInterface, NodeTemplate, NodeTypePersistentMetadata, OutputConnector, Previewing,
};
use crate::messages::portfolio::document::utility_types::nodes::{CollapsedLayers, LayerPanelEntry};
use crate::messages::portfolio::document::utility_types::wires::{GraphWireStyle, WirePath, WirePathUpdate, build_vector_wire};
use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
use crate::messages::tool::common_functionality::graph_modification_utils::{self, get_clip_mode};
use crate::messages::tool::common_functionality::graph_modification_utils::get_clip_mode;
use crate::messages::tool::common_functionality::utility_functions::make_path_editable_is_allowed;
use crate::messages::tool::tool_messages::tool_prelude::{Key, MouseMotion};
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
use crate::messages::viewport::Position;
use glam::{DAffine2, DVec2, IVec2};
use graph_craft::document::{DocumentNodeImplementation, NodeId, NodeInput};
use graph_craft::proto::GraphErrors;
use graphene_std::math::math_ext::QuadExt;
use graphene_std::vector::algorithms::bezpath_algorithms::bezpath_is_inside_bezpath;
use graphene_std::*;
Expand Down Expand Up @@ -51,7 +50,6 @@ pub struct NodeGraphMessageContext<'a> {
pub struct NodeGraphMessageHandler {
// TODO: Remove network and move to NodeNetworkInterface
pub network: Vec<NodeId>,
pub node_graph_errors: GraphErrors,
has_selection: bool,
widgets: [LayoutGroup; 2],
/// Used to add a transaction for the first node move when dragging.
Expand Down Expand Up @@ -875,13 +873,14 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
self.disconnecting = Some(*clicked_input);

let output_connector = if *clicked_input == InputConnector::Export(0) {
network_interface.root_node(selection_network_path).map(|root_node| root_node.to_connector())
network_interface.root_node(breadcrumb_network_path).map(|root_node| root_node.to_connector())
} else {
network_interface.upstream_output_connector(clicked_input, selection_network_path)
network_interface.upstream_output_connector(clicked_input, breadcrumb_network_path)
};
let Some(output_connector) = output_connector else { return };
self.wire_in_progress_from_connector = network_interface.output_position(&output_connector, selection_network_path);
self.wire_in_progress_type = FrontendGraphDataType::from_type(&network_interface.input_type(clicked_input, breadcrumb_network_path).0);
self.wire_in_progress_from_connector = network_interface.output_position(&output_connector, breadcrumb_network_path);

self.wire_in_progress_type = network_interface.output_type(&output_connector, breadcrumb_network_path).displayed_type();
return;
}

Expand All @@ -891,8 +890,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
self.initial_disconnecting = false;

self.wire_in_progress_from_connector = network_interface.output_position(&clicked_output, selection_network_path);
let (output_type, source) = &network_interface.output_type(&clicked_output, breadcrumb_network_path);
self.wire_in_progress_type = FrontendGraphDataType::displayed_type(output_type, source);
let output_type = network_interface.output_type(&clicked_output, breadcrumb_network_path);
self.wire_in_progress_type = output_type.displayed_type();

self.update_node_graph_hints(responses);
return;
Expand Down Expand Up @@ -1211,21 +1210,17 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
}

// Get the output types from the network interface
let (output_type, type_source) = network_interface.output_type(&output_connector, selection_network_path);
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
warn!("No network_metadata");
return;
};

let compatible_type = match type_source {
TypeSource::RandomProtonodeImplementation | TypeSource::Error(_) => None,
_ => Some(format!("type:{}", output_type.nested_type())),
};

let appear_right_of_mouse = if ipp.mouse.position.x > viewport.size().y() - 173. { -173. } else { 0. };
let appear_above_mouse = if ipp.mouse.position.y > viewport.size().y() - 34. { -34. } else { 0. };
let node_graph_shift = DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.matrix2.x_axis.x;

let compatible_type = network_interface.output_type(&output_connector, selection_network_path).add_node_string();

self.context_menu = Some(ContextMenuInformation {
context_menu_coordinates: ((point.x + node_graph_shift.x) as i32, (point.y + node_graph_shift.y) as i32),
context_menu_data: ContextMenuData::CreateNode { compatible_type },
Expand Down Expand Up @@ -1632,7 +1627,7 @@ 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 {
nodes.push(*node_id);
}
for error in &self.node_graph_errors {
for error in &network_interface.resolved_types.node_graph_errors {
if error.node_path.contains(node_id) {
nodes.push(*node_id);
}
Expand Down Expand Up @@ -1996,13 +1991,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
responses.add(NodeGraphMessage::SendGraph);
}
NodeGraphMessage::UpdateTypes { resolved_types, node_graph_errors } => {
for (path, node_type) in resolved_types.add {
network_interface.resolved_types.types.insert(path.to_vec(), node_type);
}
for path in resolved_types.remove {
network_interface.resolved_types.types.remove(&path.to_vec());
}
self.node_graph_errors = node_graph_errors;
network_interface.resolved_types.update(resolved_types, node_graph_errors);
}
NodeGraphMessage::UpdateActionButtons => {
if selection_network_path == breadcrumb_network_path {
Expand Down Expand Up @@ -2115,16 +2104,7 @@ impl NodeGraphMessageHandler {
.popover_layout({
// Showing only compatible types
let compatible_type = match (selection_includes_layers, has_multiple_selection, selected_layer) {
(true, false, Some(layer)) => {
let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, network_interface);
let node_type = graph_layer.horizontal_layer_flow().nth(1);
if let Some(node_id) = node_type {
let (output_type, _) = network_interface.output_type(&OutputConnector::node(node_id, 0), &[]);
Some(format!("type:{}", output_type.nested_type()))
} else {
None
}
}
(true, false, Some(layer)) => network_interface.output_type(&OutputConnector::node(layer.to_node(), 1), &[]).add_node_string(),
_ => None,
};

Expand Down Expand Up @@ -2437,17 +2417,10 @@ impl NodeGraphMessageHandler {
.icon(Some("Node".to_string()))
.tooltip("Add an operation to the end of this layer's chain of nodes")
.popover_layout({
let layer_identifier = LayerNodeIdentifier::new(layer, context.network_interface);
let compatible_type = {
let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer_identifier, context.network_interface);
let node_type = graph_layer.horizontal_layer_flow().nth(1);
if let Some(node_id) = node_type {
let (output_type, _) = context.network_interface.output_type(&OutputConnector::node(node_id, 0), &[]);
Some(format!("type:{}", output_type.nested_type()))
} else {
None
}
};
let compatible_type = context
.network_interface
.upstream_output_connector(&InputConnector::node(layer, 1), &[])
.and_then(|upstream_output| context.network_interface.output_type(&upstream_output, &[]).add_node_string());

let mut node_chooser = NodeCatalog::new();
node_chooser.intial_search = compatible_type.unwrap_or("".to_string());
Expand Down Expand Up @@ -2579,13 +2552,14 @@ impl NodeGraphMessageHandler {

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

let errors = self
let errors = network_interface
.resolved_types
.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)) {
if network_interface.resolved_types.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
Expand Down Expand Up @@ -2768,7 +2742,6 @@ impl Default for NodeGraphMessageHandler {
fn default() -> Self {
Self {
network: Vec::new(),
node_graph_errors: Vec::new(),
has_selection: false,
widgets: [LayoutGroup::Row { widgets: Vec::new() }, LayoutGroup::Row { widgets: Vec::new() }],
drag_start: None,
Expand Down Expand Up @@ -2800,7 +2773,6 @@ impl Default for NodeGraphMessageHandler {
impl PartialEq for NodeGraphMessageHandler {
fn eq(&self, other: &Self) -> bool {
self.network == other.network
&& self.node_graph_errors == other.node_graph_errors
&& self.has_selection == other.has_selection
&& self.widgets == other.widgets
&& self.drag_start == other.drag_start
Expand Down
Loading