mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 19:08:05 +08:00
Make Copy to Points and (Circular) Repeat and nodes output group data, and add flattening nodes (#2011)
* Output group from repeat, add flatten vector elements * Fix tests * Fix demo artwork * Output group from copy to points, add repeat for graphic groups, fix editor freeze on render fail * Restore painted dreams * WIP: Fix demo artwork * Fix demo artwork, add ungroup node * Incorrect scaling * fix test * Fix demo art --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -239,18 +239,28 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
// Gets the node id of a node with a specific reference that is upstream from the layer node, and creates it if it does not exist
|
||||
pub fn existing_node_id(&mut self, reference: &'static str) -> Option<NodeId> {
|
||||
// Start from the layer node or export
|
||||
let node_id = self.get_output_layer().map_or(Vec::new(), |output_layer| vec![output_layer.to_node()]);
|
||||
let output_layer = self.get_output_layer()?;
|
||||
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]).0.nested_type();
|
||||
|
||||
let upstream = self.network_interface.upstream_flow_back_from_nodes(node_id, &[], network_interface::FlowType::HorizontalFlow);
|
||||
|
||||
let is_traversal_start = |node_id: NodeId| {
|
||||
self.layer_node.map(|layer| layer.to_node()) == Some(node_id) || self.network_interface.network(&[]).unwrap().exports.iter().any(|export| export.as_node() == Some(node_id))
|
||||
};
|
||||
let upstream = self
|
||||
.network_interface
|
||||
.upstream_flow_back_from_nodes(vec![output_layer.to_node()], &[], network_interface::FlowType::HorizontalFlow);
|
||||
|
||||
// Take until another layer node is found (but not the first layer node)
|
||||
let existing_node_id = upstream
|
||||
.take_while(|node_id| is_traversal_start(*node_id) || !self.network_interface.is_layer(node_id, &[]))
|
||||
.find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|node_reference| node_reference == reference));
|
||||
let mut existing_node_id = None;
|
||||
for upstream_node in upstream.collect::<Vec<_>>() {
|
||||
let upstream_node_input_type = self.network_interface.input_type(&InputConnector::node(upstream_node, 0), &[]).0.nested_type();
|
||||
let is_traversal_start = |node_id: NodeId| {
|
||||
self.layer_node.map(|layer| layer.to_node()) == Some(node_id) || self.network_interface.network(&[]).unwrap().exports.iter().any(|export| export.as_node() == Some(node_id))
|
||||
};
|
||||
if !is_traversal_start(upstream_node) && (self.network_interface.is_layer(&upstream_node, &[]) || upstream_node_input_type != layer_input_type) {
|
||||
break;
|
||||
}
|
||||
if self.network_interface.reference(&upstream_node, &[]).is_some_and(|node_reference| node_reference == reference) {
|
||||
existing_node_id = Some(upstream_node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new node if the node does not exist and update its inputs
|
||||
existing_node_id.or_else(|| {
|
||||
|
||||
@@ -752,8 +752,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
return;
|
||||
};
|
||||
|
||||
responses.add(DocumentMessage::EndTransaction);
|
||||
|
||||
if let Some(preview_node) = self.preview_on_mouse_up {
|
||||
responses.add(NodeGraphMessage::TogglePreview { node_id: preview_node });
|
||||
self.preview_on_mouse_up = None;
|
||||
@@ -992,6 +990,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
self.box_selection_start = None;
|
||||
self.wire_in_progress_from_connector = None;
|
||||
self.wire_in_progress_to_connector = None;
|
||||
responses.add(DocumentMessage::EndTransaction);
|
||||
responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: None });
|
||||
responses.add(FrontendMessage::UpdateBox { box_selection: None })
|
||||
}
|
||||
|
||||
@@ -3603,7 +3603,7 @@ impl NodeNetworkInterface {
|
||||
};
|
||||
|
||||
// Check whether the being-deleted node's first (primary) input is a node
|
||||
let mut reconnect_to_input = network.nodes.get(node_id).and_then(|node| {
|
||||
let reconnect_to_input = network.nodes.get(node_id).and_then(|node| {
|
||||
node.inputs
|
||||
.iter()
|
||||
.find(|input| input.is_exposed_to_frontend(network_path.is_empty()))
|
||||
@@ -3625,15 +3625,22 @@ impl NodeNetworkInterface {
|
||||
|
||||
let mut reconnect_node = None;
|
||||
|
||||
// Don't reconnect if the upstream node is a layer and there are multiple downstream inputs to reconnect
|
||||
let multiple_disconnect_and_upstream_is_layer = downstream_inputs_to_disconnect.len() > 1
|
||||
&& reconnect_to_input
|
||||
.as_ref()
|
||||
.is_some_and(|upstream_input| upstream_input.as_node().map_or(false, |node_id| self.is_layer(&node_id, network_path)));
|
||||
|
||||
for downstream_input in &downstream_inputs_to_disconnect {
|
||||
self.disconnect_input(downstream_input, network_path);
|
||||
// Prevent reconnecting export to import until https://github.com/GraphiteEditor/Graphite/issues/1762 is solved
|
||||
if !(matches!(reconnect_to_input, Some(NodeInput::Network { .. })) && matches!(downstream_input, InputConnector::Export(_))) {
|
||||
if let Some(reconnect_input) = reconnect_to_input.take() {
|
||||
// Get the reconnect node position only if it is in a stack
|
||||
if let Some(reconnect_input) = &reconnect_to_input {
|
||||
reconnect_node = reconnect_input.as_node().and_then(|node_id| if self.is_stack(&node_id, network_path) { Some(node_id) } else { None });
|
||||
self.disconnect_input(&InputConnector::node(*node_id, 0), network_path);
|
||||
self.set_input(downstream_input, reconnect_input, network_path);
|
||||
if !multiple_disconnect_and_upstream_is_layer {
|
||||
self.set_input(downstream_input, reconnect_input.clone(), network_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -963,6 +963,7 @@ impl PortfolioMessageHandler {
|
||||
/text>"#
|
||||
// It's a mystery why the `/text>` tag above needs to be missing its `<`, but when it exists it prints the `<` character in the text. However this works with it removed.
|
||||
.to_string();
|
||||
responses.add(Message::EndBuffer(graphene_std::renderer::RenderMetadata::default()));
|
||||
responses.add(FrontendMessage::UpdateDocumentArtwork { svg: error });
|
||||
}
|
||||
result
|
||||
|
||||
@@ -15,7 +15,7 @@ use graphene_core::renderer::{RenderSvgSegmentList, SvgSegment};
|
||||
use graphene_core::text::FontCache;
|
||||
use graphene_core::transform::Footprint;
|
||||
use graphene_core::vector::style::ViewMode;
|
||||
use graphene_std::renderer::format_transform_matrix;
|
||||
use graphene_std::renderer::{format_transform_matrix, RenderMetadata};
|
||||
use graphene_std::vector::VectorData;
|
||||
use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
|
||||
use interpreted_executor::dynamic_executor::{DynamicExecutor, IntrospectError, ResolvedDocumentNodeTypesDelta};
|
||||
@@ -630,6 +630,7 @@ impl NodeGraphExecutor {
|
||||
}
|
||||
|
||||
fn process_node_graph_output(&mut self, node_graph_output: TaggedValue, transform: DAffine2, responses: &mut VecDeque<Message>) -> Result<(), String> {
|
||||
let mut render_output_metadata = RenderMetadata::default();
|
||||
match node_graph_output {
|
||||
TaggedValue::RenderOutput(render_output) => {
|
||||
match render_output.data {
|
||||
@@ -651,10 +652,7 @@ impl NodeGraphExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
responses.add(Message::EndBuffer(render_output.metadata));
|
||||
responses.add(DocumentMessage::RenderScrollbars);
|
||||
responses.add(DocumentMessage::RenderRulers);
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
render_output_metadata = render_output.metadata;
|
||||
}
|
||||
TaggedValue::Bool(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
TaggedValue::String(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
@@ -669,6 +667,10 @@ impl NodeGraphExecutor {
|
||||
return Err(format!("Invalid node graph output type: {node_graph_output:#?}"));
|
||||
}
|
||||
};
|
||||
responses.add(Message::EndBuffer(render_output_metadata));
|
||||
responses.add(DocumentMessage::RenderScrollbars);
|
||||
responses.add(DocumentMessage::RenderRulers);
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user