mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 07:18:04 +08:00
Masks
This commit is contained in:
@@ -51,7 +51,9 @@ impl Editor {
|
||||
in_selected_network: &active_document.selection_network_path == breadcrumb_network_path,
|
||||
previewed_node,
|
||||
};
|
||||
let node_graph_overlay_node = generate_node_graph_overlay(node_graph_render_data, active_document.graph_fade_artwork_percentage);
|
||||
let opacity = active_document.graph_fade_artwork_percentage;
|
||||
let font_cache = self.dispatcher.message_handlers.portfolio_message_handler.persistent_data.font_cache.clone();
|
||||
let node_graph_overlay_node = generate_node_graph_overlay(node_graph_render_data, opacity, font_cache);
|
||||
Some(NodeNetwork {
|
||||
exports: vec![NodeInput::node(NodeId(0), 0)],
|
||||
nodes: vec![(NodeId(0), node_graph_overlay_node)].into_iter().collect(),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use graph_craft::{
|
||||
concrete,
|
||||
document::{DocumentNode, DocumentNodeImplementation, NodeInput, NodeNetwork, value::TaggedValue},
|
||||
@@ -5,11 +7,14 @@ use graph_craft::{
|
||||
use graphene_std::{
|
||||
node_graph_overlay::{types::NodeGraphOverlayData, ui_context::UIContext},
|
||||
table::Table,
|
||||
text::FontCache,
|
||||
uuid::NodeId,
|
||||
};
|
||||
|
||||
/// https://excalidraw.com/#json=LgKS6I4lQvGPmke06ZJyp,D9aON9vVZJAjNnZWfwy_SQ
|
||||
pub fn generate_node_graph_overlay(node_graph_overlay_data: NodeGraphOverlayData, opacity: f64) -> DocumentNode {
|
||||
pub fn generate_node_graph_overlay(node_graph_overlay_data: NodeGraphOverlayData, opacity: f64, font_cache: Arc<FontCache>) -> DocumentNode {
|
||||
let font_cache_id = NodeId::new();
|
||||
|
||||
let generate_nodes_id = NodeId::new();
|
||||
let cache_nodes_id = NodeId::new();
|
||||
let transform_nodes_id = NodeId::new();
|
||||
@@ -34,12 +39,20 @@ pub fn generate_node_graph_overlay(node_graph_overlay_data: NodeGraphOverlayData
|
||||
implementation: DocumentNodeImplementation::Network(NodeNetwork {
|
||||
exports: vec![NodeInput::node(send_overlay_id, 0)],
|
||||
nodes: vec![
|
||||
(
|
||||
font_cache_id,
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::value(TaggedValue::FontCache(font_cache), false)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(graphene_std::ops::identity::IDENTIFIER),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
// Create the nodes
|
||||
(
|
||||
generate_nodes_id,
|
||||
DocumentNode {
|
||||
call_argument: concrete!(UIContext),
|
||||
inputs: vec![NodeInput::network(concrete!(UIContext), 1)],
|
||||
inputs: vec![NodeInput::network(concrete!(UIContext), 1), NodeInput::node(font_cache_id, 0)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::node_graph_overlay::GenerateNodesNode".into()),
|
||||
..Default::default()
|
||||
},
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use graphene_core_shaders::Ctx;
|
||||
|
||||
use crate::{
|
||||
Graphic,
|
||||
node_graph_overlay::{
|
||||
background::generate_background,
|
||||
nodes_and_wires::{draw_layers, draw_nodes},
|
||||
@@ -8,8 +11,8 @@ use crate::{
|
||||
ui_context::{UIContext, UIRuntimeResponse},
|
||||
},
|
||||
table::Table,
|
||||
text::FontCache,
|
||||
transform::ApplyTransform,
|
||||
vector::Vector,
|
||||
};
|
||||
|
||||
pub mod background;
|
||||
@@ -19,31 +22,31 @@ pub mod types;
|
||||
pub mod ui_context;
|
||||
|
||||
#[node_macro::node(skip_impl)]
|
||||
pub fn generate_nodes(_: impl Ctx, node_graph_overlay_data: NodeGraphOverlayData) -> Table<Vector> {
|
||||
pub fn generate_nodes(_: impl Ctx, node_graph_overlay_data: NodeGraphOverlayData, font_cache: Arc<FontCache>) -> Table<Graphic> {
|
||||
let mut nodes_and_wires = Table::new();
|
||||
let layers = draw_layers(&node_graph_overlay_data.nodes_to_render);
|
||||
let layers = draw_layers(&node_graph_overlay_data.nodes_to_render, font_cache.as_ref());
|
||||
nodes_and_wires.extend(layers);
|
||||
|
||||
let nodes = draw_nodes(&node_graph_overlay_data.nodes_to_render);
|
||||
let nodes = draw_nodes(&node_graph_overlay_data.nodes_to_render, font_cache.as_ref());
|
||||
nodes_and_wires.extend(nodes);
|
||||
|
||||
nodes_and_wires
|
||||
}
|
||||
|
||||
#[node_macro::node(skip_impl)]
|
||||
pub fn transform_nodes(ui_context: UIContext, mut nodes: Table<Vector>) -> Table<Vector> {
|
||||
pub fn transform_nodes(ui_context: UIContext, mut nodes: Table<Graphic>) -> Table<Graphic> {
|
||||
let matrix = ui_context.transform.to_daffine2();
|
||||
nodes.apply_transform(&matrix);
|
||||
nodes.left_apply_transform(&matrix);
|
||||
nodes
|
||||
}
|
||||
|
||||
#[node_macro::node(skip_impl)]
|
||||
pub fn dot_grid_background(ui_context: UIContext, opacity: f64) -> Table<Vector> {
|
||||
generate_background(ui_context, opacity)
|
||||
pub fn dot_grid_background(ui_context: UIContext, opacity: f64) -> Table<Graphic> {
|
||||
Table::new_from_element(Graphic::Vector(generate_background(ui_context, opacity)))
|
||||
}
|
||||
|
||||
#[node_macro::node(skip_impl)]
|
||||
pub fn node_graph_ui_extend(_: impl Ctx, new: Table<Vector>, mut base: Table<Vector>) -> Table<Vector> {
|
||||
pub fn node_graph_ui_extend(_: impl Ctx, new: Table<Graphic>, mut base: Table<Graphic>) -> Table<Graphic> {
|
||||
base.extend(new);
|
||||
base
|
||||
}
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
use glam::DVec2;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphene_core_shaders::color::{AlphaMut, Color};
|
||||
use kurbo::{BezPath, Rect, RoundedRect, Shape};
|
||||
|
||||
use crate::{
|
||||
Graphic,
|
||||
bounds::{BoundingBox, RenderBoundingBox},
|
||||
node_graph_overlay::{
|
||||
consts::*,
|
||||
types::{FrontendGraphDataType, FrontendNodeToRender},
|
||||
},
|
||||
table::{Table, TableRow},
|
||||
text::{self, FontCache, TextAlign, TypesettingConfig},
|
||||
transform::ApplyTransform,
|
||||
vector::{Vector, style::Fill},
|
||||
};
|
||||
|
||||
pub fn draw_nodes(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
pub fn draw_nodes(nodes: &Vec<FrontendNodeToRender>, _font_cache: &FontCache) -> Table<Graphic> {
|
||||
let mut node_table = Table::new();
|
||||
for node_to_render in nodes {
|
||||
if let Some(frontend_node) = node_to_render.node_or_layer.node.as_ref() {
|
||||
@@ -22,15 +26,12 @@ pub fn draw_nodes(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
let height = 1 + number_of_exposed_inputs;
|
||||
let h = height as f64 * GRID_SIZE;
|
||||
|
||||
let border_rect = RoundedRect::new(x, y, x + w, y + h, 2.);
|
||||
let bez_path = border_rect.to_path(BEZ_PATH_TOLERANCE);
|
||||
let mut border_vector = Vector::from_bezpath(bez_path);
|
||||
let primary_output_color = frontend_node.outputs[0]
|
||||
.as_ref()
|
||||
.map(|primary_output| primary_output.data_type.data_color_dim())
|
||||
.unwrap_or(FrontendGraphDataType::General.data_color_dim());
|
||||
let border_color = Color::from_rgba8_no_srgb(primary_output_color).unwrap();
|
||||
border_vector.style.stroke = Some(crate::vector::style::Stroke::new(Some(border_color), 1.));
|
||||
let node_rect = RoundedRect::new(x, y, x + w, y + h, 2.);
|
||||
let node_bez_path = node_rect.to_path(BEZ_PATH_TOLERANCE);
|
||||
|
||||
// Background table
|
||||
let mut bg_table = Table::new();
|
||||
let mut bg_vector = Vector::from_bezpath(node_bez_path.clone());
|
||||
let node_color = if node_to_render.metadata.selected {
|
||||
let mut selection_color = Color::from_rgba8_no_srgb(COLOR_F_WHITE).unwrap();
|
||||
selection_color.set_alpha(0.15);
|
||||
@@ -40,37 +41,65 @@ pub fn draw_nodes(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
bg_color.set_alpha(0.33);
|
||||
bg_color
|
||||
};
|
||||
border_vector.style.fill = crate::vector::style::Fill::Solid(node_color);
|
||||
|
||||
bg_vector.style.fill = crate::vector::style::Fill::Solid(node_color.clone());
|
||||
bg_table.push(TableRow::new_from_element(bg_vector));
|
||||
// Make primary input brighter
|
||||
if number_of_exposed_inputs == 0 {
|
||||
// Draw the first row with rounded bottom corners
|
||||
node_table.push(TableRow::new_from_element(node_first_row(x, y, true)));
|
||||
bg_table.push(TableRow::new_from_element(node_first_row(x, y, false)));
|
||||
} else {
|
||||
// Draw the first row without rounded bottom corners
|
||||
node_table.push(TableRow::new_from_element(node_first_row(x, y, false)));
|
||||
// for node_index in 0..(number_of_exposed_inputs - 1) {
|
||||
// node_table.push(TableRow::new_from_element(node_secondary_row(x, y, node_index + 1, false)));
|
||||
// }
|
||||
// // Draw the last row with bottom corners
|
||||
// node_table.push(TableRow::new_from_element(node_secondary_row(x, y, number_of_exposed_inputs, true)));
|
||||
bg_table.push(TableRow::new_from_element(node_first_row(x, y, false)));
|
||||
};
|
||||
node_table.push(TableRow::new_from_element(Graphic::Vector(bg_table)));
|
||||
|
||||
node_table.push(TableRow::new_from_element(border_vector));
|
||||
// Border table
|
||||
let mut border_table = Table::new();
|
||||
let mut border_vector = Vector::from_bezpath(node_bez_path);
|
||||
let primary_output_color = frontend_node.outputs[0]
|
||||
.as_ref()
|
||||
.map(|primary_output| primary_output.data_type.data_color_dim())
|
||||
.unwrap_or(FrontendGraphDataType::General.data_color_dim());
|
||||
let border_color = Color::from_rgba8_no_srgb(primary_output_color).unwrap();
|
||||
border_vector.style.stroke = Some(crate::vector::style::Stroke::new(Some(border_color), 1.));
|
||||
border_table.push(TableRow::new_from_element(border_vector));
|
||||
node_table.push(TableRow::new_from_element(Graphic::Vector(border_table)));
|
||||
|
||||
// Border mask table
|
||||
let mut border_mask_table = Table::new();
|
||||
let mut border_masks = BezPath::new();
|
||||
if frontend_node.inputs[0].is_some() {
|
||||
let index = 0;
|
||||
border_masks.extend(Rect::new(-8., index as f64 * GRID_SIZE + 4., 8., index as f64 * GRID_SIZE + 20.).to_path(BEZ_PATH_TOLERANCE));
|
||||
}
|
||||
for index in 1..=frontend_node.inputs.iter().skip(1).filter(|input| input.is_some()).count() {
|
||||
border_masks.extend(Rect::new(-8., index as f64 * GRID_SIZE + 4., 8., index as f64 * GRID_SIZE + 20.).to_path(BEZ_PATH_TOLERANCE));
|
||||
}
|
||||
if frontend_node.outputs[0].is_some() {
|
||||
let index = 0;
|
||||
border_masks.extend(Rect::new(-8. + 5. * GRID_SIZE, index as f64 * GRID_SIZE + 4., 8. + 5. * GRID_SIZE, index as f64 * GRID_SIZE + 20.).to_path(BEZ_PATH_TOLERANCE));
|
||||
}
|
||||
for index in 1..=frontend_node.outputs.iter().skip(1).filter(|output| output.is_some()).count() {
|
||||
border_masks.extend(Rect::new(-8. + 5. * GRID_SIZE, index as f64 * GRID_SIZE + 4., 8. + 5. * GRID_SIZE, index as f64 * GRID_SIZE + 20.).to_path(BEZ_PATH_TOLERANCE));
|
||||
}
|
||||
let mut border_masks_vector = Vector::from_bezpath(border_masks);
|
||||
border_masks_vector.style.fill = Fill::Solid(node_color);
|
||||
let mut border_masks_row = TableRow::new_from_element(border_masks_vector);
|
||||
border_masks_row.alpha_blending.clip = true;
|
||||
border_masks_row.transform.left_apply_transform(&DAffine2::from_translation(DVec2::new(x, y)));
|
||||
border_mask_table.push(border_masks_row);
|
||||
node_table.push(TableRow::new_from_element(Graphic::Vector(border_mask_table)));
|
||||
}
|
||||
}
|
||||
node_table
|
||||
}
|
||||
|
||||
pub fn draw_layers(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
pub fn draw_layers(nodes: &Vec<FrontendNodeToRender>, font_cache: &FontCache) -> Table<Graphic> {
|
||||
let mut layer_table = Table::new();
|
||||
for node_to_render in nodes {
|
||||
if let Some(frontend_layer) = node_to_render.node_or_layer.layer.as_ref() {
|
||||
// First render the text too get the layer width
|
||||
let text_width: f64 = 0.;
|
||||
|
||||
// The layer position is the top left of the thumbnail
|
||||
let layer_position = DVec2::new(frontend_layer.position.x as f64 * GRID_SIZE + 0.5, frontend_layer.position.y as f64 * GRID_SIZE);
|
||||
let layer_position = DVec2::new(frontend_layer.position.x as f64 * GRID_SIZE + 12., frontend_layer.position.y as f64 * GRID_SIZE);
|
||||
|
||||
// Width from the left of the thumbnail to the left border
|
||||
let chain_width = if frontend_layer.chain_width > 0 {
|
||||
@@ -78,9 +107,39 @@ pub fn draw_layers(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
// Width from the right of the thumbnail to the right border
|
||||
let right_layer_width = text_width.max(4.5);
|
||||
let thumbnail_width = 2. * GRID_SIZE;
|
||||
|
||||
// First render the text to get the layer width
|
||||
// Create typesetting configuration
|
||||
let typesetting = TypesettingConfig {
|
||||
font_size: 14.,
|
||||
line_height_ratio: 1.2,
|
||||
character_spacing: 0.0,
|
||||
max_width: None,
|
||||
max_height: None,
|
||||
tilt: 0.0,
|
||||
align: TextAlign::Left,
|
||||
};
|
||||
|
||||
let font_blob = Some(text::load_font(font_cache.source_sans_pro()));
|
||||
let mut text_table = crate::text::to_path(&node_to_render.metadata.display_name, font_blob, typesetting, false);
|
||||
|
||||
let text_width = if let RenderBoundingBox::Rectangle(bbox) = text_table.bounding_box(DAffine2::default(), true) {
|
||||
bbox[1].x - bbox[0].x
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
|
||||
// Text starts at thumbnail + left padding
|
||||
let text_start = 12. + 8.;
|
||||
let right_text_edge = text_start + text_width;
|
||||
let rounded_text_edge = (right_text_edge as f64 / 24.).ceil() * 24.;
|
||||
|
||||
let rounded_layer_width_pixels = rounded_text_edge + 24.;
|
||||
// Subtract the left thumbnail
|
||||
let layer_right_edge_width = rounded_layer_width_pixels - 12.;
|
||||
|
||||
let right_layer_width = layer_right_edge_width.max(4.5 * GRID_SIZE);
|
||||
let thumbnail_width = 3. * GRID_SIZE;
|
||||
let full_layer_width = chain_width + thumbnail_width + right_layer_width;
|
||||
|
||||
let x0 = layer_position.x - chain_width;
|
||||
@@ -88,7 +147,8 @@ pub fn draw_layers(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
let h = 2. * GRID_SIZE;
|
||||
|
||||
// Background
|
||||
let bg_rect = RoundedRect::new(x0, y0, x0 + full_layer_width, y0 + full_layer_width, 8.);
|
||||
let mut background_table = Table::new();
|
||||
let bg_rect = RoundedRect::new(x0, y0, x0 + full_layer_width, y0 + h, 8.);
|
||||
let bez_path = bg_rect.to_path(BEZ_PATH_TOLERANCE);
|
||||
let mut bg_vector = Vector::from_bezpath(bez_path);
|
||||
let mut background = if node_to_render.metadata.selected {
|
||||
@@ -97,18 +157,22 @@ pub fn draw_layers(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
Color::from_rgba8_no_srgb(COLOR_0_BLACK).unwrap()
|
||||
};
|
||||
background.set_alpha(0.33);
|
||||
bg_vector.style.fill = crate::vector::style::Fill::Solid(background);
|
||||
layer_table.push(TableRow::new_from_element(bg_vector));
|
||||
bg_vector.style.fill = Fill::Solid(background.clone());
|
||||
background_table.push(TableRow::new_from_element(bg_vector));
|
||||
layer_table.push(TableRow::new_from_element(Graphic::Vector(background_table)));
|
||||
|
||||
// Border
|
||||
let border_rect = RoundedRect::new(x0, y0, x0 + full_layer_width, y0 + full_layer_width, 8.);
|
||||
let mut border_table = Table::new();
|
||||
let border_rect = RoundedRect::new(x0, y0, x0 + full_layer_width, y0 + h, 8.);
|
||||
let bez_path = border_rect.to_path(BEZ_PATH_TOLERANCE);
|
||||
let mut border_vector = Vector::from_bezpath(bez_path);
|
||||
let border_color = Color::from_rgba8_no_srgb(COLOR_5_DULLGRAY).unwrap();
|
||||
border_vector.style.stroke = Some(crate::vector::style::Stroke::new(Some(border_color), 1.));
|
||||
layer_table.push(TableRow::new_from_element(border_vector));
|
||||
border_table.push(TableRow::new_from_element(border_vector));
|
||||
layer_table.push(TableRow::new_from_element(Graphic::Vector(border_table)));
|
||||
|
||||
// Border mask
|
||||
let mut border_mask_table = Table::new();
|
||||
let mut border_mask = BezPath::new();
|
||||
if frontend_layer.layer_has_left_border_gap && chain_width > 0.1 {
|
||||
let left_input_mask = Rect::new(-8., 16., 8., 32.);
|
||||
@@ -118,12 +182,24 @@ pub fn draw_layers(nodes: &Vec<FrontendNodeToRender>) -> Table<Vector> {
|
||||
border_mask.extend(thumbnail_mask.to_path(BEZ_PATH_TOLERANCE));
|
||||
let right_visibility_mask = Rect::new(full_layer_width - 12., 12., full_layer_width + 12., 36.);
|
||||
border_mask.extend(right_visibility_mask.to_path(BEZ_PATH_TOLERANCE));
|
||||
let border_mask_vector = Vector::from_bezpath(border_mask);
|
||||
let mut border_mask = TableRow::new_from_element(border_mask_vector);
|
||||
border_mask.alpha_blending.clip = true;
|
||||
layer_table.push(border_mask);
|
||||
let mut border_mask_vector = Vector::from_bezpath(border_mask);
|
||||
border_mask_vector.style.fill = Fill::Solid(background);
|
||||
let mut border_mask_row = TableRow::new_from_element(border_mask_vector);
|
||||
border_mask_row.alpha_blending.clip = true;
|
||||
border_mask_row.transform.left_apply_transform(&DAffine2::from_translation(DVec2::new(x0, y0)));
|
||||
border_mask_table.push(border_mask_row);
|
||||
layer_table.push(TableRow::new_from_element(Graphic::Vector(border_mask_table)));
|
||||
|
||||
// The top layer contains the ports,thumbnail,text, etc
|
||||
for text_row in text_table.iter_mut() {
|
||||
text_row.element.style.fill = Fill::Solid(Color::WHITE);
|
||||
*text_row.transform = DAffine2::from_translation(layer_position + DVec2::new(thumbnail_width + text_start, 16.));
|
||||
}
|
||||
let top_layer = text_table;
|
||||
layer_table.push(TableRow::new_from_element(Graphic::Vector(top_layer)));
|
||||
}
|
||||
}
|
||||
|
||||
layer_table
|
||||
}
|
||||
|
||||
@@ -133,6 +209,8 @@ fn node_first_row(x0: f64, y0: f64, rounded_bottom: bool) -> Vector {
|
||||
let r = 2.;
|
||||
|
||||
let bez_path = if rounded_bottom {
|
||||
RoundedRect::new(x0, y0, x1, y1, r).to_path(BEZ_PATH_TOLERANCE)
|
||||
} else {
|
||||
let mut path = BezPath::new();
|
||||
// Start at bottom-left
|
||||
path.move_to((x0, y1));
|
||||
@@ -157,8 +235,6 @@ fn node_first_row(x0: f64, y0: f64, rounded_bottom: bool) -> Vector {
|
||||
|
||||
path.close_path();
|
||||
path
|
||||
} else {
|
||||
RoundedRect::new(x0, y0, x1, y1, r).to_path(BEZ_PATH_TOLERANCE)
|
||||
};
|
||||
|
||||
let mut vector = Vector::from_bezpath(bez_path);
|
||||
|
||||
@@ -24,6 +24,7 @@ use graphene_std::gradient::GradientStops;
|
||||
use graphene_std::node_graph_overlay::types::NodeGraphOverlayData;
|
||||
use graphene_std::node_graph_overlay::ui_context::UIContext;
|
||||
use graphene_std::table::Table;
|
||||
use graphene_std::text::FontCache;
|
||||
use graphene_std::transform::Footprint;
|
||||
use graphene_std::uuid::NodeId;
|
||||
use graphene_std::vector::Vector;
|
||||
@@ -253,11 +254,11 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
||||
node_io
|
||||
},
|
||||
),
|
||||
async_node!(graphene_core::node_graph_overlay::GenerateNodesNode<_>, input: UIContext, fn_params: [UIContext => NodeGraphOverlayData]),
|
||||
async_node!(graphene_core::node_graph_overlay::TransformNodesNode<_>, input: UIContext, fn_params: [UIContext =>Table<Vector>]),
|
||||
async_node!(graphene_core::node_graph_overlay::GenerateNodesNode<_, _>, input: UIContext, fn_params: [UIContext => NodeGraphOverlayData, UIContext => Arc<FontCache>]),
|
||||
async_node!(graphene_core::node_graph_overlay::TransformNodesNode<_>, input: UIContext, fn_params: [UIContext =>Table<Graphic>]),
|
||||
async_node!(graphene_core::node_graph_overlay::DotGridBackgroundNode<_>, input: UIContext, fn_params: [UIContext =>f64]),
|
||||
async_node!(graphene_core::node_graph_overlay::NodeGraphUiExtendNode<_, _>, input: UIContext, fn_params: [UIContext =>Table<Vector>, UIContext =>Table<Vector>]),
|
||||
async_node!(graphene_std::wasm_application_io::RenderNodeGraphUiNode<_>, input: UIContext, fn_params: [UIContext =>Table<Vector>]),
|
||||
async_node!(graphene_core::node_graph_overlay::NodeGraphUiExtendNode<_, _>, input: UIContext, fn_params: [UIContext =>Table<Graphic>, UIContext =>Table<Graphic>]),
|
||||
async_node!(graphene_std::wasm_application_io::RenderNodeGraphUiNode<_>, input: UIContext, fn_params: [UIContext =>Table<Graphic>]),
|
||||
async_node!(graphene_core::node_graph_overlay::SendRenderNode<_>, input: UIContext, fn_params: [UIContext => String]),
|
||||
];
|
||||
// =============
|
||||
|
||||
Reference in New Issue
Block a user