mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 07:18:04 +08:00
Instance tables refactor part 1: wrap graphical data in the new Instances<T> struct (#2230)
* Port VectorData to Instances<VectorData> * Port ImageFrame<P> and TextureFrame to Instances<ImageFrame<P>> and Instances<TextureFrame> * Avoid mutation with the TransformMut trait * Port GraphicGroup to Instances<GraphicGroup> * It compiles! * Organize debugging * Document upgrading * Fix Brush node * Restore TransformMut in lieu of TransformSet trait * Fix tests * Final code review
This commit is contained in:
@@ -13,7 +13,6 @@ use graphene_core::vector::style::ViewMode;
|
||||
use graphene_core::Color;
|
||||
use graphene_std::renderer::ClickTarget;
|
||||
use graphene_std::transform::Footprint;
|
||||
use graphene_std::vector::VectorData;
|
||||
|
||||
use glam::DAffine2;
|
||||
|
||||
@@ -181,9 +180,6 @@ pub enum DocumentMessage {
|
||||
UpdateClipTargets {
|
||||
clip_targets: HashSet<NodeId>,
|
||||
},
|
||||
UpdateVectorModify {
|
||||
vector_modify: HashMap<NodeId, VectorData>,
|
||||
},
|
||||
Undo,
|
||||
UngroupSelectedLayers,
|
||||
UngroupLayer {
|
||||
|
||||
@@ -27,7 +27,8 @@ use crate::node_graph_executor::NodeGraphExecutor;
|
||||
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::{NodeId, NodeNetwork, OldNodeNetwork};
|
||||
use graphene_core::raster::{BlendMode, ImageFrame};
|
||||
use graphene_core::raster::image::ImageFrame;
|
||||
use graphene_core::raster::BlendMode;
|
||||
use graphene_core::vector::style::ViewMode;
|
||||
use graphene_std::renderer::{ClickTarget, Quad};
|
||||
use graphene_std::vector::path_bool_lib;
|
||||
@@ -1159,9 +1160,6 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
DocumentMessage::UpdateClipTargets { clip_targets } => {
|
||||
self.network_interface.update_clip_targets(clip_targets);
|
||||
}
|
||||
DocumentMessage::UpdateVectorModify { vector_modify } => {
|
||||
self.network_interface.update_vector_modify(vector_modify);
|
||||
}
|
||||
DocumentMessage::Undo => {
|
||||
if self.network_interface.transaction_status() != TransactionStatus::Finished {
|
||||
return;
|
||||
@@ -2126,7 +2124,7 @@ impl DocumentMessageHandler {
|
||||
/// Create a network interface with a single export
|
||||
fn default_document_network_interface() -> NodeNetworkInterface {
|
||||
let mut network_interface = NodeNetworkInterface::default();
|
||||
network_interface.add_export(TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY), -1, "", &[]);
|
||||
network_interface.add_export(TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::default()), -1, "", &[]);
|
||||
network_interface
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ use crate::messages::prelude::*;
|
||||
|
||||
use bezier_rs::Subpath;
|
||||
use graph_craft::document::NodeId;
|
||||
use graphene_core::raster::{BlendMode, ImageFrame};
|
||||
use graphene_core::raster::image::ImageFrame;
|
||||
use graphene_core::raster::BlendMode;
|
||||
use graphene_core::text::{Font, TypesettingConfig};
|
||||
use graphene_core::vector::brush_stroke::BrushStroke;
|
||||
use graphene_core::vector::style::{Fill, Stroke};
|
||||
|
||||
@@ -8,16 +8,17 @@ use bezier_rs::Subpath;
|
||||
use graph_craft::concrete;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::{NodeId, NodeInput};
|
||||
use graphene_core::raster::{BlendMode, ImageFrame};
|
||||
use graphene_core::raster::image::{ImageFrame, ImageFrameTable};
|
||||
use graphene_core::raster::BlendMode;
|
||||
use graphene_core::text::{Font, TypesettingConfig};
|
||||
use graphene_core::vector::brush_stroke::BrushStroke;
|
||||
use graphene_core::vector::style::{Fill, Stroke};
|
||||
use graphene_core::vector::{PointId, VectorModificationType};
|
||||
use graphene_core::{Artboard, Color};
|
||||
use graphene_std::vector::{VectorData, VectorDataTable};
|
||||
use graphene_std::GraphicGroupTable;
|
||||
|
||||
use glam::{DAffine2, DVec2, IVec2};
|
||||
use graphene_std::vector::VectorData;
|
||||
use graphene_std::GraphicGroup;
|
||||
|
||||
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum TransformIn {
|
||||
@@ -125,8 +126,8 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
/// Creates an artboard as the primary export for the document network
|
||||
pub fn create_artboard(&mut self, new_id: NodeId, artboard: Artboard) -> LayerNodeIdentifier {
|
||||
let artboard_node_template = resolve_document_node_type("Artboard").expect("Node").node_template_input_override([
|
||||
Some(NodeInput::value(TaggedValue::ArtboardGroup(graphene_std::ArtboardGroup::EMPTY), true)),
|
||||
Some(NodeInput::value(TaggedValue::GraphicGroup(graphene_core::GraphicGroup::EMPTY), true)),
|
||||
Some(NodeInput::value(TaggedValue::ArtboardGroup(graphene_std::ArtboardGroup::default()), true)),
|
||||
Some(NodeInput::value(TaggedValue::GraphicGroup(graphene_core::GraphicGroupTable::default()), true)),
|
||||
Some(NodeInput::value(TaggedValue::IVec2(artboard.location), false)),
|
||||
Some(NodeInput::value(TaggedValue::IVec2(artboard.dimensions), false)),
|
||||
Some(NodeInput::value(TaggedValue::Color(artboard.background), false)),
|
||||
@@ -138,7 +139,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
|
||||
pub fn insert_boolean_data(&mut self, operation: graphene_std::vector::misc::BooleanOperation, layer: LayerNodeIdentifier) {
|
||||
let boolean = resolve_document_node_type("Boolean Operation").expect("Boolean node does not exist").node_template_input_override([
|
||||
Some(NodeInput::value(TaggedValue::GraphicGroup(graphene_std::GraphicGroup::EMPTY), true)),
|
||||
Some(NodeInput::value(TaggedValue::GraphicGroup(graphene_std::GraphicGroupTable::default()), true)),
|
||||
Some(NodeInput::value(TaggedValue::BooleanOperation(operation), false)),
|
||||
]);
|
||||
|
||||
@@ -148,7 +149,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
}
|
||||
|
||||
pub fn insert_vector_data(&mut self, subpaths: Vec<Subpath<PointId>>, layer: LayerNodeIdentifier, include_transform: bool, include_fill: bool, include_stroke: bool) {
|
||||
let vector_data = VectorData::from_subpaths(subpaths, true);
|
||||
let vector_data = VectorDataTable::new(VectorData::from_subpaths(subpaths, true));
|
||||
|
||||
let shape = resolve_document_node_type("Path")
|
||||
.expect("Path node does not exist")
|
||||
@@ -213,9 +214,10 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
|
||||
pub fn insert_image_data(&mut self, image_frame: ImageFrame<Color>, layer: LayerNodeIdentifier) {
|
||||
let transform = resolve_document_node_type("Transform").expect("Transform node does not exist").default_node_template();
|
||||
let image = resolve_document_node_type("Image")
|
||||
.expect("Image node does not exist")
|
||||
.node_template_input_override([Some(NodeInput::value(TaggedValue::None, false)), Some(NodeInput::value(TaggedValue::ImageFrame(image_frame), false))]);
|
||||
let image = resolve_document_node_type("Image").expect("Image node does not exist").node_template_input_override([
|
||||
Some(NodeInput::value(TaggedValue::None, false)),
|
||||
Some(NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::new(image_frame)), false)),
|
||||
]);
|
||||
|
||||
let image_id = NodeId::new();
|
||||
self.network_interface.insert_node(image_id, image, &[]);
|
||||
@@ -289,7 +291,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
// TODO: Allow the path node to operate on Graphic Group data by utilizing the reference for each vector data in a group.
|
||||
if node_definition.identifier == "Path" {
|
||||
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]).0.nested_type();
|
||||
if layer_input_type == concrete!(GraphicGroup) {
|
||||
if layer_input_type == concrete!(GraphicGroupTable) {
|
||||
let Some(flatten_vector_elements_definition) = resolve_document_node_type("Flatten Vector Elements") else {
|
||||
log::error!("Flatten Vector Elements does not exist in ModifyInputsContext::existing_node_id");
|
||||
return None;
|
||||
|
||||
@@ -15,13 +15,13 @@ use graph_craft::document::*;
|
||||
use graph_craft::imaginate_input::ImaginateSamplingMethod;
|
||||
use graph_craft::ProtoNodeIdentifier;
|
||||
use graphene_core::raster::brush_cache::BrushCache;
|
||||
use graphene_core::raster::{CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, ImageFrame, NoiseType, RedGreenBlue, RedGreenBlueAlpha};
|
||||
use graphene_core::raster::image::ImageFrameTable;
|
||||
use graphene_core::raster::{CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, NoiseType, RedGreenBlue, RedGreenBlueAlpha};
|
||||
use graphene_core::text::{Font, TypesettingConfig};
|
||||
use graphene_core::transform::Footprint;
|
||||
use graphene_core::vector::VectorData;
|
||||
use graphene_core::vector::VectorDataTable;
|
||||
use graphene_core::*;
|
||||
use graphene_std::wasm_application_io::WasmEditorApi;
|
||||
|
||||
#[cfg(feature = "gpu")]
|
||||
use wgpu_executor::{Bindgroup, CommandBuffer, PipelineLayout, ShaderHandle, ShaderInputFrame, WgpuShaderInput};
|
||||
|
||||
@@ -40,9 +40,7 @@ pub struct NodePropertiesContext<'a> {
|
||||
|
||||
impl NodePropertiesContext<'_> {
|
||||
pub fn call_widget_override(&mut self, node_id: &NodeId, index: usize) -> Option<Vec<LayoutGroup>> {
|
||||
let Some(input_properties_row) = self.network_interface.input_properties_row(node_id, index, self.selection_network_path) else {
|
||||
return None;
|
||||
};
|
||||
let input_properties_row = self.network_interface.input_properties_row(node_id, index, self.selection_network_path)?;
|
||||
if let Some(widget_override) = &input_properties_row.widget_override {
|
||||
let Some(widget_override_lambda) = INPUT_OVERRIDES.get(widget_override) else {
|
||||
log::error!("Could not get widget override lambda in call_widget_override");
|
||||
@@ -204,8 +202,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroupTable::default()), true),
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroupTable::default()), true),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
@@ -312,8 +310,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ArtboardGroup(ArtboardGroup::EMPTY), true),
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||
NodeInput::value(TaggedValue::ArtboardGroup(ArtboardGroup::default()), true),
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroupTable::default()), true),
|
||||
NodeInput::value(TaggedValue::IVec2(glam::IVec2::ZERO), false),
|
||||
NodeInput::value(TaggedValue::IVec2(glam::IVec2::new(1920, 1080)), false),
|
||||
NodeInput::value(TaggedValue::Color(Color::WHITE), false),
|
||||
@@ -545,8 +543,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
exports: vec![NodeInput::node(NodeId(3), 0)],
|
||||
nodes: [
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrame<Color>), 0)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IntoNode<_, ImageFrame>")),
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrameTable<Color>), 0)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IntoNode<_, ImageFrame>")), // TODO: Possibly change `ImageFrame` to something else
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNode {
|
||||
@@ -573,7 +571,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true)],
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
|
||||
..Default::default()
|
||||
},
|
||||
persistent_node_metadata: DocumentNodePersistentMetadata {
|
||||
@@ -664,7 +662,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::VectorData(VectorData::default()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(VectorDataTable::default()), true),
|
||||
NodeInput::value(
|
||||
TaggedValue::Footprint(Footprint {
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::new(100., 100.), 0., DVec2::new(0., 0.)),
|
||||
@@ -811,8 +809,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_std::raster::MaskImageNode"),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
@@ -834,8 +832,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_std::raster::InsertChannelNode"),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::RedGreenBlue(RedGreenBlue::default()), false),
|
||||
],
|
||||
..Default::default()
|
||||
@@ -858,10 +856,10 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_std::raster::CombineChannelsNode"),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::None, false),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
@@ -889,7 +887,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
nodes: [
|
||||
DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::network(concrete!(ImageFrame<Color>), 0),
|
||||
NodeInput::network(concrete!(ImageFrameTable<Color>), 0),
|
||||
NodeInput::value(TaggedValue::RedGreenBlueAlpha(RedGreenBlueAlpha::Red), false),
|
||||
],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::raster::adjustments::ExtractChannelNode")),
|
||||
@@ -898,7 +896,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
},
|
||||
DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::network(concrete!(ImageFrame<Color>), 0),
|
||||
NodeInput::network(concrete!(ImageFrameTable<Color>), 0),
|
||||
NodeInput::value(TaggedValue::RedGreenBlueAlpha(RedGreenBlueAlpha::Green), false),
|
||||
],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::raster::adjustments::ExtractChannelNode")),
|
||||
@@ -907,7 +905,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
},
|
||||
DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::network(concrete!(ImageFrame<Color>), 0),
|
||||
NodeInput::network(concrete!(ImageFrameTable<Color>), 0),
|
||||
NodeInput::value(TaggedValue::RedGreenBlueAlpha(RedGreenBlueAlpha::Blue), false),
|
||||
],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::raster::adjustments::ExtractChannelNode")),
|
||||
@@ -916,7 +914,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
},
|
||||
DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::network(concrete!(ImageFrame<Color>), 0),
|
||||
NodeInput::network(concrete!(ImageFrameTable<Color>), 0),
|
||||
NodeInput::value(TaggedValue::RedGreenBlueAlpha(RedGreenBlueAlpha::Alpha), false),
|
||||
],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::raster::adjustments::ExtractChannelNode")),
|
||||
@@ -931,7 +929,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true)],
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
|
||||
..Default::default()
|
||||
},
|
||||
persistent_node_metadata: DocumentNodePersistentMetadata {
|
||||
@@ -997,8 +995,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
exports: vec![NodeInput::node(NodeId(0), 0)],
|
||||
nodes: vec![DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::network(concrete!(graphene_core::raster::ImageFrame<Color>), 0),
|
||||
NodeInput::network(concrete!(graphene_core::raster::ImageFrame<Color>), 1),
|
||||
NodeInput::network(concrete!(ImageFrameTable<Color>), 0),
|
||||
NodeInput::network(concrete!(ImageFrameTable<Color>), 1),
|
||||
NodeInput::network(concrete!(Vec<graphene_core::vector::brush_stroke::BrushStroke>), 2),
|
||||
NodeInput::network(concrete!(BrushCache), 3),
|
||||
],
|
||||
@@ -1013,8 +1011,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::BrushStrokes(Vec::new()), false),
|
||||
NodeInput::value(TaggedValue::BrushCache(BrushCache::new_proto()), false),
|
||||
],
|
||||
@@ -1063,7 +1061,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
node_template: NodeTemplate {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::memo::MemoNode"),
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true)],
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
|
||||
manual_composition: Some(concrete!(())),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -1082,7 +1080,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
node_template: NodeTemplate {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::memo::ImpureMemoNode"),
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true)],
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
|
||||
manual_composition: Some(concrete!(Footprint)),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -1103,7 +1101,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
implementation: DocumentNodeImplementation::Network(NodeNetwork {
|
||||
exports: vec![NodeInput::node(NodeId(0), 0)],
|
||||
nodes: vec![DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrame<Color>), 1)],
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrameTable<Color>), 1)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::transform::CullNode")),
|
||||
manual_composition: Some(concrete!(Footprint)),
|
||||
..Default::default()
|
||||
@@ -1114,7 +1112,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), false)],
|
||||
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), false)],
|
||||
..Default::default()
|
||||
},
|
||||
persistent_node_metadata: DocumentNodePersistentMetadata {
|
||||
@@ -1809,7 +1807,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrame<Color>), 0), NodeInput::node(NodeId(0), 0)],
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrameTable<Color>), 0), NodeInput::node(NodeId(0), 0)],
|
||||
manual_composition: Some(generic!(T)),
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("wgpu_executor::UploadTextureNode")),
|
||||
..Default::default()
|
||||
@@ -1827,7 +1825,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true)],
|
||||
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
|
||||
..Default::default()
|
||||
},
|
||||
persistent_node_metadata: DocumentNodePersistentMetadata {
|
||||
@@ -1883,7 +1881,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_std::executor::MapGpuSingleImageNode"),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::DocumentNode(DocumentNode::default()), true),
|
||||
],
|
||||
..Default::default()
|
||||
@@ -1925,7 +1923,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::raster::BrightnessContrastNode"),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::F64(0.), false),
|
||||
NodeInput::value(TaggedValue::F64(0.), false),
|
||||
NodeInput::value(TaggedValue::Bool(false), false),
|
||||
@@ -1956,7 +1954,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::raster::CurvesNode"),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::value(TaggedValue::Curve(Default::default()), false),
|
||||
],
|
||||
..Default::default()
|
||||
@@ -2046,7 +2044,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
exports: vec![NodeInput::node(NodeId(1), 0)],
|
||||
nodes: vec![
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(VectorData), 0)],
|
||||
inputs: vec![NodeInput::network(concrete!(VectorDataTable), 0)],
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::memo::MonitorNode"),
|
||||
manual_composition: Some(generic!(T)),
|
||||
skip_deduplication: true,
|
||||
@@ -2066,7 +2064,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::VectorData(VectorData::empty()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(VectorDataTable::default()), true),
|
||||
NodeInput::value(TaggedValue::VectorModification(Default::default()), false),
|
||||
],
|
||||
..Default::default()
|
||||
@@ -2189,7 +2187,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
node_template: NodeTemplate {
|
||||
document_node: DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::VectorData(VectorData::empty()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(VectorDataTable::default()), true),
|
||||
NodeInput::value(TaggedValue::DVec2(DVec2::ZERO), false),
|
||||
NodeInput::value(TaggedValue::F64(0.), false),
|
||||
NodeInput::value(TaggedValue::DVec2(DVec2::ONE), false),
|
||||
@@ -2200,7 +2198,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
exports: vec![NodeInput::node(NodeId(1), 0)],
|
||||
nodes: [
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(VectorData), 0)],
|
||||
inputs: vec![NodeInput::network(concrete!(VectorDataTable), 0)],
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::memo::MonitorNode"),
|
||||
manual_composition: Some(generic!(T)),
|
||||
skip_deduplication: true,
|
||||
@@ -2296,7 +2294,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
exports: vec![NodeInput::node(NodeId(1), 0)],
|
||||
nodes: vec![
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(VectorData), 0), NodeInput::network(concrete!(vector::style::Fill), 1)],
|
||||
inputs: vec![NodeInput::network(concrete!(VectorDataTable), 0), NodeInput::network(concrete!(vector::style::Fill), 1)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::vector::BooleanOperationNode")),
|
||||
manual_composition: Some(generic!(T)),
|
||||
..Default::default()
|
||||
@@ -2315,7 +2313,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroupTable::default()), true),
|
||||
NodeInput::value(TaggedValue::BooleanOperation(vector::misc::BooleanOperation::Union), false),
|
||||
],
|
||||
..Default::default()
|
||||
@@ -2366,8 +2364,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
// TODO: Wrap this implementation with a document node that has a cache node so the output is cached?
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::vector::CopyToPointsNode"),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorDataTable::default()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorDataTable::default()), true),
|
||||
NodeInput::value(TaggedValue::F64(1.), false),
|
||||
NodeInput::value(TaggedValue::F64(1.), false),
|
||||
NodeInput::value(TaggedValue::F64(0.), false),
|
||||
@@ -2463,14 +2461,14 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
exports: vec![NodeInput::node(NodeId(2), 0)], // Taken from output 0 of Sample Points
|
||||
nodes: [
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(graphene_core::vector::VectorData), 0)],
|
||||
inputs: vec![NodeInput::network(concrete!(graphene_core::vector::VectorDataTable), 0)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::vector::SubpathSegmentLengthsNode")),
|
||||
manual_composition: Some(generic!(T)),
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::network(concrete!(graphene_core::vector::VectorData), 0),
|
||||
NodeInput::network(concrete!(graphene_core::vector::VectorDataTable), 0),
|
||||
NodeInput::network(concrete!(f64), 1), // From the document node's parameters
|
||||
NodeInput::network(concrete!(f64), 2), // From the document node's parameters
|
||||
NodeInput::network(concrete!(f64), 3), // From the document node's parameters
|
||||
@@ -2495,7 +2493,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorDataTable::default()), true),
|
||||
NodeInput::value(TaggedValue::F64(100.), false),
|
||||
NodeInput::value(TaggedValue::F64(0.), false),
|
||||
NodeInput::value(TaggedValue::F64(0.), false),
|
||||
@@ -2586,7 +2584,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
nodes: [
|
||||
DocumentNode {
|
||||
inputs: vec![
|
||||
NodeInput::network(concrete!(graphene_core::vector::VectorData), 0),
|
||||
NodeInput::network(concrete!(graphene_core::vector::VectorDataTable), 0),
|
||||
NodeInput::network(concrete!(f64), 1),
|
||||
NodeInput::network(concrete!(u32), 2),
|
||||
],
|
||||
@@ -2608,7 +2606,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
|
||||
NodeInput::value(TaggedValue::VectorData(graphene_core::vector::VectorDataTable::default()), true),
|
||||
NodeInput::value(TaggedValue::F64(10.), false),
|
||||
NodeInput::value(TaggedValue::U32(0), false),
|
||||
],
|
||||
@@ -2667,29 +2665,6 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
},
|
||||
},
|
||||
|
||||
description: Cow::Borrowed("TODO"),
|
||||
properties: None,
|
||||
},
|
||||
// TODO: This needs to work with resolution-aware (raster with footprint, post-Cull node) data.
|
||||
DocumentNodeDefinition {
|
||||
identifier: "Index",
|
||||
category: "Debug",
|
||||
node_template: NodeTemplate {
|
||||
document_node: DocumentNode {
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::raster::IndexNode"),
|
||||
inputs: vec![NodeInput::value(TaggedValue::Segments(vec![ImageFrame::empty()]), true), NodeInput::value(TaggedValue::U32(0), false)],
|
||||
..Default::default()
|
||||
},
|
||||
persistent_node_metadata: DocumentNodePersistentMetadata {
|
||||
input_properties: vec![
|
||||
"Segmentation".into(),
|
||||
PropertiesRow::with_override("Index", WidgetOverride::Number(NumberInputSettings { min: Some(0.), ..Default::default() })),
|
||||
],
|
||||
output_names: vec!["Image".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
|
||||
description: Cow::Borrowed("TODO"),
|
||||
properties: None,
|
||||
},
|
||||
@@ -2807,7 +2782,7 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
|
||||
exports: vec![NodeInput::node(NodeId(1), 0)],
|
||||
nodes: [
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrame<Color>), 0)],
|
||||
inputs: vec![NodeInput::network(concrete!(ImageFrameTable<Color>), 0)],
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::memo::MonitorNode"),
|
||||
manual_composition: Some(concrete!(())),
|
||||
skip_deduplication: true,
|
||||
@@ -2845,7 +2820,7 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
|
||||
NodeInput::scope("editor-api"),
|
||||
NodeInput::value(TaggedValue::ImaginateController(Default::default()), false),
|
||||
NodeInput::value(TaggedValue::F64(0.), false), // Remember to keep index used in `ImaginateRandom` updated with this entry's index
|
||||
|
||||
@@ -11,8 +11,9 @@ use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, No
|
||||
use graph_craft::imaginate_input::{ImaginateMaskStartingFill, ImaginateSamplingMethod};
|
||||
use graph_craft::Type;
|
||||
use graphene_core::raster::curve::Curve;
|
||||
use graphene_core::raster::image::ImageFrameTable;
|
||||
use graphene_core::raster::{
|
||||
BlendMode, CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, ImageFrame, LuminanceCalculation, NoiseType, RedGreenBlue, RedGreenBlueAlpha, RelativeAbsolute,
|
||||
BlendMode, CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, LuminanceCalculation, NoiseType, RedGreenBlue, RedGreenBlueAlpha, RelativeAbsolute,
|
||||
SelectiveColorChoice,
|
||||
};
|
||||
use graphene_core::text::Font;
|
||||
@@ -22,8 +23,8 @@ use graphene_std::application_io::TextureFrame;
|
||||
use graphene_std::transform::Footprint;
|
||||
use graphene_std::vector::misc::BooleanOperation;
|
||||
use graphene_std::vector::style::{Fill, FillChoice, FillType, GradientStops};
|
||||
use graphene_std::vector::VectorData;
|
||||
use graphene_std::{GraphicGroup, Raster};
|
||||
use graphene_std::vector::VectorDataTable;
|
||||
use graphene_std::{GraphicGroupTable, RasterFrame};
|
||||
|
||||
use glam::{DAffine2, DVec2, IVec2, UVec2};
|
||||
|
||||
@@ -152,11 +153,11 @@ pub(crate) fn property_from_type(node_id: NodeId, index: usize, ty: &Type, numbe
|
||||
}
|
||||
Some(x) if x == TypeId::of::<Curve>() => curves_widget(document_node, node_id, index, name, true),
|
||||
Some(x) if x == TypeId::of::<GradientStops>() => color_widget(document_node, node_id, index, name, ColorButton::default().allow_none(false), true),
|
||||
Some(x) if x == TypeId::of::<VectorData>() => vector_widget(document_node, node_id, index, name, true).into(),
|
||||
Some(x) if x == TypeId::of::<Raster>() || x == TypeId::of::<ImageFrame<Color>>() || x == TypeId::of::<TextureFrame>() => {
|
||||
Some(x) if x == TypeId::of::<VectorDataTable>() => vector_widget(document_node, node_id, index, name, true).into(),
|
||||
Some(x) if x == TypeId::of::<RasterFrame>() || x == TypeId::of::<ImageFrameTable<Color>>() || x == TypeId::of::<TextureFrame>() => {
|
||||
raster_widget(document_node, node_id, index, name, true).into()
|
||||
}
|
||||
Some(x) if x == TypeId::of::<GraphicGroup>() => group_widget(document_node, node_id, index, name, true).into(),
|
||||
Some(x) if x == TypeId::of::<GraphicGroupTable>() => group_widget(document_node, node_id, index, name, true).into(),
|
||||
Some(x) if x == TypeId::of::<Footprint>() => {
|
||||
let widgets = footprint_widget(document_node, node_id, index);
|
||||
let (last, rest) = widgets.split_last().expect("Footprint widget should return multiple rows");
|
||||
|
||||
@@ -30,7 +30,7 @@ impl FrontendGraphDataType {
|
||||
| TaggedValue::F64Array4(_)
|
||||
| TaggedValue::VecF64(_)
|
||||
| TaggedValue::VecDVec2(_) => Self::Number,
|
||||
TaggedValue::GraphicGroup(_) | TaggedValue::GraphicElement(_) => Self::Group,
|
||||
TaggedValue::GraphicGroup(_) | TaggedValue::GraphicElement(_) => Self::Group, // TODO: Is GraphicElement supposed to be included here?
|
||||
TaggedValue::ArtboardGroup(_) => Self::Artboard,
|
||||
_ => Self::General,
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ use graph_craft::document::NodeId;
|
||||
use graphene_core::renderer::ClickTarget;
|
||||
use graphene_core::renderer::Quad;
|
||||
use graphene_core::transform::Footprint;
|
||||
use graphene_std::vector::PointId;
|
||||
use graphene_std::vector::VectorData;
|
||||
use graphene_std::vector::{PointId, VectorData};
|
||||
|
||||
use glam::{DAffine2, DVec2};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
@@ -1323,7 +1323,7 @@ impl NodeNetworkInterface {
|
||||
}
|
||||
|
||||
/// Layers excluding ones that are children of other layers in the list.
|
||||
/// TODO: Cache this
|
||||
// TODO: Cache this
|
||||
pub fn shallowest_unique_layers(&self, network_path: &[NodeId]) -> impl Iterator<Item = LayerNodeIdentifier> {
|
||||
let mut sorted_layers = if let Some(selected_nodes) = self.selected_nodes(network_path) {
|
||||
selected_nodes
|
||||
@@ -5977,9 +5977,11 @@ pub struct NodeNetworkPersistentMetadata {
|
||||
// Stores the transform and navigation state for the network
|
||||
pub navigation_metadata: NavigationMetadata,
|
||||
/// Stack of selection snapshots for previous history states.
|
||||
// TODO: Use `#[serde(skip)]` here instead? @TrueDoctor claims this isn't valid but hasn't satisfactorily explained how it differs from the situation where `#[serde(default)]` fills in the default value. From brief testing, skip seems to work without issue.
|
||||
#[serde(default)]
|
||||
pub selection_undo_history: VecDeque<SelectedNodes>,
|
||||
/// Stack of selection snapshots for future history states.
|
||||
// TODO: Use `#[serde(skip)]` here instead? See above.
|
||||
#[serde(default)]
|
||||
pub selection_redo_history: VecDeque<SelectedNodes>,
|
||||
}
|
||||
@@ -6016,7 +6018,7 @@ pub struct NodeNetworkTransientMetadata {
|
||||
// node_group_bounding_box: Vec<(Subpath<ManipulatorGroupId>, Vec<Nodes>)>,
|
||||
/// Cache for all outward wire connections
|
||||
pub outward_wires: TransientMetadata<HashMap<OutputConnector, Vec<InputConnector>>>,
|
||||
/// TODO: Cache all wire paths instead of calculating in Graph.svelte
|
||||
// TODO: Cache all wire paths instead of calculating in Graph.svelte
|
||||
// pub wire_paths: Vec<WirePath>
|
||||
/// All export connector click targets
|
||||
pub import_export_ports: TransientMetadata<Ports>,
|
||||
@@ -6132,7 +6134,7 @@ pub enum WidgetOverride {
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct PropertiesRow {
|
||||
/// A general datastore than can store key value pairs of any types for any input
|
||||
/// TODO: This could be simplified to just Value, and key value pairs could be stored as the Object variant
|
||||
// TODO: This could be simplified to just Value, and key value pairs could be stored as the Object variant
|
||||
pub input_data: HashMap<String, Value>,
|
||||
// An input can override a widget, which would otherwise be automatically generated from the type
|
||||
// The string is the identifier to the widget override function stored in INPUT_OVERRIDES
|
||||
@@ -6220,13 +6222,36 @@ impl PropertiesRow {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Eventually remove this migration document upgrade code
|
||||
fn migrate_output_names<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Vec<String>, D::Error> {
|
||||
use serde::Deserialize;
|
||||
|
||||
const REPLACEMENTS: [(&str, &str); 3] = [
|
||||
("VectorData", "Instances<VectorData>"),
|
||||
("GraphicGroup", "Instances<GraphicGroup>"),
|
||||
("ImageFrame", "Instances<ImageFrame>"),
|
||||
];
|
||||
|
||||
let mut names = Vec::<String>::deserialize(deserializer)?;
|
||||
|
||||
for name in names.iter_mut() {
|
||||
for (old, new) in REPLACEMENTS.iter() {
|
||||
if name == old {
|
||||
*name = new.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(names)
|
||||
}
|
||||
|
||||
/// Persistent metadata for each node in the network, which must be included when creating, serializing, and deserializing saving a node.
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct DocumentNodePersistentMetadata {
|
||||
/// The name of the node definition, as originally set by [`DocumentNodeDefinition`], used to display in the UI and to display the appropriate properties if no display name is set.
|
||||
/// TODO: Used during serialization/deserialization to prevent storing implementation or inputs (and possible other fields) if they are the same as the definition.
|
||||
/// TODO: The reference is removed once the node is modified, since the node now stores its own implementation and inputs.
|
||||
/// TODO: Implement node versioning so that references to old nodes can be updated to the new node definition.
|
||||
// TODO: Used during serialization/deserialization to prevent storing implementation or inputs (and possible other fields) if they are the same as the definition.
|
||||
// TODO: The reference is removed once the node is modified, since the node now stores its own implementation and inputs.
|
||||
// TODO: Implement node versioning so that references to old nodes can be updated to the new node definition.
|
||||
pub reference: Option<String>,
|
||||
/// A name chosen by the user for this instance of the node. Empty indicates no given name, in which case the reference name is displayed to the user in italics.
|
||||
#[serde(default)]
|
||||
@@ -6234,6 +6259,7 @@ pub struct DocumentNodePersistentMetadata {
|
||||
/// Stores metadata to override the properties in the properties panel for each input. These can either be generated automatically based on the type, or with a custom function.
|
||||
/// Must match the length of node inputs
|
||||
pub input_properties: Vec<PropertiesRow>,
|
||||
#[serde(deserialize_with = "migrate_output_names")]
|
||||
pub output_names: Vec<String>,
|
||||
/// Indicates to the UI if a primary output should be drawn for this node.
|
||||
/// True for most nodes, but the Split Channels node is an example of a node that has multiple secondary outputs but no primary output.
|
||||
|
||||
@@ -428,7 +428,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||
}
|
||||
};
|
||||
|
||||
const REPLACEMENTS: [(&str, &str); 36] = [
|
||||
const REPLACEMENTS: [(&str, &str); 35] = [
|
||||
("graphene_core::AddArtboardNode", "graphene_core::graphic_element::AppendArtboardNode"),
|
||||
("graphene_core::ConstructArtboardNode", "graphene_core::graphic_element::ToArtboardNode"),
|
||||
("graphene_core::ToGraphicElementNode", "graphene_core::graphic_element::ToElementNode"),
|
||||
@@ -445,8 +445,8 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||
("graphene_core::raster::ExtractChannelNode", "graphene_core::raster::adjustments::ExtractChannelNode"),
|
||||
("graphene_core::raster::GradientMapNode", "graphene_core::raster::adjustments::GradientMapNode"),
|
||||
("graphene_core::raster::HueSaturationNode", "graphene_core::raster::adjustments::HueSaturationNode"),
|
||||
("graphene_core::raster::IndexNode", "graphene_core::raster::adjustments::IndexNode"),
|
||||
("graphene_core::raster::InvertNode", "graphene_core::raster::adjustments::InvertNode"),
|
||||
// ("graphene_core::raster::IndexNode", "graphene_core::raster::adjustments::IndexNode"),
|
||||
("graphene_core::raster::InvertRGBNode", "graphene_core::raster::adjustments::InvertNode"),
|
||||
("graphene_core::raster::LevelsNode", "graphene_core::raster::adjustments::LevelsNode"),
|
||||
("graphene_core::raster::LuminanceNode", "graphene_core::raster::adjustments::LuminanceNode"),
|
||||
|
||||
@@ -3,7 +3,8 @@ use crate::messages::portfolio::document::utility_types::network_interface::{Flo
|
||||
use crate::messages::prelude::*;
|
||||
use bezier_rs::Subpath;
|
||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
||||
use graphene_core::raster::{BlendMode, ImageFrame};
|
||||
use graphene_core::raster::image::ImageFrame;
|
||||
use graphene_core::raster::BlendMode;
|
||||
use graphene_core::text::{Font, TypesettingConfig};
|
||||
use graphene_core::vector::style::Gradient;
|
||||
use graphene_core::vector::PointId;
|
||||
@@ -12,7 +13,7 @@ use graphene_core::Color;
|
||||
use glam::DVec2;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
/// Create a new vector layer from a vector of [`bezier_rs::Subpath`].
|
||||
/// Create a new vector layer.
|
||||
pub fn new_vector_layer(subpaths: Vec<Subpath<PointId>>, id: NodeId, parent: LayerNodeIdentifier, responses: &mut VecDeque<Message>) -> LayerNodeIdentifier {
|
||||
let insert_index = 0;
|
||||
responses.add(GraphOperationMessage::NewVectorLayer { id, subpaths, parent, insert_index });
|
||||
@@ -21,7 +22,7 @@ pub fn new_vector_layer(subpaths: Vec<Subpath<PointId>>, id: NodeId, parent: Lay
|
||||
LayerNodeIdentifier::new_unchecked(id)
|
||||
}
|
||||
|
||||
/// Create a new bitmap layer from an [`graphene_core::raster::ImageFrame<Color>`]
|
||||
/// Create a new bitmap layer.
|
||||
pub fn new_image_layer(image_frame: ImageFrame<Color>, id: NodeId, parent: LayerNodeIdentifier, responses: &mut VecDeque<Message>) -> LayerNodeIdentifier {
|
||||
let insert_index = 0;
|
||||
responses.add(GraphOperationMessage::NewBitmapLayer {
|
||||
@@ -33,7 +34,7 @@ pub fn new_image_layer(image_frame: ImageFrame<Color>, id: NodeId, parent: Layer
|
||||
LayerNodeIdentifier::new_unchecked(id)
|
||||
}
|
||||
|
||||
/// Create a new group layer from an svg
|
||||
/// Create a new group layer from an SVG string.
|
||||
pub fn new_svg_layer(svg: String, transform: glam::DAffine2, id: NodeId, parent: LayerNodeIdentifier, responses: &mut VecDeque<Message>) -> LayerNodeIdentifier {
|
||||
let insert_index = 0;
|
||||
responses.add(GraphOperationMessage::NewSvg {
|
||||
|
||||
@@ -372,7 +372,7 @@ impl Fsm for ArtboardToolFsmState {
|
||||
responses.add(GraphOperationMessage::NewArtboard {
|
||||
id,
|
||||
artboard: graphene_core::Artboard {
|
||||
graphic_group: graphene_core::GraphicGroup::EMPTY,
|
||||
graphic_group: graphene_core::GraphicGroupTable::default(),
|
||||
label: String::from("Artboard"),
|
||||
location: start.round().as_ivec2(),
|
||||
dimensions: IVec2::splat(1),
|
||||
|
||||
@@ -502,7 +502,7 @@ impl PathToolData {
|
||||
});
|
||||
|
||||
// Make handles colinear if opposite handle is zero length
|
||||
if opposite_handle_length.map_or(false, |l| l == 0.) {
|
||||
if opposite_handle_length == Some(0.) {
|
||||
shape_editor.convert_selected_manipulators_to_colinear_handles(responses, document);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user