From 887dbaca2cb9e068d5099b634131c1e320e070ca Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sat, 22 Aug 2026 12:35:48 +0000 Subject: [PATCH] Re-home the layer-path stamp and switch the node path to its plain value form --- .../data_panel/data_panel_message_handler.rs | 10 ++++++++++ node-graph/graph-craft/src/document.rs | 2 +- node-graph/graph-craft/src/document/value.rs | 20 +++++-------------- node-graph/nodes/graphic/src/graphic.rs | 15 ++++++++++++-- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs b/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs index e20e639205..817b4bad0a 100644 --- a/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs +++ b/editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs @@ -180,6 +180,11 @@ fn generate_layout(introspected_data: &Arc>() { return Some(table_node_id_path_layout_with_breadcrumb(list, data)); } + // The path's plain value form, produced by `path_of_subgraph` on leveled wires. + if let Some(path) = introspected_data.downcast_ref::>() { + let list: List = path.iter().copied().map(graphene_std::list::Item::new_from_element).collect(); + return Some(table_node_id_path_layout_with_breadcrumb(&list, data)); + } generate_layout_downcast!(introspected_data, data, [ List, List, @@ -1011,6 +1016,11 @@ fn drilldown_attribute_layout(any: &dyn Any, data: &mut LayoutData) -> Option>() { return Some(table_node_id_path_layout_with_breadcrumb(path, data)); } + // The path's plain value form, the layer-path marker's owned shape. + if let Some(path) = any.downcast_ref::>() { + let list: List = path.iter().copied().map(graphene_std::list::Item::new_from_element).collect(); + return Some(table_node_id_path_layout_with_breadcrumb(&list, data)); + } macro_rules! check { ( $($ty:ty),* $(,)? ) => { $( diff --git a/node-graph/graph-craft/src/document.rs b/node-graph/graph-craft/src/document.rs index 08d08fc267..fc1dd3ad10 100644 --- a/node-graph/graph-craft/src/document.rs +++ b/node-graph/graph-craft/src/document.rs @@ -221,7 +221,7 @@ pub enum DocumentNodeMetadata { impl DocumentNodeMetadata { pub fn ty(&self) -> Type { match self { - DocumentNodeMetadata::DocumentNodePath => concrete!(core_types::list::List), + DocumentNodeMetadata::DocumentNodePath => concrete!(Vec), DocumentNodeMetadata::SourceId => concrete!(u64), } } diff --git a/node-graph/graph-craft/src/document/value.rs b/node-graph/graph-craft/src/document/value.rs index c63822646a..cadb789a0f 100644 --- a/node-graph/graph-craft/src/document/value.rs +++ b/node-graph/graph-craft/src/document/value.rs @@ -174,10 +174,7 @@ macro_rules! tagged_value { // NON-SERIALIZED VARIANTS // ======================= Self::RenderOutput(x) => Box::new(x), - Self::NodeIdPath(path) => { - let list: List = path.into_iter().map(core_types::list::Item::new_from_element).collect(); - Box::new(list) - } + Self::NodeIdPath(path) => Box::new(path), Self::DocumentNode(node) => Box::new(node), Self::ContextModification(modification) => Box::new(modification), Self::EditorApi(x) => Box::new(x), @@ -224,10 +221,7 @@ macro_rules! tagged_value { // NON-SERIALIZED VARIANTS // ======================= Self::RenderOutput(x) => Arc::new(x), - Self::NodeIdPath(path) => { - let list: List = path.into_iter().map(core_types::list::Item::new_from_element).collect(); - Arc::new(list) - } + Self::NodeIdPath(path) => Arc::new(path), Self::DocumentNode(node) => Arc::new(node), Self::ContextModification(modification) => Arc::new(modification), Self::EditorApi(x) => Arc::new(x), @@ -255,7 +249,7 @@ macro_rules! tagged_value { // NON-SERIALIZED VARIANTS // ======================= Self::RenderOutput(_) => concrete!(RenderOutput), - Self::NodeIdPath(_) => concrete!(List), + Self::NodeIdPath(_) => concrete!(Vec), Self::DocumentNode(_) => concrete!(DocumentNode), Self::ContextModification(_) => concrete!(ContextModification), Self::EditorApi(_) => concrete!(Arc), @@ -283,7 +277,7 @@ macro_rules! tagged_value { Self::BrushStrokes(_) => core_types::record::element_write::>(), $( Self::$identifier(_) => core_types::record::element_write::<$ty>(), )* Self::RenderOutput(_) => core_types::record::element_write::(), - Self::NodeIdPath(_) => core_types::record::element_write::>(), + Self::NodeIdPath(_) => core_types::record::element_write::>(), Self::DocumentNode(_) => core_types::record::element_write::(), Self::ContextModification(_) => core_types::record::element_write::(), Self::EditorApi(_) => core_types::record::element_write::>(), @@ -330,10 +324,7 @@ macro_rules! tagged_value { // NON-SERIALIZED VARIANTS // ======================= Self::RenderOutput(x) => Ok(record_value_edge(x)), - Self::NodeIdPath(path) => { - let list: List = path.into_iter().map(core_types::list::Item::new_from_element).collect(); - Ok(record_value_edge(list)) - } + Self::NodeIdPath(path) => Ok(record_value_edge(path)), Self::DocumentNode(node) => Ok(record_value_edge(node)), Self::ContextModification(modification) => Ok(record_value_edge(modification)), Self::EditorApi(x) => Ok(record_value_edge(x)), @@ -623,7 +614,6 @@ impl TaggedValue { Self::Color(color) => Ok(leveled_record_value_edge(color.into_iter().collect::>())), Self::Gradient(stops) => Ok(leveled_record_value_edge(vec![stops])), Self::BrushStrokes(strokes) => Ok(leveled_record_value_edge(strokes)), - Self::NodeIdPath(path) => Ok(leveled_record_value_edge(path)), other => other.to_edge(), } } diff --git a/node-graph/nodes/graphic/src/graphic.rs b/node-graph/nodes/graphic/src/graphic.rs index 685caf678a..070519b09e 100644 --- a/node-graph/nodes/graphic/src/graphic.rs +++ b/node-graph/nodes/graphic/src/graphic.rs @@ -1,4 +1,4 @@ -use core_types::attribute::{Attr, Transform as TransformAttr}; +use core_types::attribute::{Attr, EditorLayerPath, Transform as TransformAttr}; use core_types::bounds::{BoundingBox, RenderBoundingBox}; use core_types::extent::{ExtentIn, LevelIn, ListIn, ValueIn}; use core_types::gpoll::{Extent, GPoll, GraphError, Interrupt, Level}; @@ -204,11 +204,22 @@ where /// editor tools (e.g. selection, click target routing) trace data back to its owning layer regardless of whether /// the layer is at the root document network or nested inside a custom subgraph. #[node_macro::node(name("Path of Subgraph"), category(""))] -pub fn path_of_subgraph(_: impl Ctx, node_path: List) -> List { +pub fn path_of_subgraph(_: impl Ctx, node_path: Vec) -> Vec { let len = node_path.len(); node_path.into_iter().take(len.saturating_sub(1)).collect() } +/// The layer-path stamp: writes the owning layer's document node path on +/// each lane, which lets editor tools trace data back to its layer. +#[node_macro::node(category(""))] +pub fn stamp_layer_path<'e, T>(ctx: impl Ctx + ExtractArena<'e>, element: T, path: Vec) -> Result<(T, Attr<'e, EditorLayerPath>), Interrupt> { + let (parked, _) = ctx.arena().alloc(path).ok_or(GraphError { + kind: core_types::gpoll::ErrorKind::ArenaExhausted, + trace: Vec::new(), + })?; + Ok((element, Attr(parked.as_slice()))) +} + /// Sets a named attribute on the input `List`, computing one value per item via the value-producing input. That input /// is evaluated once per item, with the item's index and the item itself (as a `List` containing only that item, /// passed as a vararg) provided via context, so the upstream pipeline can return a different value per item that may