Skip to content

Commit 2591d8f

Browse files
adamgerhantKeavon
authored andcommitted
Generalize LayerNodeIdentifier, monitor_nodes support for Artboard node, adjust ResizeArtboard/ClearArtboards, move alias validation to Rust
1 parent 2b7d495 commit 2591d8f

File tree

10 files changed

+76
-42
lines changed

10 files changed

+76
-42
lines changed

editor/src/messages/portfolio/document/document_message_handler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,7 @@ impl DocumentMessageHandler {
847847
self.metadata
848848
.root()
849849
.descendants(&self.metadata)
850+
//.artboard_descendants(&self.metadata, &self.network)
850851
.filter(|&layer| self.selected_nodes.layer_visible(layer, self.metadata()))
851852
.filter(|&layer| !self.selected_nodes.layer_locked(layer, self.metadata()))
852853
.filter_map(|layer| self.metadata.click_target(layer).map(|targets| (layer, targets)))

editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,8 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for Gr
197197
load_network_structure(document_network, document_metadata, selected_nodes, collapsed);
198198
}
199199
GraphOperationMessage::ResizeArtboard { id, location, dimensions } => {
200-
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(id, document_network, document_metadata, node_graph, responses) {
201-
modify_inputs.resize_artboard(location, dimensions);
202-
}
200+
let mut modify_inputs = ModifyInputsContext::new(document_network, document_metadata, node_graph, responses);
201+
modify_inputs.resize_artboard(location, dimensions);
203202
}
204203
GraphOperationMessage::DeleteLayer { id } => {
205204
let mut modify_inputs = ModifyInputsContext::new(document_network, document_metadata, node_graph, responses);
@@ -218,20 +217,15 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for Gr
218217
}
219218
GraphOperationMessage::ClearArtboards => {
220219
let mut modify_inputs = ModifyInputsContext::new(document_network, document_metadata, node_graph, responses);
221-
let layer_nodes = modify_inputs.document_network.nodes.iter().filter(|(_, node)| node.is_layer()).map(|(id, _)| *id).collect::<Vec<_>>();
222-
for layer in layer_nodes {
223-
let artboards = modify_inputs
224-
.document_network
225-
.upstream_flow_back_from_nodes(vec![layer], true)
226-
.filter_map(|(node, _id)| if node.is_artboard() { Some(_id) } else { None })
227-
.collect::<Vec<_>>();
228-
if artboards.is_empty() {
229-
continue;
230-
}
231-
for artboard in artboards {
232-
modify_inputs.delete_artboard(artboard, selected_nodes);
233-
}
234-
modify_inputs.delete_layer(layer, selected_nodes, true);
220+
let artboard_nodes = modify_inputs
221+
.document_network
222+
.nodes
223+
.iter()
224+
.filter(|(_, node)| node.is_artboard())
225+
.map(|(id, _)| *id)
226+
.collect::<Vec<_>>();
227+
for artboard in artboard_nodes {
228+
modify_inputs.delete_artboard(artboard, selected_nodes);
235229
}
236230
load_network_structure(document_network, document_metadata, selected_nodes, collapsed);
237231
}

editor/src/messages/portfolio/document/graph_operation/utility_types.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl<'a> ModifyInputsContext<'a> {
177177

178178
// Update the document metadata structure
179179
if let Some(new_id) = new_id {
180-
let parent = if self.document_network.nodes.get(&output_node_id).is_some_and(|node| node.is_layer()) {
180+
let parent = if self.document_network.nodes.get(&output_node_id).is_some_and(|node| node.is_layer) {
181181
LayerNodeIdentifier::new(output_node_id, self.document_network)
182182
} else {
183183
LayerNodeIdentifier::ROOT
@@ -217,12 +217,6 @@ impl<'a> ModifyInputsContext<'a> {
217217
Default::default(),
218218
);
219219

220-
// Doesn't work
221-
// let artboard_node = resolve_document_node_type("Artboard").expect("Artboard node").default_document_node();
222-
223-
// Works
224-
// let artboard_node = resolve_document_node_type("Layer").expect("Layer node").default_document_node();
225-
226220
// Get node that feeds into output. If it exists, connect the new artboard node in between. Else connect the new artboard directly to output.
227221
let output_node_primary_input = self.document_network.nodes.get(&output_node_id)?.primary_input();
228222
let created_node_id = if let NodeInput::Node { node_id, .. } = &output_node_primary_input? {
@@ -236,6 +230,11 @@ impl<'a> ModifyInputsContext<'a> {
236230
shift = IVec2::new(-8, 3);
237231
self.insert_node_before(new_id, output_node_id, 0, artboard_node, shift)
238232
};
233+
234+
if let Some(new_id) = created_node_id {
235+
let new_child = LayerNodeIdentifier::new_unchecked(new_id);
236+
LayerNodeIdentifier::ROOT.push_front_child(self.document_metadata, new_child);
237+
}
239238
//self.responses.add(NodeGraphMessage::RunDocumentGraph);
240239
created_node_id
241240
}
@@ -559,8 +558,8 @@ impl<'a> ModifyInputsContext<'a> {
559558

560559
pub fn resize_artboard(&mut self, location: IVec2, dimensions: IVec2) {
561560
self.modify_inputs("Artboard", false, |inputs, _node_id, _metadata| {
562-
inputs[1] = NodeInput::value(TaggedValue::IVec2(location), false);
563-
inputs[2] = NodeInput::value(TaggedValue::IVec2(dimensions), false);
561+
inputs[2] = NodeInput::value(TaggedValue::IVec2(location), false);
562+
inputs[3] = NodeInput::value(TaggedValue::IVec2(dimensions), false);
564563
});
565564
}
566565

editor/src/messages/portfolio/document/node_graph/document_node_types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2994,6 +2994,7 @@ impl DocumentNodeDefinition {
29942994

29952995
DocumentNode {
29962996
name: self.name.to_string(),
2997+
is_layer: self.is_layer,
29972998
inputs,
29982999
manual_composition: self.manual_composition.clone(),
29993000
has_primary_output: self.has_primary_output,

editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ impl NodeGraphMessageHandler {
737737

738738
let mut nodes = Vec::new();
739739
for (&node_id, node) in &network.nodes {
740+
let alias = (!node.alias.is_empty()).then_some(node.alias.clone()).unwrap_or(node.name.clone());
741+
740742
let node_path = vec![node_id];
741743
// TODO: This should be based on the graph runtime type inference system in order to change the colors of node connectors to match the data type in use
742744
let Some(document_node_definition) = document_node_types::resolve_document_node_type(&node.name) else {
@@ -783,8 +785,9 @@ impl NodeGraphMessageHandler {
783785

784786
nodes.push(FrontendNode {
785787
id: node_id,
786-
is_layer: node.is_layer,
787-
alias: node.alias.clone(),
788+
//is_layer: node.is_layer,
789+
is_layer: false,
790+
alias,
788791
name: node.name.clone(),
789792
primary_input,
790793
exposed_inputs,
@@ -831,7 +834,7 @@ impl NodeGraphMessageHandler {
831834
has_children: layer.has_children(metadata),
832835
depth: layer.ancestors(metadata).count() - 1,
833836
parent_id: layer.parent(metadata).map(|parent| parent.to_node()),
834-
name: network.nodes.get(&node_id).map(|node| node.alias.clone()).unwrap_or_default(),
837+
name: network.nodes.get(&node_id).map(|node| node.alias.clone()).unwrap_or(node.name.clone()),
835838
tooltip: if cfg!(debug_assertions) { format!("Layer ID: {node_id}") } else { "".into() },
836839
visible: node.visible,
837840
parents_visible,

editor/src/messages/portfolio/document/utility_types/document_metadata.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl DocumentMetadata {
148148
/// Loads the structure of layer nodes from a node graph.
149149
pub fn load_structure(&mut self, graph: &NodeNetwork, selected_nodes: &mut SelectedNodes) {
150150
fn first_child_layer<'a>(graph: &'a NodeNetwork, node: &DocumentNode) -> Option<(&'a DocumentNode, NodeId)> {
151-
graph.upstream_flow_back_from_nodes(vec![node.primary_input()?.as_node()?], true).find(|(node, _)| node.is_layer())
151+
graph.upstream_flow_back_from_nodes(vec![node.primary_input()?.as_node()?], true).find(|(node, _)| node.is_layer)
152152
}
153153

154154
self.structure = HashMap::from_iter([(LayerNodeIdentifier::ROOT, NodeRelations::default())]);
@@ -157,8 +157,9 @@ impl DocumentMetadata {
157157
self.hidden = HashSet::new();
158158
self.locked = HashSet::new();
159159

160-
let id = graph.exports[0].node_id;
161-
let Some(output_node) = graph.nodes.get(&id) else {
160+
// Refers to output node: NodeId(0)
161+
let output_node_id = graph.exports[0].node_id;
162+
let Some(output_node) = graph.nodes.get(&output_node_id) else {
162163
return;
163164
};
164165
let Some((layer_node, node_id)) = first_child_layer(graph, output_node) else {
@@ -351,7 +352,7 @@ impl LayerNodeIdentifier {
351352
#[track_caller]
352353
pub fn new(node_id: NodeId, network: &NodeNetwork) -> Self {
353354
debug_assert!(
354-
node_id == LayerNodeIdentifier::ROOT.to_node() || network.nodes.get(&node_id).is_some_and(|node| node.is_layer()),
355+
node_id == LayerNodeIdentifier::ROOT.to_node() || network.nodes.get(&node_id).is_some_and(|node| node.is_layer),
355356
"Layer identifier constructed from non-layer node {node_id}: {:#?}",
356357
network.nodes.get(&node_id)
357358
);
@@ -429,6 +430,27 @@ impl LayerNodeIdentifier {
429430
}
430431
}
431432

433+
/// TODO: Delete this. Only used for comparing to descendants() functionality in click_xray
434+
/// Returns an iterator over all artboards connected to ROOT node (output node, id = 0). Should be replaced
435+
pub fn artboard_descendants<'a>(self, metadata: &'a DocumentMetadata, network: &'a NodeNetwork) -> DescendantsIter<'a> {
436+
let front = network.nodes.get(&NodeId(0)).and_then(|document_node| {
437+
if let Some(graph_craft::document::NodeInput::Node { node_id, .. }) = document_node.inputs.get(0).as_ref() {
438+
Some(LayerNodeIdentifier::new_unchecked(*node_id))
439+
} else {
440+
None
441+
}
442+
});
443+
let back = network.nodes.get(&NodeId(0)).and_then(|document_node| {
444+
let mut current_node_id = &NodeId(0);
445+
// Loop until current node does not have an input of type Node.
446+
while let Some(graph_craft::document::NodeInput::Node { node_id, .. }) = &network.nodes.get(&current_node_id).and_then(|document_node| document_node.inputs.get(0)) {
447+
current_node_id = node_id;
448+
}
449+
Some(LayerNodeIdentifier::new_unchecked(*current_node_id))
450+
});
451+
DescendantsIter { front, back, metadata }
452+
}
453+
432454
/// Add a child towards the top of the Layers panel
433455
pub fn push_front_child(self, metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) {
434456
assert!(!metadata.structure.contains_key(&new), "Cannot add already existing layer");

editor/src/messages/tool/tool_messages/artboard_tool.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl ArtboardToolData {
125125

126126
let mut intersections = document
127127
.click_xray(input.mouse.position)
128-
.filter(|&layer| is_layer_fed_by_node_of_name(layer, &document.network, "Artboard"));
128+
.filter(|&layer| document.network.nodes.get(&layer.to_node()).map_or(false, |document_node| document_node.is_artboard()));
129129

130130
if let Some(intersection) = intersections.next() {
131131
self.selected_artboard = Some(intersection);

editor/src/node_graph_executor.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,28 @@ impl NodeRuntime {
275275
continue;
276276
};
277277

278+
enum IntrospectedData<'a> {
279+
GraphicElement(&'a graphene_core::GraphicElement),
280+
Artboard(&'a graphene_core::Artboard),
281+
}
282+
283+
let introspected_data_output = introspected_data
284+
.downcast_ref::<IORecord<Footprint, graphene_core::GraphicElement>>()
285+
.and_then(|io_data| Some(IntrospectedData::GraphicElement(&io_data.output)))
286+
.or_else(|| {
287+
introspected_data
288+
.downcast_ref::<IORecord<Footprint, graphene_core::Artboard>>()
289+
.and_then(|io_data| Some(IntrospectedData::Artboard(&io_data.output)))
290+
});
291+
292+
let graphic_element: Option<GraphicElement> = match introspected_data_output {
293+
Some(IntrospectedData::GraphicElement(graphic_element)) => Some(graphic_element.clone()),
294+
Some(IntrospectedData::Artboard(artboard)) => Some(<graphene_core::Artboard as Into<graphene_core::GraphicElement>>::into(artboard.clone())),
295+
_ => None,
296+
};
278297
// If this is `GraphicElement` data:
279298
// Regenerate click targets and thumbnails for the layers in the graph, modifying the state and updating the UI.
280-
if let Some(io_data) = introspected_data.downcast_ref::<IORecord<Footprint, graphene_core::GraphicElement>>() {
281-
let graphic_element = &io_data.output;
282-
283-
// UPDATE CLICK TARGETS
284-
285-
// Get the previously stored click targets and wipe them out, then regenerate them
299+
if let Some(graphic_element) = graphic_element {
286300
let click_targets = self.click_targets.entry(parent_network_node_id).or_default();
287301
click_targets.clear();
288302
graphic_element.add_click_targets(click_targets);

frontend/src/components/views/Graph.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@
884884
<div class="details">
885885
<!-- TODO: Allow the user to edit the name, just like in the Layers panel -->
886886
<span title={editor.instance.inDevelopmentMode() ? `Node ID: ${node.id}` : undefined} bind:offsetWidth={layerNameLabelWidths[String(node.id)]}>
887-
{node.alias || "Layer"}
887+
{node.alias}
888888
</span>
889889
</div>
890890
<IconButton

node-graph/graph-craft/src/document.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ impl<'a> Iterator for FlowIter<'a> {
815815
let node_id = self.stack.pop()?;
816816

817817
if let Some(document_node) = self.network.nodes.get(&node_id) {
818-
let skip = if document_node.is_layer() { 1 } else { 0 };
818+
let skip = if document_node.is_layer { 1 } else { 0 };
819819
let take = if self.only_follow_primary { 1 } else { usize::MAX };
820820
let inputs = document_node.inputs.iter().skip(skip).take(take);
821821

0 commit comments

Comments
 (0)