mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 08:08:12 +08:00
Move source_node_id to "editor:layer" and Vector<Upstream> to "editor:merged_layers", backed by a new 'Write Attribute' node (#4061)
* Fix click target propagation with the Rasterize node * Add the 'Write Attribute' node * Remove tag_layer in favor of the new Write Attribute node, prune redundant attribute writes * Replace the Vector<Upstream> type argument with the "editor:merged_layers" attribute
This commit is contained in:
@@ -177,33 +177,53 @@ where
|
||||
result_table
|
||||
}
|
||||
|
||||
/// Performs internal editor record-keeping that enables tools to target this network's layer.
|
||||
/// This node associates the ID of the network's parent layer to every element of output data.
|
||||
/// This technical detail may be ignored by users, and will be phased out in the future.
|
||||
/// Returns the NodeId of the user-facing parent layer node that encapsulates this sub-network.
|
||||
/// Used as the value source for stamping the `editor:layer` attribute on each row of a layer's output,
|
||||
/// which lets editor tools (e.g. selection, click target routing) trace data back to its owning layer.
|
||||
#[node_macro::node(category(""))]
|
||||
pub async fn source_node_id<T: 'n + Send + Clone>(
|
||||
_: impl Ctx,
|
||||
#[implementations(
|
||||
Table<Artboard>,
|
||||
Table<Graphic>,
|
||||
Table<Vector>,
|
||||
Table<Raster<CPU>>,
|
||||
Table<Raster<GPU>>,
|
||||
Table<Color>,
|
||||
Table<GradientStops>,
|
||||
)]
|
||||
content: Table<T>,
|
||||
node_path: Vec<NodeId>,
|
||||
) -> Table<T> {
|
||||
pub fn parent_layer(_: impl Ctx, node_path: Vec<NodeId>) -> Option<NodeId> {
|
||||
// Get the penultimate element of the node path, or None if the path is too short
|
||||
// This is used to get the ID of the user-facing parent layer node (whose network contains this internal node).
|
||||
let source_node_id = node_path.get(node_path.len().wrapping_sub(2)).copied();
|
||||
node_path.get(node_path.len().wrapping_sub(2)).copied()
|
||||
}
|
||||
|
||||
let mut content = content;
|
||||
for source_id in content.iter_attribute_values_mut_or_default::<Option<NodeId>>("source_node_id") {
|
||||
*source_id = source_node_id;
|
||||
/// Writes a per-row attribute column on the input table. The value-producing input is evaluated once per row,
|
||||
/// with the row's element index and the row itself (as a single-row table vararg) passed via context, so the
|
||||
/// upstream pipeline can return a different value per row that may be derived from the row's own data.
|
||||
/// If the column already exists, its values are replaced; if not, the column is created.
|
||||
#[node_macro::node(category("General"))]
|
||||
async fn write_attribute<T: AnyHash + Clone + Send + Sync + core_types::CacheHash, U: Clone + Send + Sync + Default + std::fmt::Debug + 'static>(
|
||||
ctx: impl ExtractAll + CloneVarArgs + Ctx,
|
||||
/// The table whose rows will gain or replace the named attribute column.
|
||||
#[implementations(
|
||||
Table<Artboard>, Table<Artboard>, Table<Artboard>, Table<Artboard>, Table<Artboard>, Table<Artboard>, Table<Artboard>,
|
||||
Table<Graphic>, Table<Graphic>, Table<Graphic>, Table<Graphic>, Table<Graphic>, Table<Graphic>, Table<Graphic>,
|
||||
Table<Vector>, Table<Vector>, Table<Vector>, Table<Vector>, Table<Vector>, Table<Vector>, Table<Vector>,
|
||||
Table<Raster<CPU>>, Table<Raster<CPU>>, Table<Raster<CPU>>, Table<Raster<CPU>>, Table<Raster<CPU>>, Table<Raster<CPU>>, Table<Raster<CPU>>,
|
||||
Table<Raster<GPU>>, Table<Raster<GPU>>, Table<Raster<GPU>>, Table<Raster<GPU>>, Table<Raster<GPU>>, Table<Raster<GPU>>, Table<Raster<GPU>>,
|
||||
Table<Color>, Table<Color>, Table<Color>, Table<Color>, Table<Color>, Table<Color>, Table<Color>,
|
||||
Table<GradientStops>, Table<GradientStops>, Table<GradientStops>, Table<GradientStops>, Table<GradientStops>, Table<GradientStops>, Table<GradientStops>,
|
||||
)]
|
||||
mut content: Table<T>,
|
||||
/// The attribute name (column key) to write or replace.
|
||||
name: String,
|
||||
/// The node that produces the per-row value. Called once per row with the row index in context.
|
||||
#[implementations(
|
||||
Context -> f64, Context -> u32, Context -> bool, Context -> String, Context -> DVec2, Context -> DAffine2, Context -> Option<NodeId>,
|
||||
Context -> f64, Context -> u32, Context -> bool, Context -> String, Context -> DVec2, Context -> DAffine2, Context -> Option<NodeId>,
|
||||
Context -> f64, Context -> u32, Context -> bool, Context -> String, Context -> DVec2, Context -> DAffine2, Context -> Option<NodeId>,
|
||||
Context -> f64, Context -> u32, Context -> bool, Context -> String, Context -> DVec2, Context -> DAffine2, Context -> Option<NodeId>,
|
||||
Context -> f64, Context -> u32, Context -> bool, Context -> String, Context -> DVec2, Context -> DAffine2, Context -> Option<NodeId>,
|
||||
Context -> f64, Context -> u32, Context -> bool, Context -> String, Context -> DVec2, Context -> DAffine2, Context -> Option<NodeId>,
|
||||
Context -> f64, Context -> u32, Context -> bool, Context -> String, Context -> DVec2, Context -> DAffine2, Context -> Option<NodeId>,
|
||||
)]
|
||||
value: impl Node<'n, Context<'static>, Output = U>,
|
||||
) -> Table<T> {
|
||||
for index in 0..content.len() {
|
||||
let row = content.clone_row(index).expect("index is within bounds");
|
||||
let owned_ctx = OwnedContextImpl::from(ctx.clone()).with_vararg(Box::new(Table::new_from_row(row))).with_index(index);
|
||||
let v = value.eval(owned_ctx.into_context()).await;
|
||||
content.set_attribute(&name, index, v);
|
||||
}
|
||||
|
||||
content
|
||||
}
|
||||
|
||||
@@ -239,11 +259,11 @@ pub async fn legacy_layer_extend<T: 'n + Send + Clone>(
|
||||
) -> Table<T> {
|
||||
// Get the penultimate element of the node path, or None if the path is too short
|
||||
// This is used to get the ID of the user-facing parent layer-style node (which encapsulates this internal node).
|
||||
let source_node_id = nested_node_path.get(nested_node_path.len().wrapping_sub(2)).copied();
|
||||
let layer = nested_node_path.get(nested_node_path.len().wrapping_sub(2)).copied();
|
||||
|
||||
let mut base = base;
|
||||
for mut row in new.into_iter() {
|
||||
row.set_attribute("source_node_id", source_node_id);
|
||||
row.set_attribute("editor:layer", layer);
|
||||
base.push(row);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user