Migrate text layers to nodes (#1155)

* Initial work towards text to node

* Add the text generate node

* Implement live edit

* Fix merge error

* Cleanup text tool

* Implement text

* Fix transforms

* Fix broken image frame

* Double click to edit text

* Fix rendering text on load

* Moving whilst editing

* Better text properties

* Prevent changing vector when there is a Text node

* Push node api

* Use node fn macro

* Stable ids

* Image module as a seperate file

* Explain check for "Input Frame" node

* Code review

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube
2023-04-27 03:07:43 +01:00
committed by Keavon Chambers
parent 271f9d5158
commit ef93f8442a
44 changed files with 1082 additions and 1143 deletions

View File

@@ -324,20 +324,19 @@ impl NodeNetwork {
}
/// Appends a new node to the network after the output node and sets it as the new output
pub fn push_node(&mut self, mut node: DocumentNode) -> NodeId {
pub fn push_node(&mut self, mut node: DocumentNode, connect_to_previous: bool) -> NodeId {
let id = self.nodes.len().try_into().expect("Too many nodes in network");
// Set the correct position for the new node
if let Some(pos) = self.nodes.get(&self.original_outputs()[0].node_id).map(|n| n.metadata.position) {
if let Some(pos) = self.original_outputs().first().and_then(|first| self.nodes.get(&first.node_id)).map(|n| n.metadata.position) {
node.metadata.position = pos + IVec2::new(8, 0);
}
if self.outputs.is_empty() {
self.outputs.push(NodeOutput::new(id, 0));
}
let input = NodeInput::node(self.outputs[0].node_id, self.outputs[0].node_output_index);
if node.inputs.is_empty() {
node.inputs.push(input);
} else {
node.inputs[0] = input;
if connect_to_previous && !self.outputs.is_empty() {
let input = NodeInput::node(self.outputs[0].node_id, self.outputs[0].node_output_index);
if node.inputs.is_empty() {
node.inputs.push(input);
} else {
node.inputs[0] = input;
}
}
self.nodes.insert(id, node);
self.outputs = vec![NodeOutput::new(id, 0)];
@@ -352,7 +351,7 @@ impl NodeNetwork {
implementation: DocumentNodeImplementation::Unresolved("graphene_core::ops::IdNode".into()),
metadata: DocumentNodeMetadata { position: (0, 0).into() },
};
self.push_node(node)
self.push_node(node, true)
}
/// Adds a Cache and a Clone node to the network
@@ -389,7 +388,7 @@ impl NodeNetwork {
}),
metadata: DocumentNodeMetadata { position: (0, 0).into() },
};
self.push_node(node)
self.push_node(node, true)
}
/// Get the nested network given by the path of node ids

View File

@@ -52,8 +52,10 @@ pub enum TaggedValue {
Quantization(graphene_core::quantization::QuantizationChannels),
OptionalColor(Option<graphene_core::raster::color::Color>),
ManipulatorGroupIds(Vec<graphene_core::uuid::ManipulatorGroupId>),
Font(graphene_core::text::Font),
VecDVec2(Vec<DVec2>),
Segments(Vec<graphene_core::raster::ImageFrame<Color>>),
EditorApi(graphene_core::EditorApi<'static>),
DocumentNode(DocumentNode),
}
@@ -115,6 +117,7 @@ impl Hash for TaggedValue {
Self::Quantization(quantized_image) => quantized_image.hash(state),
Self::OptionalColor(color) => color.hash(state),
Self::ManipulatorGroupIds(mirror) => mirror.hash(state),
Self::Font(font) => font.hash(state),
Self::VecDVec2(vec_dvec2) => {
vec_dvec2.len().hash(state);
for dvec2 in vec_dvec2 {
@@ -126,9 +129,8 @@ impl Hash for TaggedValue {
segment.hash(state)
}
}
Self::DocumentNode(document_node) => {
document_node.hash(state);
}
Self::EditorApi(editor_api) => editor_api.hash(state),
Self::DocumentNode(document_node) => document_node.hash(state),
}
}
}
@@ -173,8 +175,10 @@ impl<'a> TaggedValue {
TaggedValue::Quantization(x) => Box::new(x),
TaggedValue::OptionalColor(x) => Box::new(x),
TaggedValue::ManipulatorGroupIds(x) => Box::new(x),
TaggedValue::Font(x) => Box::new(x),
TaggedValue::VecDVec2(x) => Box::new(x),
TaggedValue::Segments(x) => Box::new(x),
TaggedValue::EditorApi(x) => Box::new(x),
TaggedValue::DocumentNode(x) => Box::new(x),
}
}
@@ -231,8 +235,10 @@ impl<'a> TaggedValue {
TaggedValue::Quantization(_) => concrete!(graphene_core::quantization::QuantizationChannels),
TaggedValue::OptionalColor(_) => concrete!(Option<graphene_core::Color>),
TaggedValue::ManipulatorGroupIds(_) => concrete!(Vec<graphene_core::uuid::ManipulatorGroupId>),
TaggedValue::Font(_) => concrete!(graphene_core::text::Font),
TaggedValue::VecDVec2(_) => concrete!(Vec<DVec2>),
TaggedValue::Segments(_) => concrete!(graphene_core::raster::IndexNode<Vec<graphene_core::raster::ImageFrame<Color>>>),
TaggedValue::EditorApi(_) => concrete!(graphene_core::EditorApi),
TaggedValue::DocumentNode(_) => concrete!(crate::document::DocumentNode),
}
}