Refactor naming to deprecate "node graph frame" terminology (#1187)
This commit is contained in:
parent
3f17207a32
commit
dcabd6c0b4
|
|
@ -2,7 +2,7 @@ use crate::boolean_ops::composite_boolean_operation;
|
||||||
use crate::intersection::Quad;
|
use crate::intersection::Quad;
|
||||||
use crate::layers::folder_layer::FolderLayer;
|
use crate::layers::folder_layer::FolderLayer;
|
||||||
use crate::layers::layer_info::{Layer, LayerData, LayerDataType, LayerDataTypeDiscriminant};
|
use crate::layers::layer_info::{Layer, LayerData, LayerDataType, LayerDataTypeDiscriminant};
|
||||||
use crate::layers::nodegraph_layer::{CachedOutputData, NodeGraphFrameLayer};
|
use crate::layers::layer_layer::{CachedOutputData, LayerLayer};
|
||||||
use crate::layers::shape_layer::ShapeLayer;
|
use crate::layers::shape_layer::ShapeLayer;
|
||||||
use crate::layers::style::RenderData;
|
use crate::layers::style::RenderData;
|
||||||
use crate::{DocumentError, DocumentResponse, Operation};
|
use crate::{DocumentError, DocumentResponse, Operation};
|
||||||
|
|
@ -514,13 +514,13 @@ impl Document {
|
||||||
|
|
||||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||||
}
|
}
|
||||||
Operation::AddNodeGraphFrame {
|
Operation::AddFrame {
|
||||||
path,
|
path,
|
||||||
insert_index,
|
insert_index,
|
||||||
transform,
|
transform,
|
||||||
network,
|
network,
|
||||||
} => {
|
} => {
|
||||||
let layer = Layer::new(LayerDataType::NodeGraphFrame(NodeGraphFrameLayer { network, ..Default::default() }), transform);
|
let layer = Layer::new(LayerDataType::Layer(LayerLayer { network, ..Default::default() }), transform);
|
||||||
|
|
||||||
self.set_layer(&path, layer, insert_index)?;
|
self.set_layer(&path, layer, insert_index)?;
|
||||||
|
|
||||||
|
|
@ -694,11 +694,11 @@ impl Document {
|
||||||
Operation::SetLayerBlobUrl { layer_path, blob_url, resolution: _ } => {
|
Operation::SetLayerBlobUrl { layer_path, blob_url, resolution: _ } => {
|
||||||
let layer = self.layer_mut(&layer_path).unwrap_or_else(|_| panic!("Blob URL for invalid layer with path '{:?}'", layer_path));
|
let layer = self.layer_mut(&layer_path).unwrap_or_else(|_| panic!("Blob URL for invalid layer with path '{:?}'", layer_path));
|
||||||
|
|
||||||
let LayerDataType::NodeGraphFrame(node_graph_frame) = &mut layer.data else {
|
let LayerDataType::Layer(layer) = &mut layer.data else {
|
||||||
panic!("Incorrectly trying to set the image blob URL for a layer that is not a NodeGraphFrame layer type");
|
panic!("Incorrectly trying to set the image blob URL for a layer that is not a 'Layer' layer type");
|
||||||
};
|
};
|
||||||
|
|
||||||
node_graph_frame.cached_output_data = CachedOutputData::BlobURL(blob_url);
|
layer.cached_output_data = CachedOutputData::BlobURL(blob_url);
|
||||||
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
self.mark_as_dirty(&layer_path)?;
|
||||||
Some([vec![DocumentChanged, LayerChanged { path: layer_path.clone() }], update_thumbnails_upstream(&layer_path)].concat())
|
Some([vec![DocumentChanged, LayerChanged { path: layer_path.clone() }], update_thumbnails_upstream(&layer_path)].concat())
|
||||||
|
|
@ -706,9 +706,9 @@ impl Document {
|
||||||
Operation::ClearBlobURL { path } => {
|
Operation::ClearBlobURL { path } => {
|
||||||
let layer = self.layer_mut(&path).expect("Clearing node graph image for invalid layer");
|
let layer = self.layer_mut(&path).expect("Clearing node graph image for invalid layer");
|
||||||
match &mut layer.data {
|
match &mut layer.data {
|
||||||
LayerDataType::NodeGraphFrame(node_graph) => {
|
LayerDataType::Layer(layer) => {
|
||||||
if matches!(node_graph.cached_output_data, CachedOutputData::BlobURL(_)) {
|
if matches!(layer.cached_output_data, CachedOutputData::BlobURL(_)) {
|
||||||
node_graph.cached_output_data = CachedOutputData::None;
|
layer.cached_output_data = CachedOutputData::None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e => panic!("Incorrectly trying to clear the blob URL for layer of type {}", LayerDataTypeDiscriminant::from(&*e)),
|
e => panic!("Incorrectly trying to clear the blob URL for layer of type {}", LayerDataTypeDiscriminant::from(&*e)),
|
||||||
|
|
@ -737,8 +737,8 @@ impl Document {
|
||||||
Some(vec![DocumentChanged, LayerChanged { path }])
|
Some(vec![DocumentChanged, LayerChanged { path }])
|
||||||
}
|
}
|
||||||
Operation::SetVectorData { path, vector_data } => {
|
Operation::SetVectorData { path, vector_data } => {
|
||||||
if let LayerDataType::NodeGraphFrame(graph) = &mut self.layer_mut(&path)?.data {
|
if let LayerDataType::Layer(layer) = &mut self.layer_mut(&path)?.data {
|
||||||
graph.cached_output_data = CachedOutputData::VectorPath(Box::new(vector_data));
|
layer.cached_output_data = CachedOutputData::VectorPath(Box::new(vector_data));
|
||||||
}
|
}
|
||||||
Some(Vec::new())
|
Some(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::blend_mode::BlendMode;
|
use super::blend_mode::BlendMode;
|
||||||
use super::folder_layer::FolderLayer;
|
use super::folder_layer::FolderLayer;
|
||||||
use super::nodegraph_layer::NodeGraphFrameLayer;
|
use super::layer_layer::LayerLayer;
|
||||||
use super::shape_layer::ShapeLayer;
|
use super::shape_layer::ShapeLayer;
|
||||||
use super::style::{PathStyle, RenderData};
|
use super::style::{PathStyle, RenderData};
|
||||||
use crate::intersection::Quad;
|
use crate::intersection::Quad;
|
||||||
|
|
@ -22,24 +22,24 @@ pub enum LayerDataType {
|
||||||
Folder(FolderLayer),
|
Folder(FolderLayer),
|
||||||
/// A layer that wraps a [ShapeLayer] struct.
|
/// A layer that wraps a [ShapeLayer] struct.
|
||||||
Shape(ShapeLayer),
|
Shape(ShapeLayer),
|
||||||
/// A layer that wraps an [NodeGraphFrameLayer] struct.
|
/// A layer that wraps an [LayerLayer] struct.
|
||||||
NodeGraphFrame(NodeGraphFrameLayer),
|
Layer(LayerLayer),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayerDataType {
|
impl LayerDataType {
|
||||||
pub fn inner(&self) -> &dyn LayerData {
|
pub fn inner(&self) -> &dyn LayerData {
|
||||||
match self {
|
match self {
|
||||||
LayerDataType::Shape(s) => s,
|
LayerDataType::Shape(shape) => shape,
|
||||||
LayerDataType::Folder(f) => f,
|
LayerDataType::Folder(folder) => folder,
|
||||||
LayerDataType::NodeGraphFrame(n) => n,
|
LayerDataType::Layer(layer) => layer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inner_mut(&mut self) -> &mut dyn LayerData {
|
pub fn inner_mut(&mut self) -> &mut dyn LayerData {
|
||||||
match self {
|
match self {
|
||||||
LayerDataType::Shape(s) => s,
|
LayerDataType::Shape(shape) => shape,
|
||||||
LayerDataType::Folder(f) => f,
|
LayerDataType::Folder(folder) => folder,
|
||||||
LayerDataType::NodeGraphFrame(n) => n,
|
LayerDataType::Layer(layer) => layer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,8 +48,7 @@ impl LayerDataType {
|
||||||
pub enum LayerDataTypeDiscriminant {
|
pub enum LayerDataTypeDiscriminant {
|
||||||
Folder,
|
Folder,
|
||||||
Shape,
|
Shape,
|
||||||
Text,
|
Layer,
|
||||||
NodeGraphFrame,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for LayerDataTypeDiscriminant {
|
impl fmt::Display for LayerDataTypeDiscriminant {
|
||||||
|
|
@ -57,8 +56,7 @@ impl fmt::Display for LayerDataTypeDiscriminant {
|
||||||
match self {
|
match self {
|
||||||
LayerDataTypeDiscriminant::Folder => write!(f, "Folder"),
|
LayerDataTypeDiscriminant::Folder => write!(f, "Folder"),
|
||||||
LayerDataTypeDiscriminant::Shape => write!(f, "Shape"),
|
LayerDataTypeDiscriminant::Shape => write!(f, "Shape"),
|
||||||
LayerDataTypeDiscriminant::Text => write!(f, "Text"),
|
LayerDataTypeDiscriminant::Layer => write!(f, "Layer"),
|
||||||
LayerDataTypeDiscriminant::NodeGraphFrame => write!(f, "Layer"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +68,7 @@ impl From<&LayerDataType> for LayerDataTypeDiscriminant {
|
||||||
match data {
|
match data {
|
||||||
Folder(_) => LayerDataTypeDiscriminant::Folder,
|
Folder(_) => LayerDataTypeDiscriminant::Folder,
|
||||||
Shape(_) => LayerDataTypeDiscriminant::Shape,
|
Shape(_) => LayerDataTypeDiscriminant::Shape,
|
||||||
NodeGraphFrame(_) => LayerDataTypeDiscriminant::NodeGraphFrame,
|
Layer(_) => LayerDataTypeDiscriminant::Layer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,8 +81,6 @@ impl<'a> TryFrom<&'a mut Layer> for &'a mut Subpath {
|
||||||
fn try_from(layer: &'a mut Layer) -> Result<&'a mut Subpath, Self::Error> {
|
fn try_from(layer: &'a mut Layer) -> Result<&'a mut Subpath, Self::Error> {
|
||||||
match &mut layer.data {
|
match &mut layer.data {
|
||||||
LayerDataType::Shape(layer) => Ok(&mut layer.shape),
|
LayerDataType::Shape(layer) => Ok(&mut layer.shape),
|
||||||
// TODO Resolve converting text into a Subpath at the layer level
|
|
||||||
// LayerDataType::Text(text) => Some(Subpath::new(path_to_shape.to_vec(), viewport_transform, true)),
|
|
||||||
_ => Err("Did not find any shape data in the layer"),
|
_ => Err("Did not find any shape data in the layer"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -96,8 +92,6 @@ impl<'a> TryFrom<&'a Layer> for &'a Subpath {
|
||||||
fn try_from(layer: &'a Layer) -> Result<&'a Subpath, Self::Error> {
|
fn try_from(layer: &'a Layer) -> Result<&'a Subpath, Self::Error> {
|
||||||
match &layer.data {
|
match &layer.data {
|
||||||
LayerDataType::Shape(layer) => Ok(&layer.shape),
|
LayerDataType::Shape(layer) => Ok(&layer.shape),
|
||||||
// TODO Resolve converting text into a Subpath at the layer level
|
|
||||||
// LayerDataType::Text(text) => Some(Subpath::new(path_to_shape.to_vec(), viewport_transform, true)),
|
|
||||||
_ => Err("Did not find any shape data in the layer"),
|
_ => Err("Did not find any shape data in the layer"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -432,7 +426,7 @@ impl Layer {
|
||||||
|
|
||||||
pub fn as_vector_data(&self) -> Option<&VectorData> {
|
pub fn as_vector_data(&self) -> Option<&VectorData> {
|
||||||
match &self.data {
|
match &self.data {
|
||||||
LayerDataType::NodeGraphFrame(frame) => frame.as_vector_data(),
|
LayerDataType::Layer(layer) => layer.as_vector_data(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -454,34 +448,34 @@ impl Layer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable reference to the NodeNetwork
|
/// Get a mutable reference to the NodeNetwork
|
||||||
/// This operation will fail if the [Layer type](Layer::data) is not `LayerDataType::NodeGraphFrame`.
|
/// This operation will fail if the [Layer type](Layer::data) is not `LayerDataType::Layer`.
|
||||||
pub fn as_node_graph_mut(&mut self) -> Result<&mut graph_craft::document::NodeNetwork, DocumentError> {
|
pub fn as_node_graph_mut(&mut self) -> Result<&mut graph_craft::document::NodeNetwork, DocumentError> {
|
||||||
match &mut self.data {
|
match &mut self.data {
|
||||||
LayerDataType::NodeGraphFrame(frame) => Ok(&mut frame.network),
|
LayerDataType::Layer(layer) => Ok(&mut layer.network),
|
||||||
_ => Err(DocumentError::NotNodeGraph),
|
_ => Err(DocumentError::NotNodeGraph),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the NodeNetwork
|
/// Get a reference to the NodeNetwork
|
||||||
/// This operation will fail if the [Layer type](Layer::data) is not `LayerDataType::NodeGraphFrame`.
|
/// This operation will fail if the [Layer type](Layer::data) is not `LayerDataType::Layer`.
|
||||||
pub fn as_node_graph(&self) -> Result<&graph_craft::document::NodeNetwork, DocumentError> {
|
pub fn as_node_graph(&self) -> Result<&graph_craft::document::NodeNetwork, DocumentError> {
|
||||||
match &self.data {
|
match &self.data {
|
||||||
LayerDataType::NodeGraphFrame(frame) => Ok(&frame.network),
|
LayerDataType::Layer(layer) => Ok(&layer.network),
|
||||||
_ => Err(DocumentError::NotNodeGraph),
|
_ => Err(DocumentError::NotNodeGraph),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_graph_frame(&self) -> Result<&NodeGraphFrameLayer, DocumentError> {
|
pub fn as_graph_frame(&self) -> Result<&LayerLayer, DocumentError> {
|
||||||
match &self.data {
|
match &self.data {
|
||||||
LayerDataType::NodeGraphFrame(frame) => Ok(frame),
|
LayerDataType::Layer(layer) => Ok(layer),
|
||||||
_ => Err(DocumentError::NotNodeGraph),
|
_ => Err(DocumentError::NotNodeGraph),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style(&self) -> Result<&PathStyle, DocumentError> {
|
pub fn style(&self) -> Result<&PathStyle, DocumentError> {
|
||||||
match &self.data {
|
match &self.data {
|
||||||
LayerDataType::Shape(s) => Ok(&s.style),
|
LayerDataType::Shape(shape) => Ok(&shape.style),
|
||||||
LayerDataType::NodeGraphFrame(t) => t.as_vector_data().map(|vector| &vector.style).ok_or(DocumentError::NotShape),
|
LayerDataType::Layer(layer) => layer.as_vector_data().map(|vector| &vector.style).ok_or(DocumentError::NotShape),
|
||||||
_ => Err(DocumentError::NotShape),
|
_ => Err(DocumentError::NotShape),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ pub enum CachedOutputData {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct NodeGraphFrameLayer {
|
pub struct LayerLayer {
|
||||||
/// The document node network that this layer contains
|
/// The document node network that this layer contains
|
||||||
pub network: graph_craft::document::NodeNetwork,
|
pub network: graph_craft::document::NodeNetwork,
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ pub struct NodeGraphFrameLayer {
|
||||||
pub cached_output_data: CachedOutputData,
|
pub cached_output_data: CachedOutputData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayerData for NodeGraphFrameLayer {
|
impl LayerData for LayerLayer {
|
||||||
fn render(&mut self, svg: &mut String, svg_defs: &mut String, transforms: &mut Vec<DAffine2>, render_data: &RenderData) -> bool {
|
fn render(&mut self, svg: &mut String, svg_defs: &mut String, transforms: &mut Vec<DAffine2>, render_data: &RenderData) -> bool {
|
||||||
let transform = self.transform(transforms, render_data.view_mode);
|
let transform = self.transform(transforms, render_data.view_mode);
|
||||||
let inverse = transform.inverse();
|
let inverse = transform.inverse();
|
||||||
|
|
@ -121,7 +121,7 @@ impl LayerData for NodeGraphFrameLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeGraphFrameLayer {
|
impl LayerLayer {
|
||||||
pub fn transform(&self, transforms: &[DAffine2], mode: ViewMode) -> DAffine2 {
|
pub fn transform(&self, transforms: &[DAffine2], mode: ViewMode) -> DAffine2 {
|
||||||
let start = match mode {
|
let start = match mode {
|
||||||
ViewMode::Outline => 0,
|
ViewMode::Outline => 0,
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
//! There are currently these different types of layers:
|
//! There are currently these different types of layers:
|
||||||
//! * [Folder layers](folder_layer::FolderLayer), which encapsulate sub-layers
|
//! * [Folder layers](folder_layer::FolderLayer), which encapsulate sub-layers
|
||||||
//! * [Shape layers](shape_layer::ShapeLayer), which contain generic SVG [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)s
|
//! * [Shape layers](shape_layer::ShapeLayer), which contain generic SVG [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)s
|
||||||
//! * [Node Graph layers](nodegraph_layer::NodegraphLayer), which contain a node graph frame
|
//! * [Layer layers](layer_layer::NodegraphLayer), which contain a node graph layer
|
||||||
//!
|
//!
|
||||||
//! Refer to the module-level documentation for detailed information on each layer.
|
//! Refer to the module-level documentation for detailed information on each layer.
|
||||||
//!
|
//!
|
||||||
|
|
@ -21,7 +21,7 @@ pub mod folder_layer;
|
||||||
/// Contains the base [Layer](layer_info::Layer) type, an abstraction over the different types of layers.
|
/// Contains the base [Layer](layer_info::Layer) type, an abstraction over the different types of layers.
|
||||||
pub mod layer_info;
|
pub mod layer_info;
|
||||||
/// Contains the [NodegraphLayer](nodegraph_layer::NodegraphLayer) type that contains a node graph.
|
/// Contains the [NodegraphLayer](nodegraph_layer::NodegraphLayer) type that contains a node graph.
|
||||||
pub mod nodegraph_layer;
|
pub mod layer_layer;
|
||||||
// TODO: Remove shape layers after rewriting the overlay system
|
// TODO: Remove shape layers after rewriting the overlay system
|
||||||
/// Contains the [ShapeLayer](shape_layer::ShapeLayer) type, a generic SVG element defined using Bezier paths.
|
/// Contains the [ShapeLayer](shape_layer::ShapeLayer) type, a generic SVG element defined using Bezier paths.
|
||||||
pub mod shape_layer;
|
pub mod shape_layer;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ pub enum Operation {
|
||||||
transform: [f64; 6],
|
transform: [f64; 6],
|
||||||
style: style::PathStyle,
|
style: style::PathStyle,
|
||||||
},
|
},
|
||||||
AddNodeGraphFrame {
|
AddFrame {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
insert_index: isize,
|
insert_index: isize,
|
||||||
transform: [f64; 6],
|
transform: [f64; 6],
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[
|
||||||
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::UpdateDocumentLayerTreeStructure),
|
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::UpdateDocumentLayerTreeStructure),
|
||||||
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::TriggerFontLoad),
|
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::TriggerFontLoad),
|
||||||
MessageDiscriminant::Broadcast(BroadcastMessageDiscriminant::TriggerEvent(BroadcastEventDiscriminant::DocumentIsDirty)),
|
MessageDiscriminant::Broadcast(BroadcastMessageDiscriminant::TriggerEvent(BroadcastEventDiscriminant::DocumentIsDirty)),
|
||||||
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::NodeGraphFrameGenerate)),
|
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::InputFrameRasterizeRegionBelowLayer)),
|
||||||
];
|
];
|
||||||
|
|
||||||
impl Dispatcher {
|
impl Dispatcher {
|
||||||
|
|
|
||||||
|
|
@ -105,16 +105,6 @@ pub enum FrontendMessage {
|
||||||
},
|
},
|
||||||
TriggerLoadAutoSaveDocuments,
|
TriggerLoadAutoSaveDocuments,
|
||||||
TriggerLoadPreferences,
|
TriggerLoadPreferences,
|
||||||
TriggerNodeGraphFrameGenerate {
|
|
||||||
#[serde(rename = "documentId")]
|
|
||||||
document_id: u64,
|
|
||||||
#[serde(rename = "layerPath")]
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
svg: String,
|
|
||||||
size: glam::DVec2,
|
|
||||||
#[serde(rename = "imaginateNode")]
|
|
||||||
imaginate_node: Option<Vec<NodeId>>,
|
|
||||||
},
|
|
||||||
TriggerOpenDocument,
|
TriggerOpenDocument,
|
||||||
TriggerPaste,
|
TriggerPaste,
|
||||||
TriggerRasterDownload {
|
TriggerRasterDownload {
|
||||||
|
|
@ -123,6 +113,16 @@ pub enum FrontendMessage {
|
||||||
mime: String,
|
mime: String,
|
||||||
size: (f64, f64),
|
size: (f64, f64),
|
||||||
},
|
},
|
||||||
|
TriggerRasterizeRegionBelowLayer {
|
||||||
|
#[serde(rename = "documentId")]
|
||||||
|
document_id: u64,
|
||||||
|
#[serde(rename = "layerPath")]
|
||||||
|
layer_path: Vec<LayerId>,
|
||||||
|
svg: String,
|
||||||
|
size: glam::DVec2,
|
||||||
|
#[serde(rename = "imaginateNodePath")]
|
||||||
|
imaginate_node_path: Option<Vec<NodeId>>,
|
||||||
|
},
|
||||||
TriggerRefreshBoundsOfViewports,
|
TriggerRefreshBoundsOfViewports,
|
||||||
TriggerRevokeBlobUrl {
|
TriggerRevokeBlobUrl {
|
||||||
url: String,
|
url: String,
|
||||||
|
|
|
||||||
|
|
@ -145,12 +145,12 @@ pub fn default_mapping() -> Mapping {
|
||||||
entry!(KeyDown(Escape); action_dispatch=ImaginateToolMessage::Abort),
|
entry!(KeyDown(Escape); action_dispatch=ImaginateToolMessage::Abort),
|
||||||
entry!(PointerMove; refresh_keys=[Alt, Shift], action_dispatch=ImaginateToolMessage::Resize { center: Alt, lock_ratio: Shift }),
|
entry!(PointerMove; refresh_keys=[Alt, Shift], action_dispatch=ImaginateToolMessage::Resize { center: Alt, lock_ratio: Shift }),
|
||||||
//
|
//
|
||||||
// NodeGraphFrameToolMessage
|
// FrameToolMessage
|
||||||
entry!(KeyDown(Lmb); action_dispatch=NodeGraphFrameToolMessage::DragStart),
|
entry!(KeyDown(Lmb); action_dispatch=FrameToolMessage::DragStart),
|
||||||
entry!(KeyUp(Lmb); action_dispatch=NodeGraphFrameToolMessage::DragStop),
|
entry!(KeyUp(Lmb); action_dispatch=FrameToolMessage::DragStop),
|
||||||
entry!(KeyDown(Rmb); action_dispatch=NodeGraphFrameToolMessage::Abort),
|
entry!(KeyDown(Rmb); action_dispatch=FrameToolMessage::Abort),
|
||||||
entry!(KeyDown(Escape); action_dispatch=NodeGraphFrameToolMessage::Abort),
|
entry!(KeyDown(Escape); action_dispatch=FrameToolMessage::Abort),
|
||||||
entry!(PointerMove; refresh_keys=[Alt, Shift], action_dispatch=NodeGraphFrameToolMessage::Resize { center: Alt, lock_ratio: Shift }),
|
entry!(PointerMove; refresh_keys=[Alt, Shift], action_dispatch=FrameToolMessage::Resize { center: Alt, lock_ratio: Shift }),
|
||||||
//
|
//
|
||||||
// EllipseToolMessage
|
// EllipseToolMessage
|
||||||
entry!(KeyDown(Lmb); action_dispatch=EllipseToolMessage::DragStart),
|
entry!(KeyDown(Lmb); action_dispatch=EllipseToolMessage::DragStart),
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,27 @@ pub enum DocumentMessage {
|
||||||
},
|
},
|
||||||
FrameClear,
|
FrameClear,
|
||||||
GroupSelectedLayers,
|
GroupSelectedLayers,
|
||||||
|
ImaginateClear {
|
||||||
|
layer_path: Vec<LayerId>,
|
||||||
|
node_id: NodeId,
|
||||||
|
cached_index: usize,
|
||||||
|
},
|
||||||
|
ImaginateGenerate {
|
||||||
|
layer_path: Vec<LayerId>,
|
||||||
|
imaginate_node: Vec<NodeId>,
|
||||||
|
},
|
||||||
|
ImaginateRandom {
|
||||||
|
layer_path: Vec<LayerId>,
|
||||||
|
imaginate_node: Vec<NodeId>,
|
||||||
|
then_generate: bool,
|
||||||
|
},
|
||||||
|
ImaginateTerminate {
|
||||||
|
layer_path: Vec<LayerId>,
|
||||||
|
node_path: Vec<NodeId>,
|
||||||
|
},
|
||||||
|
InputFrameRasterizeRegionBelowLayer {
|
||||||
|
layer_path: Vec<LayerId>,
|
||||||
|
},
|
||||||
LayerChanged {
|
LayerChanged {
|
||||||
affected_layer_path: Vec<LayerId>,
|
affected_layer_path: Vec<LayerId>,
|
||||||
},
|
},
|
||||||
|
|
@ -95,27 +116,6 @@ pub enum DocumentMessage {
|
||||||
insert_index: isize,
|
insert_index: isize,
|
||||||
reverse_index: bool,
|
reverse_index: bool,
|
||||||
},
|
},
|
||||||
NodeGraphFrameClear {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
node_id: NodeId,
|
|
||||||
cached_index: usize,
|
|
||||||
},
|
|
||||||
NodeGraphFrameGenerate {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
},
|
|
||||||
NodeGraphFrameImaginate {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
imaginate_node: Vec<NodeId>,
|
|
||||||
},
|
|
||||||
NodeGraphFrameImaginateRandom {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
imaginate_node: Vec<NodeId>,
|
|
||||||
then_generate: bool,
|
|
||||||
},
|
|
||||||
NodeGraphFrameImaginateTerminate {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
node_path: Vec<NodeId>,
|
|
||||||
},
|
|
||||||
NudgeSelectedLayers {
|
NudgeSelectedLayers {
|
||||||
delta_x: f64,
|
delta_x: f64,
|
||||||
delta_y: f64,
|
delta_y: f64,
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ use document_legacy::document::Document as DocumentLegacy;
|
||||||
use document_legacy::layers::blend_mode::BlendMode;
|
use document_legacy::layers::blend_mode::BlendMode;
|
||||||
use document_legacy::layers::folder_layer::FolderLayer;
|
use document_legacy::layers::folder_layer::FolderLayer;
|
||||||
use document_legacy::layers::layer_info::{LayerDataType, LayerDataTypeDiscriminant};
|
use document_legacy::layers::layer_info::{LayerDataType, LayerDataTypeDiscriminant};
|
||||||
use document_legacy::layers::nodegraph_layer::CachedOutputData;
|
use document_legacy::layers::layer_layer::CachedOutputData;
|
||||||
use document_legacy::layers::style::{RenderData, ViewMode};
|
use document_legacy::layers::style::{RenderData, ViewMode};
|
||||||
use document_legacy::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
|
use document_legacy::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
|
|
@ -394,18 +394,18 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
responses.extend([LayerChanged { affected_layer_path }.into(), DocumentStructureChanged.into()]);
|
responses.extend([LayerChanged { affected_layer_path }.into(), DocumentStructureChanged.into()]);
|
||||||
}
|
}
|
||||||
FrameClear => {
|
FrameClear => {
|
||||||
let mut selected_frame_layers = self.selected_layers_with_type(LayerDataTypeDiscriminant::NodeGraphFrame);
|
let mut selected_frame_layers = self.selected_layers_with_type(LayerDataTypeDiscriminant::Layer);
|
||||||
// Get what is hopefully the only selected NodeGraphFrame layer
|
// Get what is hopefully the only selected Layer layer
|
||||||
let layer_path = selected_frame_layers.next();
|
let layer_path = selected_frame_layers.next();
|
||||||
// Abort if we didn't have any NodeGraphFrame layer, or if there are additional ones also selected
|
// Abort if we didn't have any Layer layer, or if there are additional ones also selected
|
||||||
if layer_path.is_none() || selected_frame_layers.next().is_some() {
|
if layer_path.is_none() || selected_frame_layers.next().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let layer_path = layer_path.unwrap();
|
let layer_path = layer_path.unwrap();
|
||||||
|
|
||||||
let layer = self.document_legacy.layer(layer_path).expect("Clearing NodeGraphFrame image for invalid layer");
|
let layer = self.document_legacy.layer(layer_path).expect("Clearing Layer image for invalid layer");
|
||||||
let previous_blob_url = match &layer.data {
|
let previous_blob_url = match &layer.data {
|
||||||
LayerDataType::NodeGraphFrame(node_graph_frame) => node_graph_frame.as_blob_url(),
|
LayerDataType::Layer(layer) => layer.as_blob_url(),
|
||||||
x => panic!("Cannot find blob url for layer type {}", LayerDataTypeDiscriminant::from(x)),
|
x => panic!("Cannot find blob url for layer type {}", LayerDataTypeDiscriminant::from(x)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -437,6 +437,51 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
replacement_selected_layers: vec![new_folder_path],
|
replacement_selected_layers: vec![new_folder_path],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
ImaginateClear {
|
||||||
|
layer_path,
|
||||||
|
node_id,
|
||||||
|
cached_index: input_index,
|
||||||
|
} => {
|
||||||
|
let value = graph_craft::document::value::TaggedValue::RcImage(None);
|
||||||
|
responses.add(NodeGraphMessage::SetInputValue { node_id, input_index, value });
|
||||||
|
responses.add(InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
|
}
|
||||||
|
ImaginateGenerate { layer_path, imaginate_node } => {
|
||||||
|
if let Some(message) = self.rasterize_region_below_layer(document_id, layer_path, preferences, persistent_data, Some(imaginate_node)) {
|
||||||
|
responses.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImaginateRandom {
|
||||||
|
layer_path,
|
||||||
|
imaginate_node,
|
||||||
|
then_generate,
|
||||||
|
} => {
|
||||||
|
// Set a random seed input
|
||||||
|
responses.add(NodeGraphMessage::SetInputValue {
|
||||||
|
node_id: *imaginate_node.last().unwrap(),
|
||||||
|
// Needs to match the index of the seed parameter in `pub const IMAGINATE_NODE: DocumentNodeType` in `document_node_type.rs`
|
||||||
|
input_index: 1,
|
||||||
|
value: graph_craft::document::value::TaggedValue::F64((generate_uuid() >> 1) as f64),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate the image
|
||||||
|
if then_generate {
|
||||||
|
responses.add(DocumentMessage::ImaginateGenerate { layer_path, imaginate_node });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImaginateTerminate { layer_path, node_path } => {
|
||||||
|
responses.add(FrontendMessage::TriggerImaginateTerminate {
|
||||||
|
document_id,
|
||||||
|
layer_path,
|
||||||
|
node_path,
|
||||||
|
hostname: preferences.imaginate_server_hostname.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
InputFrameRasterizeRegionBelowLayer { layer_path } => {
|
||||||
|
if let Some(message) = self.rasterize_region_below_layer(document_id, layer_path, preferences, persistent_data, None) {
|
||||||
|
responses.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
LayerChanged { affected_layer_path } => {
|
LayerChanged { affected_layer_path } => {
|
||||||
if let Ok(layer_entry) = self.layer_panel_entry(affected_layer_path.clone(), &render_data) {
|
if let Ok(layer_entry) = self.layer_panel_entry(affected_layer_path.clone(), &render_data) {
|
||||||
responses.add(FrontendMessage::UpdateDocumentLayerDetails { data: layer_entry });
|
responses.add(FrontendMessage::UpdateDocumentLayerDetails { data: layer_entry });
|
||||||
|
|
@ -466,51 +511,6 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
insert_index,
|
insert_index,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
NodeGraphFrameClear {
|
|
||||||
layer_path,
|
|
||||||
node_id,
|
|
||||||
cached_index: input_index,
|
|
||||||
} => {
|
|
||||||
let value = graph_craft::document::value::TaggedValue::RcImage(None);
|
|
||||||
responses.add(NodeGraphMessage::SetInputValue { node_id, input_index, value });
|
|
||||||
responses.add(NodeGraphFrameGenerate { layer_path });
|
|
||||||
}
|
|
||||||
NodeGraphFrameGenerate { layer_path } => {
|
|
||||||
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, None) {
|
|
||||||
responses.add(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NodeGraphFrameImaginate { layer_path, imaginate_node } => {
|
|
||||||
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, Some(imaginate_node)) {
|
|
||||||
responses.add(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NodeGraphFrameImaginateRandom {
|
|
||||||
layer_path,
|
|
||||||
imaginate_node,
|
|
||||||
then_generate,
|
|
||||||
} => {
|
|
||||||
// Set a random seed input
|
|
||||||
responses.add(NodeGraphMessage::SetInputValue {
|
|
||||||
node_id: *imaginate_node.last().unwrap(),
|
|
||||||
// Needs to match the index of the seed parameter in `pub const IMAGINATE_NODE: DocumentNodeType` in `document_node_type.rs`
|
|
||||||
input_index: 1,
|
|
||||||
value: graph_craft::document::value::TaggedValue::F64((generate_uuid() >> 1) as f64),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Generate the image
|
|
||||||
if then_generate {
|
|
||||||
responses.add(DocumentMessage::NodeGraphFrameImaginate { layer_path, imaginate_node });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NodeGraphFrameImaginateTerminate { layer_path, node_path } => {
|
|
||||||
responses.add(FrontendMessage::TriggerImaginateTerminate {
|
|
||||||
document_id,
|
|
||||||
layer_path,
|
|
||||||
node_path,
|
|
||||||
hostname: preferences.imaginate_server_hostname.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
NudgeSelectedLayers {
|
NudgeSelectedLayers {
|
||||||
delta_x,
|
delta_x,
|
||||||
delta_y,
|
delta_y,
|
||||||
|
|
@ -622,7 +622,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
downres_node_type.to_document_node_default_inputs([Some(graph_craft::document::NodeInput::node(transform_node_id, 0))], next_pos()),
|
downres_node_type.to_document_node_default_inputs([Some(graph_craft::document::NodeInput::node(transform_node_id, 0))], next_pos()),
|
||||||
);
|
);
|
||||||
|
|
||||||
responses.add(DocumentOperation::AddNodeGraphFrame {
|
responses.add(DocumentOperation::AddFrame {
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
|
|
@ -639,7 +639,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
skip_rerender: false,
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: path });
|
||||||
|
|
||||||
// Force chosen tool to be Select Tool after importing image.
|
// Force chosen tool to be Select Tool after importing image.
|
||||||
responses.add(ToolMessage::ActivateTool { tool_type: ToolType::Select });
|
responses.add(ToolMessage::ActivateTool { tool_type: ToolType::Select });
|
||||||
|
|
@ -785,16 +785,13 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
|
|
||||||
// Revoke the old blob URL
|
// Revoke the old blob URL
|
||||||
match &layer.data {
|
match &layer.data {
|
||||||
LayerDataType::NodeGraphFrame(node_graph_frame) => {
|
LayerDataType::Layer(layer) => {
|
||||||
if let Some(url) = node_graph_frame.as_blob_url() {
|
if let Some(url) = layer.as_blob_url() {
|
||||||
responses.add(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() });
|
responses.add(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
warn!(
|
warn!("Setting blob URL for invalid layer type, which must be a `Layer` layer type. Found: `{:?}`", other);
|
||||||
"Setting blob URL for invalid layer type, which must be an `Imaginate`, `NodeGraphFrame` or `Image`. Found: `{:?}`",
|
|
||||||
other
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -961,53 +958,54 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DocumentMessageHandler {
|
impl DocumentMessageHandler {
|
||||||
pub fn call_node_graph_frame(
|
pub fn rasterize_region_below_layer(
|
||||||
&mut self,
|
&mut self,
|
||||||
document_id: u64,
|
document_id: u64,
|
||||||
layer_path: Vec<LayerId>,
|
layer_path: Vec<LayerId>,
|
||||||
_preferences: &PreferencesMessageHandler,
|
_preferences: &PreferencesMessageHandler,
|
||||||
persistent_data: &PersistentData,
|
persistent_data: &PersistentData,
|
||||||
imaginate_node: Option<Vec<NodeId>>,
|
imaginate_node_path: Option<Vec<NodeId>>,
|
||||||
) -> Option<Message> {
|
) -> Option<Message> {
|
||||||
// Prepare the node graph input image
|
// Prepare the node graph input image
|
||||||
|
|
||||||
let Some(node_network) = self.document_legacy.layer(&layer_path).ok().and_then(|layer|layer.as_node_graph().ok()) else {
|
let Some(node_network) = self.document_legacy.layer(&layer_path).ok().and_then(|layer| layer.as_node_graph().ok()) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if we use the "Input Frame" node.
|
// Check if we use the "Input Frame" node.
|
||||||
// TODO: Remove once rasterization is moved into a node.
|
// TODO: Remove once rasterization is moved into a node.
|
||||||
let input_frame = node_network.nodes.iter().find(|(_, node)| node.name == "Input Frame");
|
let input_frame_node_id = node_network.nodes.iter().find(|(_, node)| node.name == "Input Frame").map(|(&id, _)| id);
|
||||||
let input_node_id = input_frame.map(|(&id, _)| id);
|
let input_frame_connected_to_graph_output = input_frame_node_id.map_or(false, |target_node_id| node_network.connected_to_output(target_node_id, true));
|
||||||
let primary_input_type = input_node_id.filter(|&target_node_id| node_network.connected_to_output(target_node_id, true));
|
|
||||||
|
|
||||||
// Only calculate the frame if the primary input is an image
|
// If the Input Frame node is connected upstream, rasterize the artwork below this layer by calling into JS
|
||||||
let response = if primary_input_type.is_some() {
|
let response = if input_frame_connected_to_graph_output {
|
||||||
// Calculate the size of the region to be exported
|
|
||||||
let old_transforms = self.remove_document_transform();
|
let old_transforms = self.remove_document_transform();
|
||||||
|
|
||||||
|
// Calculate the size of the region to be exported and generate an SVG of the artwork below this layer within that region
|
||||||
let transform = self.document_legacy.multiply_transforms(&layer_path).unwrap();
|
let transform = self.document_legacy.multiply_transforms(&layer_path).unwrap();
|
||||||
let size = DVec2::new(transform.transform_vector2(DVec2::new(1., 0.)).length(), transform.transform_vector2(DVec2::new(0., 1.)).length());
|
let size = DVec2::new(transform.transform_vector2(DVec2::new(1., 0.)).length(), transform.transform_vector2(DVec2::new(0., 1.)).length());
|
||||||
|
|
||||||
let svg = self.render_document(size, transform.inverse(), persistent_data, DocumentRenderMode::OnlyBelowLayerInFolder(&layer_path));
|
let svg = self.render_document(size, transform.inverse(), persistent_data, DocumentRenderMode::OnlyBelowLayerInFolder(&layer_path));
|
||||||
|
|
||||||
self.restore_document_transform(old_transforms);
|
self.restore_document_transform(old_transforms);
|
||||||
|
|
||||||
FrontendMessage::TriggerNodeGraphFrameGenerate {
|
// Once JS asynchronously rasterizes the SVG, it will call the `PortfolioMessage::RenderGraphUsingRasterizedRegionBelowLayer` message with the rasterized image data
|
||||||
|
FrontendMessage::TriggerRasterizeRegionBelowLayer {
|
||||||
document_id,
|
document_id,
|
||||||
layer_path,
|
layer_path,
|
||||||
svg,
|
svg,
|
||||||
size,
|
size,
|
||||||
imaginate_node,
|
imaginate_node_path,
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
// Skip processing under node graph frame input if not connected
|
// Skip taking a round trip through JS since there's nothing to rasterize, and instead directly call the message which would otherwise be called asynchronously from JS
|
||||||
else {
|
else {
|
||||||
PortfolioMessage::ProcessNodeGraphFrame {
|
PortfolioMessage::RenderGraphUsingRasterizedRegionBelowLayer {
|
||||||
document_id,
|
document_id,
|
||||||
layer_path,
|
layer_path,
|
||||||
image_data: Default::default(),
|
input_image_data: vec![],
|
||||||
size: (0, 0),
|
size: (0, 0),
|
||||||
imaginate_node,
|
imaginate_node_path,
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
@ -1170,16 +1168,6 @@ impl DocumentMessageHandler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selected_visible_text_layers(&self) -> impl Iterator<Item = &[LayerId]> {
|
|
||||||
self.selected_layers().filter(|path| match self.document_legacy.layer(path) {
|
|
||||||
Ok(layer) => {
|
|
||||||
let discriminant: LayerDataTypeDiscriminant = (&layer.data).into();
|
|
||||||
layer.visible && discriminant == LayerDataTypeDiscriminant::Text
|
|
||||||
}
|
|
||||||
Err(_) => false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn visible_layers(&self) -> impl Iterator<Item = &[LayerId]> {
|
pub fn visible_layers(&self) -> impl Iterator<Item = &[LayerId]> {
|
||||||
self.all_layers().filter(|path| match self.document_legacy.layer(path) {
|
self.all_layers().filter(|path| match self.document_legacy.layer(path) {
|
||||||
Ok(layer) => layer.visible,
|
Ok(layer) => layer.visible,
|
||||||
|
|
@ -1543,11 +1531,11 @@ impl DocumentMessageHandler {
|
||||||
path.pop();
|
path.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LayerDataType::NodeGraphFrame(node_graph_frame) => {
|
LayerDataType::Layer(layer) => {
|
||||||
if node_graph_frame.cached_output_data == CachedOutputData::None {
|
if layer.cached_output_data == CachedOutputData::None {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: path.clone() });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: path.clone() });
|
||||||
}
|
}
|
||||||
for node in node_graph_frame.network.nodes.values() {
|
for node in layer.network.nodes.values() {
|
||||||
for input in &node.inputs {
|
for input in &node.inputs {
|
||||||
if let NodeInput::Value {
|
if let NodeInput::Value {
|
||||||
tagged_value: TaggedValue::Font(font),
|
tagged_value: TaggedValue::Font(font),
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
let layer_path = self.layer.to_vec();
|
let layer_path = self.layer.to_vec();
|
||||||
|
|
||||||
if !skip_rerender {
|
if !skip_rerender {
|
||||||
self.responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
self.responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
} else {
|
} else {
|
||||||
self.responses.add(DocumentMessage::FrameClear);
|
self.responses.add(DocumentMessage::FrameClear);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::messages::layout::utility_types::widgets::button_widgets::TextButton;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use document_legacy::document::Document;
|
use document_legacy::document::Document;
|
||||||
use document_legacy::layers::nodegraph_layer::NodeGraphFrameLayer;
|
use document_legacy::layers::layer_layer::LayerLayer;
|
||||||
use document_legacy::LayerId;
|
use document_legacy::LayerId;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, NodeOutput};
|
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, NodeOutput};
|
||||||
|
|
@ -223,8 +223,8 @@ impl NodeGraphMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collate the properties panel sections for a node graph
|
/// Collate the properties panel sections for a node graph
|
||||||
pub fn collate_properties(&self, node_graph_frame: &NodeGraphFrameLayer, context: &mut NodePropertiesContext, sections: &mut Vec<LayoutGroup>) {
|
pub fn collate_properties(&self, graph: &LayerLayer, context: &mut NodePropertiesContext, sections: &mut Vec<LayoutGroup>) {
|
||||||
let mut network = &node_graph_frame.network;
|
let mut network = &graph.network;
|
||||||
for segment in &self.nested_path {
|
for segment in &self.nested_path {
|
||||||
network = network.nodes.get(segment).and_then(|node| node.implementation.get_network()).unwrap();
|
network = network.nodes.get(segment).and_then(|node| node.implementation.get_network()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
@ -493,7 +493,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
||||||
// Only generate node graph if one of the selected nodes is connected to the output
|
// Only generate node graph if one of the selected nodes is connected to the output
|
||||||
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -683,7 +683,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
||||||
Self::send_graph(network, responses);
|
Self::send_graph(network, responses);
|
||||||
if should_rerender {
|
if should_rerender {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -699,7 +699,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
||||||
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id, true) {
|
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id, true) {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -737,7 +737,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
||||||
}
|
}
|
||||||
node.inputs[input_index] = NodeInput::Value { tagged_value: value, exposed: false };
|
node.inputs[input_index] = NodeInput::Value { tagged_value: value, exposed: false };
|
||||||
if network.connected_to_output(*node_id, true) {
|
if network.connected_to_output(*node_id, true) {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -811,7 +811,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
||||||
// Only generate node graph if one of the selected nodes is connected to the output
|
// Only generate node graph if one of the selected nodes is connected to the output
|
||||||
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -836,7 +836,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
||||||
}
|
}
|
||||||
self.update_selection_action_buttons(document, responses);
|
self.update_selection_action_buttons(document, responses);
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -934,7 +934,7 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeType> = Lazy::new(|| DocumentNodeTyp
|
||||||
identifier: NodeImplementation::proto("graphene_std::raster::ImaginateNode<_>"),
|
identifier: NodeImplementation::proto("graphene_std::raster::ImaginateNode<_>"),
|
||||||
inputs: vec![
|
inputs: vec![
|
||||||
DocumentInputType::value("Input Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
DocumentInputType::value("Input Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||||
DocumentInputType::value("Seed", TaggedValue::F64(0.), false), // Remember to keep index used in `NodeGraphFrameImaginateRandom` updated with this entry's index
|
DocumentInputType::value("Seed", TaggedValue::F64(0.), false), // Remember to keep index used in `ImaginateRandom` updated with this entry's index
|
||||||
DocumentInputType::value("Resolution", TaggedValue::OptionalDVec2(None), false),
|
DocumentInputType::value("Resolution", TaggedValue::OptionalDVec2(None), false),
|
||||||
DocumentInputType::value("Samples", TaggedValue::F64(30.), false),
|
DocumentInputType::value("Samples", TaggedValue::F64(30.), false),
|
||||||
DocumentInputType::value("Sampling Method", TaggedValue::ImaginateSamplingMethod(ImaginateSamplingMethod::EulerA), false),
|
DocumentInputType::value("Sampling Method", TaggedValue::ImaginateSamplingMethod(ImaginateSamplingMethod::EulerA), false),
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use glam::DVec2;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNode, NodeId, NodeInput};
|
use graph_craft::document::{DocumentNode, NodeId, NodeInput};
|
||||||
use graph_craft::imaginate_input::*;
|
use graph_craft::imaginate_input::*;
|
||||||
use graphene_core::raster::{BlendMode, Color, LuminanceCalculation, RedGreenBlue, RelativeAbsolute, SelectiveColorChoice};
|
use graphene_core::raster::{BlendMode, Color, ImageFrame, LuminanceCalculation, RedGreenBlue, RelativeAbsolute, SelectiveColorChoice};
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
use graphene_core::vector::style::{FillType, GradientType, LineCap, LineJoin};
|
use graphene_core::vector::style::{FillType, GradientType, LineCap, LineJoin};
|
||||||
use graphene_core::EditorApi;
|
use graphene_core::EditorApi;
|
||||||
|
|
@ -460,7 +460,7 @@ pub fn input_properties(_document_node: &DocumentNode, _node_id: NodeId, context
|
||||||
let layer_path = context.layer_path.to_vec();
|
let layer_path = context.layer_path.to_vec();
|
||||||
let refresh_button = TextButton::new("Refresh Input")
|
let refresh_button = TextButton::new("Refresh Input")
|
||||||
.tooltip("Refresh the artwork under the layer")
|
.tooltip("Refresh the artwork under the layer")
|
||||||
.on_update(move |_| DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() }.into())
|
.on_update(move |_| DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: layer_path.clone() }.into())
|
||||||
.widget_holder();
|
.widget_holder();
|
||||||
vec![LayoutGroup::Row { widgets: vec![information] }, LayoutGroup::Row { widgets: vec![refresh_button] }]
|
vec![LayoutGroup::Row { widgets: vec![information] }, LayoutGroup::Row { widgets: vec![refresh_button] }]
|
||||||
}
|
}
|
||||||
|
|
@ -1035,7 +1035,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||||
.on_update({
|
.on_update({
|
||||||
let imaginate_node = imaginate_node.clone();
|
let imaginate_node = imaginate_node.clone();
|
||||||
move |_| {
|
move |_| {
|
||||||
DocumentMessage::NodeGraphFrameImaginateTerminate {
|
DocumentMessage::ImaginateTerminate {
|
||||||
layer_path: layer_path.clone(),
|
layer_path: layer_path.clone(),
|
||||||
node_path: imaginate_node.clone(),
|
node_path: imaginate_node.clone(),
|
||||||
}
|
}
|
||||||
|
|
@ -1061,7 +1061,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||||
let imaginate_node = imaginate_node.clone();
|
let imaginate_node = imaginate_node.clone();
|
||||||
let layer_path = context.layer_path.to_vec();
|
let layer_path = context.layer_path.to_vec();
|
||||||
move |_| {
|
move |_| {
|
||||||
DocumentMessage::NodeGraphFrameImaginateRandom {
|
DocumentMessage::ImaginateRandom {
|
||||||
layer_path: layer_path.clone(),
|
layer_path: layer_path.clone(),
|
||||||
imaginate_node: imaginate_node.clone(),
|
imaginate_node: imaginate_node.clone(),
|
||||||
then_generate: true,
|
then_generate: true,
|
||||||
|
|
@ -1077,7 +1077,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||||
let imaginate_node = imaginate_node.clone();
|
let imaginate_node = imaginate_node.clone();
|
||||||
let layer_path = context.layer_path.to_vec();
|
let layer_path = context.layer_path.to_vec();
|
||||||
move |_| {
|
move |_| {
|
||||||
DocumentMessage::NodeGraphFrameImaginate {
|
DocumentMessage::ImaginateGenerate {
|
||||||
layer_path: layer_path.clone(),
|
layer_path: layer_path.clone(),
|
||||||
imaginate_node: imaginate_node.clone(),
|
imaginate_node: imaginate_node.clone(),
|
||||||
}
|
}
|
||||||
|
|
@ -1092,7 +1092,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||||
.on_update({
|
.on_update({
|
||||||
let layer_path = context.layer_path.to_vec();
|
let layer_path = context.layer_path.to_vec();
|
||||||
move |_| {
|
move |_| {
|
||||||
DocumentMessage::NodeGraphFrameClear {
|
DocumentMessage::ImaginateClear {
|
||||||
node_id,
|
node_id,
|
||||||
layer_path: layer_path.clone(),
|
layer_path: layer_path.clone(),
|
||||||
cached_index,
|
cached_index,
|
||||||
|
|
@ -1123,7 +1123,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||||
let imaginate_node = imaginate_node.clone();
|
let imaginate_node = imaginate_node.clone();
|
||||||
let layer_path = context.layer_path.to_vec();
|
let layer_path = context.layer_path.to_vec();
|
||||||
move |_| {
|
move |_| {
|
||||||
DocumentMessage::NodeGraphFrameImaginateRandom {
|
DocumentMessage::ImaginateRandom {
|
||||||
layer_path: layer_path.clone(),
|
layer_path: layer_path.clone(),
|
||||||
imaginate_node: imaginate_node.clone(),
|
imaginate_node: imaginate_node.clone(),
|
||||||
then_generate: false,
|
then_generate: false,
|
||||||
|
|
@ -1145,12 +1145,12 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the input to the graph using an empty image
|
// Create the input to the graph using an empty image
|
||||||
let image_frame = std::borrow::Cow::Owned(EditorApi {
|
let editor_api = std::borrow::Cow::Owned(EditorApi {
|
||||||
image_frame: None,
|
image_frame: None,
|
||||||
font_cache: Some(&context.persistent_data.font_cache),
|
font_cache: Some(&context.persistent_data.font_cache),
|
||||||
});
|
});
|
||||||
// Compute the transform input to the node graph frame
|
// Compute the transform input to the image frame
|
||||||
let image_frame: graphene_core::raster::ImageFrame<Color> = context.executor.compute_input(context.network, &imaginate_node, 0, image_frame).unwrap_or_default();
|
let image_frame: ImageFrame<Color> = context.executor.compute_input(context.network, &imaginate_node, 0, editor_api).unwrap_or_default();
|
||||||
let transform = image_frame.transform;
|
let transform = image_frame.transform;
|
||||||
|
|
||||||
let resolution = {
|
let resolution = {
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,11 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
||||||
} else {
|
} else {
|
||||||
let path = paths.into_iter().next().unwrap();
|
let path = paths.into_iter().next().unwrap();
|
||||||
if Some((path.clone(), document)) != self.active_selection {
|
if Some((path.clone(), document)) != self.active_selection {
|
||||||
// Update the node graph frame visibility
|
// Update the layer visibility
|
||||||
if get_document(document)
|
if get_document(document)
|
||||||
.layer(&path)
|
.layer(&path)
|
||||||
.ok()
|
.ok()
|
||||||
.filter(|layer| LayerDataTypeDiscriminant::from(&layer.data) == LayerDataTypeDiscriminant::NodeGraphFrame)
|
.filter(|layer| LayerDataTypeDiscriminant::from(&layer.data) == LayerDataTypeDiscriminant::Layer)
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
responses.add(NodeGraphMessage::OpenNodeGraph { layer_path: path.clone() });
|
responses.add(NodeGraphMessage::OpenNodeGraph { layer_path: path.clone() });
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ pub fn register_artwork_layer_properties(
|
||||||
tooltip: "Shape".into(),
|
tooltip: "Shape".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})),
|
})),
|
||||||
LayerDataType::NodeGraphFrame(_) => WidgetHolder::new(Widget::IconLabel(IconLabel {
|
LayerDataType::Layer(_) => WidgetHolder::new(Widget::IconLabel(IconLabel {
|
||||||
icon: "Layer".into(),
|
icon: "Layer".into(),
|
||||||
tooltip: "Layer".into(),
|
tooltip: "Layer".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
@ -266,7 +266,7 @@ pub fn register_artwork_layer_properties(
|
||||||
WidgetHolder::unrelated_separator(),
|
WidgetHolder::unrelated_separator(),
|
||||||
WidgetHolder::new(Widget::TextLabel(TextLabel {
|
WidgetHolder::new(Widget::TextLabel(TextLabel {
|
||||||
value: match &layer.data {
|
value: match &layer.data {
|
||||||
LayerDataType::NodeGraphFrame(_) => "Layer".into(),
|
LayerDataType::Layer(_) => "Layer".into(),
|
||||||
other => LayerDataTypeDiscriminant::from(other).to_string(),
|
other => LayerDataTypeDiscriminant::from(other).to_string(),
|
||||||
},
|
},
|
||||||
..TextLabel::default()
|
..TextLabel::default()
|
||||||
|
|
@ -298,7 +298,7 @@ pub fn register_artwork_layer_properties(
|
||||||
vec![node_section_transform(layer, persistent_data), node_section_stroke(&shape.style.stroke().unwrap_or_default())]
|
vec![node_section_transform(layer, persistent_data), node_section_stroke(&shape.style.stroke().unwrap_or_default())]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LayerDataType::NodeGraphFrame(node_graph_frame) => {
|
LayerDataType::Layer(layer) => {
|
||||||
let mut properties_sections = Vec::new();
|
let mut properties_sections = Vec::new();
|
||||||
|
|
||||||
let mut context = crate::messages::portfolio::document::node_graph::NodePropertiesContext {
|
let mut context = crate::messages::portfolio::document::node_graph::NodePropertiesContext {
|
||||||
|
|
@ -308,9 +308,9 @@ pub fn register_artwork_layer_properties(
|
||||||
nested_path: &node_graph_message_handler.nested_path,
|
nested_path: &node_graph_message_handler.nested_path,
|
||||||
layer_path: &layer_path,
|
layer_path: &layer_path,
|
||||||
executor,
|
executor,
|
||||||
network: &node_graph_frame.network,
|
network: &layer.network,
|
||||||
};
|
};
|
||||||
node_graph_message_handler.collate_properties(node_graph_frame, &mut context, &mut properties_sections);
|
node_graph_message_handler.collate_properties(layer, &mut context, &mut properties_sections);
|
||||||
|
|
||||||
properties_sections
|
properties_sections
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,12 +112,12 @@ pub enum PortfolioMessage {
|
||||||
data: String,
|
data: String,
|
||||||
},
|
},
|
||||||
PrevDocument,
|
PrevDocument,
|
||||||
ProcessNodeGraphFrame {
|
RenderGraphUsingRasterizedRegionBelowLayer {
|
||||||
document_id: u64,
|
document_id: u64,
|
||||||
layer_path: Vec<LayerId>,
|
layer_path: Vec<LayerId>,
|
||||||
image_data: Vec<u8>,
|
input_image_data: Vec<u8>,
|
||||||
size: (u32, u32),
|
size: (u32, u32),
|
||||||
imaginate_node: Option<Vec<NodeId>>,
|
imaginate_node_path: Option<Vec<NodeId>>,
|
||||||
},
|
},
|
||||||
SelectDocument {
|
SelectDocument {
|
||||||
document_id: u64,
|
document_id: u64,
|
||||||
|
|
|
||||||
|
|
@ -445,18 +445,18 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||||
responses.add(PortfolioMessage::SelectDocument { document_id: prev_id });
|
responses.add(PortfolioMessage::SelectDocument { document_id: prev_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::ProcessNodeGraphFrame {
|
PortfolioMessage::RenderGraphUsingRasterizedRegionBelowLayer {
|
||||||
document_id,
|
document_id,
|
||||||
layer_path,
|
layer_path,
|
||||||
image_data,
|
input_image_data,
|
||||||
size,
|
size,
|
||||||
imaginate_node,
|
imaginate_node_path,
|
||||||
} => {
|
} => {
|
||||||
let result = self.executor.evaluate_node_graph(
|
let result = self.executor.evaluate_node_graph(
|
||||||
(document_id, &mut self.documents),
|
(document_id, &mut self.documents),
|
||||||
layer_path,
|
layer_path,
|
||||||
(image_data, size),
|
(input_image_data, size),
|
||||||
imaginate_node,
|
imaginate_node_path,
|
||||||
(preferences, &self.persistent_data),
|
(preferences, &self.persistent_data),
|
||||||
responses,
|
responses,
|
||||||
);
|
);
|
||||||
|
|
@ -664,16 +664,16 @@ impl PortfolioMessageHandler {
|
||||||
x.push(*id);
|
x.push(*id);
|
||||||
x
|
x
|
||||||
}))),
|
}))),
|
||||||
LayerDataType::NodeGraphFrame(graph_frame) => {
|
LayerDataType::Layer(layer) => {
|
||||||
let input_is_font = |input: &NodeInput| {
|
let input_is_font = |input: &NodeInput| {
|
||||||
let NodeInput::Value { tagged_value: TaggedValue::Font(font), .. } = input else {
|
let NodeInput::Value { tagged_value: TaggedValue::Font(font), .. } = input else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
font == target_font
|
font == target_font
|
||||||
};
|
};
|
||||||
let should_rerender = graph_frame.network.nodes.values().any(|node| node.inputs.iter().any(input_is_font));
|
let should_rerender = layer.network.nodes.values().any(|node| node.inputs.iter().any(input_is_font));
|
||||||
if should_rerender {
|
if should_rerender {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ pub use crate::messages::tool::tool_messages::brush_tool::{BrushToolMessage, Bru
|
||||||
pub use crate::messages::tool::tool_messages::ellipse_tool::{EllipseToolMessage, EllipseToolMessageDiscriminant};
|
pub use crate::messages::tool::tool_messages::ellipse_tool::{EllipseToolMessage, EllipseToolMessageDiscriminant};
|
||||||
pub use crate::messages::tool::tool_messages::eyedropper_tool::{EyedropperToolMessage, EyedropperToolMessageDiscriminant};
|
pub use crate::messages::tool::tool_messages::eyedropper_tool::{EyedropperToolMessage, EyedropperToolMessageDiscriminant};
|
||||||
pub use crate::messages::tool::tool_messages::fill_tool::{FillToolMessage, FillToolMessageDiscriminant};
|
pub use crate::messages::tool::tool_messages::fill_tool::{FillToolMessage, FillToolMessageDiscriminant};
|
||||||
pub use crate::messages::tool::tool_messages::frame_tool::{NodeGraphFrameToolMessage, NodeGraphFrameToolMessageDiscriminant};
|
pub use crate::messages::tool::tool_messages::frame_tool::{FrameToolMessage, FrameToolMessageDiscriminant};
|
||||||
pub use crate::messages::tool::tool_messages::freehand_tool::{FreehandToolMessage, FreehandToolMessageDiscriminant};
|
pub use crate::messages::tool::tool_messages::freehand_tool::{FreehandToolMessage, FreehandToolMessageDiscriminant};
|
||||||
pub use crate::messages::tool::tool_messages::gradient_tool::{GradientToolMessage, GradientToolMessageDiscriminant};
|
pub use crate::messages::tool::tool_messages::gradient_tool::{GradientToolMessage, GradientToolMessageDiscriminant};
|
||||||
pub use crate::messages::tool::tool_messages::imaginate_tool::{ImaginateToolMessage, ImaginateToolMessageDiscriminant};
|
pub use crate::messages::tool::tool_messages::imaginate_tool::{ImaginateToolMessage, ImaginateToolMessageDiscriminant};
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ pub fn new_vector_layer(subpaths: Vec<Subpath<ManipulatorGroupId>>, layer_path:
|
||||||
|
|
||||||
pub fn new_custom_layer(network: NodeNetwork, layer_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
pub fn new_custom_layer(network: NodeNetwork, layer_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
||||||
responses.add(DocumentMessage::DeselectAllLayers);
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
responses.add(Operation::AddNodeGraphFrame {
|
responses.add(Operation::AddFrame {
|
||||||
path: layer_path.clone(),
|
path: layer_path.clone(),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
network,
|
network,
|
||||||
});
|
});
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_manipulator_mirror_angle(manipulator_groups: &Vec<ManipulatorGroup<ManipulatorGroupId>>, layer_path: &Vec<u64>, mirror_angle: bool, responses: &mut VecDeque<Message>) {
|
pub fn set_manipulator_mirror_angle(manipulator_groups: &Vec<ManipulatorGroup<ManipulatorGroupId>>, layer_path: &Vec<u64>, mirror_angle: bool, responses: &mut VecDeque<Message>) {
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ impl PathOutline {
|
||||||
// TODO Purge this area of BezPath and Kurbo
|
// TODO Purge this area of BezPath and Kurbo
|
||||||
// Get the bezpath from the shape or text
|
// Get the bezpath from the shape or text
|
||||||
let subpath = match &document_layer.data {
|
let subpath = match &document_layer.data {
|
||||||
LayerDataType::Shape(layer_shape) => Some(layer_shape.shape.clone()),
|
LayerDataType::Shape(shape) => Some(shape.shape.clone()),
|
||||||
LayerDataType::NodeGraphFrame(frame) => frame.as_vector_data().map(|vector_data| Subpath::from_bezier_crate(&vector_data.subpaths)),
|
LayerDataType::Layer(layer) => layer.as_vector_data().map(|vector_data| Subpath::from_bezier_crate(&vector_data.subpaths)),
|
||||||
_ => document_layer.aabb_for_transform(DAffine2::IDENTITY, render_data).map(|[p1, p2]| Subpath::new_rect(p1, p2)),
|
_ => document_layer.aabb_for_transform(DAffine2::IDENTITY, render_data).map(|[p1, p2]| Subpath::new_rect(p1, p2)),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ pub enum ToolMessage {
|
||||||
Imaginate(ImaginateToolMessage),
|
Imaginate(ImaginateToolMessage),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
#[child]
|
#[child]
|
||||||
NodeGraphFrame(NodeGraphFrameToolMessage),
|
Frame(FrameToolMessage),
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
|
|
@ -124,7 +124,7 @@ pub enum ToolMessage {
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ActivateToolImaginate,
|
ActivateToolImaginate,
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ActivateToolNodeGraphFrame,
|
ActivateToolFrame,
|
||||||
|
|
||||||
ActivateTool {
|
ActivateTool {
|
||||||
tool_type: ToolType,
|
tool_type: ToolType,
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,15 @@ use glam::DAffine2;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct NodeGraphFrameTool {
|
pub struct FrameTool {
|
||||||
fsm_state: NodeGraphToolFsmState,
|
fsm_state: NodeGraphToolFsmState,
|
||||||
tool_data: NodeGraphToolData,
|
tool_data: NodeGraphToolData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[remain::sorted]
|
#[remain::sorted]
|
||||||
#[impl_message(Message, ToolMessage, NodeGraphFrame)]
|
#[impl_message(Message, ToolMessage, Frame)]
|
||||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, Serialize, Deserialize, specta::Type)]
|
#[derive(PartialEq, Eq, Clone, Debug, Hash, Serialize, Deserialize, specta::Type)]
|
||||||
pub enum NodeGraphFrameToolMessage {
|
pub enum FrameToolMessage {
|
||||||
// Standard messages
|
// Standard messages
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
Abort,
|
Abort,
|
||||||
|
|
@ -35,9 +35,9 @@ pub enum NodeGraphFrameToolMessage {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PropertyHolder for NodeGraphFrameTool {}
|
impl PropertyHolder for FrameTool {}
|
||||||
|
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NodeGraphFrameTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FrameTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, true);
|
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, true);
|
||||||
}
|
}
|
||||||
|
|
@ -46,10 +46,10 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NodeGra
|
||||||
use NodeGraphToolFsmState::*;
|
use NodeGraphToolFsmState::*;
|
||||||
|
|
||||||
match self.fsm_state {
|
match self.fsm_state {
|
||||||
Ready => actions!(NodeGraphFrameToolMessageDiscriminant;
|
Ready => actions!(FrameToolMessageDiscriminant;
|
||||||
DragStart,
|
DragStart,
|
||||||
),
|
),
|
||||||
Drawing => actions!(NodeGraphFrameToolMessageDiscriminant;
|
Drawing => actions!(FrameToolMessageDiscriminant;
|
||||||
DragStop,
|
DragStop,
|
||||||
Abort,
|
Abort,
|
||||||
Resize,
|
Resize,
|
||||||
|
|
@ -58,7 +58,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NodeGra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToolMetadata for NodeGraphFrameTool {
|
impl ToolMetadata for FrameTool {
|
||||||
fn icon_name(&self) -> String {
|
fn icon_name(&self) -> String {
|
||||||
"RasterFrameTool".into()
|
"RasterFrameTool".into()
|
||||||
}
|
}
|
||||||
|
|
@ -66,15 +66,15 @@ impl ToolMetadata for NodeGraphFrameTool {
|
||||||
"Frame Tool".into()
|
"Frame Tool".into()
|
||||||
}
|
}
|
||||||
fn tool_type(&self) -> crate::messages::tool::utility_types::ToolType {
|
fn tool_type(&self) -> crate::messages::tool::utility_types::ToolType {
|
||||||
ToolType::NodeGraphFrame
|
ToolType::Frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToolTransition for NodeGraphFrameTool {
|
impl ToolTransition for FrameTool {
|
||||||
fn event_to_message_map(&self) -> EventToMessageMap {
|
fn event_to_message_map(&self) -> EventToMessageMap {
|
||||||
EventToMessageMap {
|
EventToMessageMap {
|
||||||
document_dirty: None,
|
document_dirty: None,
|
||||||
tool_abort: Some(NodeGraphFrameToolMessage::Abort.into()),
|
tool_abort: Some(FrameToolMessage::Abort.into()),
|
||||||
selection_changed: None,
|
selection_changed: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,12 +104,12 @@ impl Fsm for NodeGraphToolFsmState {
|
||||||
_tool_options: &Self::ToolOptions,
|
_tool_options: &Self::ToolOptions,
|
||||||
responses: &mut VecDeque<Message>,
|
responses: &mut VecDeque<Message>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
use NodeGraphFrameToolMessage::*;
|
use FrameToolMessage::*;
|
||||||
use NodeGraphToolFsmState::*;
|
use NodeGraphToolFsmState::*;
|
||||||
|
|
||||||
let mut shape_data = &mut tool_data.data;
|
let mut shape_data = &mut tool_data.data;
|
||||||
|
|
||||||
if let ToolMessage::NodeGraphFrame(event) = event {
|
if let ToolMessage::Frame(event) = event {
|
||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
shape_data.start(responses, document, input, render_data);
|
shape_data.start(responses, document, input, render_data);
|
||||||
|
|
@ -119,7 +119,7 @@ impl Fsm for NodeGraphToolFsmState {
|
||||||
|
|
||||||
let network = node_graph::new_image_network(8, 0);
|
let network = node_graph::new_image_network(8, 0);
|
||||||
|
|
||||||
responses.add(Operation::AddNodeGraphFrame {
|
responses.add(Operation::AddFrame {
|
||||||
path: shape_data.path.clone().unwrap(),
|
path: shape_data.path.clone().unwrap(),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
|
|
@ -136,7 +136,7 @@ impl Fsm for NodeGraphToolFsmState {
|
||||||
}
|
}
|
||||||
(Drawing, DragStop) => {
|
(Drawing, DragStop) => {
|
||||||
if let Some(layer_path) = &shape_data.path {
|
if let Some(layer_path) = &shape_data.path {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: layer_path.to_vec() });
|
||||||
}
|
}
|
||||||
|
|
||||||
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
||||||
|
|
|
||||||
|
|
@ -148,8 +148,8 @@ impl Fsm for ImaginateToolFsmState {
|
||||||
imaginate_node_type.to_document_node_default_inputs([Some(graph_craft::document::NodeInput::node(transform_node_id, 0))], next_pos()),
|
imaginate_node_type.to_document_node_default_inputs([Some(graph_craft::document::NodeInput::node(transform_node_id, 0))], next_pos()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add the node graph frame layer to the document
|
// Add a layer with a frame to the document
|
||||||
responses.add(Operation::AddNodeGraphFrame {
|
responses.add(Operation::AddFrame {
|
||||||
path: shape_data.path.clone().unwrap(),
|
path: shape_data.path.clone().unwrap(),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
|
|
@ -167,7 +167,7 @@ impl Fsm for ImaginateToolFsmState {
|
||||||
}
|
}
|
||||||
(Drawing, DragStop) => {
|
(Drawing, DragStop) => {
|
||||||
if let Some(layer_path) = &shape_data.path {
|
if let Some(layer_path) = &shape_data.path {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: layer_path.to_vec() });
|
||||||
}
|
}
|
||||||
|
|
||||||
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,7 @@ impl SelectToolData {
|
||||||
|
|
||||||
// Since the selected layers have now moved back to their original transforms before the drag began, we rerender them to be displayed as if they weren't touched.
|
// Since the selected layers have now moved back to their original transforms before the drag began, we rerender them to be displayed as if they weren't touched.
|
||||||
for layer_path in self.not_duplicated_layers.iter().flatten() {
|
for layer_path in self.not_duplicated_layers.iter().flatten() {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: layer_path.clone() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -974,7 +974,7 @@ impl Fsm for SelectToolFsmState {
|
||||||
|
|
||||||
fn rerender_selected_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque<Message>) {
|
fn rerender_selected_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque<Message>) {
|
||||||
for layer_path in &tool_data.layers_dragging {
|
for layer_path in &tool_data.layers_dragging {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: layer_path.clone() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1206,8 +1206,8 @@ fn edit_layer_deepest_manipulation(intersect: &Layer, responses: &mut VecDeque<M
|
||||||
LayerDataType::Shape(_) => {
|
LayerDataType::Shape(_) => {
|
||||||
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path });
|
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path });
|
||||||
}
|
}
|
||||||
LayerDataType::NodeGraphFrame(graph_frame) if graph_frame.as_vector_data().is_some() => {
|
LayerDataType::Layer(layer) if layer.as_vector_data().is_some() => {
|
||||||
if graph_frame.network.nodes.values().any(|node| node.name == "Text") {
|
if layer.network.nodes.values().any(|node| node.name == "Text") {
|
||||||
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Text });
|
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Text });
|
||||||
responses.add(TextToolMessage::EditSelected);
|
responses.add(TextToolMessage::EditSelected);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ impl TextToolData {
|
||||||
|
|
||||||
let network = new_text_network(String::new(), editing_text.font.clone(), editing_text.font_size as f64);
|
let network = new_text_network(String::new(), editing_text.font.clone(), editing_text.font_size as f64);
|
||||||
|
|
||||||
responses.add(Operation::AddNodeGraphFrame {
|
responses.add(Operation::AddFrame {
|
||||||
path: self.layer_path.clone(),
|
path: self.layer_path.clone(),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
||||||
responses.add(ToolMessage::UpdateHints);
|
responses.add(ToolMessage::UpdateHints);
|
||||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
for layer_path in document.selected_layers() {
|
for layer_path in document.selected_layers() {
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
|
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: layer_path.to_vec() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BeginGrab => {
|
BeginGrab => {
|
||||||
|
|
|
||||||
|
|
@ -365,7 +365,7 @@ pub enum ToolType {
|
||||||
Detail,
|
Detail,
|
||||||
Relight,
|
Relight,
|
||||||
Imaginate,
|
Imaginate,
|
||||||
NodeGraphFrame,
|
Frame,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ToolAvailability {
|
enum ToolAvailability {
|
||||||
|
|
@ -399,7 +399,7 @@ fn list_tools_in_groups() -> Vec<Vec<ToolAvailability>> {
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
// Raster tool group
|
// Raster tool group
|
||||||
ToolAvailability::Available(Box::<frame_tool::NodeGraphFrameTool>::default()),
|
ToolAvailability::Available(Box::<frame_tool::FrameTool>::default()),
|
||||||
ToolAvailability::Available(Box::<imaginate_tool::ImaginateTool>::default()),
|
ToolAvailability::Available(Box::<imaginate_tool::ImaginateTool>::default()),
|
||||||
ToolAvailability::Available(Box::<brush_tool::BrushTool>::default()),
|
ToolAvailability::Available(Box::<brush_tool::BrushTool>::default()),
|
||||||
ToolAvailability::ComingSoon(ToolEntry {
|
ToolAvailability::ComingSoon(ToolEntry {
|
||||||
|
|
@ -465,7 +465,7 @@ pub fn tool_message_to_tool_type(tool_message: &ToolMessage) -> ToolType {
|
||||||
// ToolMessage::Detail(_) => ToolType::Detail,
|
// ToolMessage::Detail(_) => ToolType::Detail,
|
||||||
// ToolMessage::Relight(_) => ToolType::Relight,
|
// ToolMessage::Relight(_) => ToolType::Relight,
|
||||||
ToolMessage::Imaginate(_) => ToolType::Imaginate,
|
ToolMessage::Imaginate(_) => ToolType::Imaginate,
|
||||||
ToolMessage::NodeGraphFrame(_) => ToolType::NodeGraphFrame,
|
ToolMessage::Frame(_) => ToolType::Frame,
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"Conversion from ToolMessage to ToolType impossible because the given ToolMessage does not have a matching ToolType. Got: {:?}",
|
"Conversion from ToolMessage to ToolType impossible because the given ToolMessage does not have a matching ToolType. Got: {:?}",
|
||||||
tool_message
|
tool_message
|
||||||
|
|
@ -502,7 +502,7 @@ pub fn tool_type_to_activate_tool_message(tool_type: ToolType) -> ToolMessageDis
|
||||||
// ToolType::Detail => ToolMessageDiscriminant::ActivateToolDetail,
|
// ToolType::Detail => ToolMessageDiscriminant::ActivateToolDetail,
|
||||||
// ToolType::Relight => ToolMessageDiscriminant::ActivateToolRelight,
|
// ToolType::Relight => ToolMessageDiscriminant::ActivateToolRelight,
|
||||||
ToolType::Imaginate => ToolMessageDiscriminant::ActivateToolImaginate,
|
ToolType::Imaginate => ToolMessageDiscriminant::ActivateToolImaginate,
|
||||||
ToolType::NodeGraphFrame => ToolMessageDiscriminant::ActivateToolNodeGraphFrame,
|
ToolType::Frame => ToolMessageDiscriminant::ActivateToolFrame,
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"Conversion from ToolType to ToolMessage impossible because the given ToolType does not have a matching ToolMessage. Got: {:?}",
|
"Conversion from ToolType to ToolMessage impossible because the given ToolType does not have a matching ToolMessage. Got: {:?}",
|
||||||
tool_type
|
tool_type
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ impl NodeGraphExecutor {
|
||||||
fn generate_imaginate(
|
fn generate_imaginate(
|
||||||
&mut self,
|
&mut self,
|
||||||
network: NodeNetwork,
|
network: NodeNetwork,
|
||||||
imaginate_node: Vec<NodeId>,
|
imaginate_node_path: Vec<NodeId>,
|
||||||
(document, document_id): (&mut DocumentMessageHandler, u64),
|
(document, document_id): (&mut DocumentMessageHandler, u64),
|
||||||
layer_path: Vec<LayerId>,
|
layer_path: Vec<LayerId>,
|
||||||
editor_api: EditorApi<'_>,
|
editor_api: EditorApi<'_>,
|
||||||
|
|
@ -135,31 +135,31 @@ impl NodeGraphExecutor {
|
||||||
let layer = document.document_legacy.layer(&layer_path).map_err(|e| format!("No layer: {e:?}"))?;
|
let layer = document.document_legacy.layer(&layer_path).map_err(|e| format!("No layer: {e:?}"))?;
|
||||||
let transform = layer.transform;
|
let transform = layer.transform;
|
||||||
|
|
||||||
let resolution: Option<glam::DVec2> = self.compute_input(&network, &imaginate_node, get("Resolution"), Cow::Borrowed(&editor_api))?;
|
let resolution: Option<glam::DVec2> = self.compute_input(&network, &imaginate_node_path, get("Resolution"), Cow::Borrowed(&editor_api))?;
|
||||||
let resolution = resolution.unwrap_or_else(|| {
|
let resolution = resolution.unwrap_or_else(|| {
|
||||||
let (x, y) = pick_safe_imaginate_resolution((transform.transform_vector2(DVec2::new(1., 0.)).length(), transform.transform_vector2(DVec2::new(0., 1.)).length()));
|
let (x, y) = pick_safe_imaginate_resolution((transform.transform_vector2(DVec2::new(1., 0.)).length(), transform.transform_vector2(DVec2::new(0., 1.)).length()));
|
||||||
DVec2::new(x as f64, y as f64)
|
DVec2::new(x as f64, y as f64)
|
||||||
});
|
});
|
||||||
|
|
||||||
let parameters = ImaginateGenerationParameters {
|
let parameters = ImaginateGenerationParameters {
|
||||||
seed: self.compute_input::<f64>(&network, &imaginate_node, get("Seed"), Cow::Borrowed(&editor_api))? as u64,
|
seed: self.compute_input::<f64>(&network, &imaginate_node_path, get("Seed"), Cow::Borrowed(&editor_api))? as u64,
|
||||||
resolution: resolution.as_uvec2().into(),
|
resolution: resolution.as_uvec2().into(),
|
||||||
samples: self.compute_input::<f64>(&network, &imaginate_node, get("Samples"), Cow::Borrowed(&editor_api))? as u32,
|
samples: self.compute_input::<f64>(&network, &imaginate_node_path, get("Samples"), Cow::Borrowed(&editor_api))? as u32,
|
||||||
sampling_method: self
|
sampling_method: self
|
||||||
.compute_input::<ImaginateSamplingMethod>(&network, &imaginate_node, get("Sampling Method"), Cow::Borrowed(&editor_api))?
|
.compute_input::<ImaginateSamplingMethod>(&network, &imaginate_node_path, get("Sampling Method"), Cow::Borrowed(&editor_api))?
|
||||||
.api_value()
|
.api_value()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
text_guidance: self.compute_input(&network, &imaginate_node, get("Prompt Guidance"), Cow::Borrowed(&editor_api))?,
|
text_guidance: self.compute_input(&network, &imaginate_node_path, get("Prompt Guidance"), Cow::Borrowed(&editor_api))?,
|
||||||
text_prompt: self.compute_input(&network, &imaginate_node, get("Prompt"), Cow::Borrowed(&editor_api))?,
|
text_prompt: self.compute_input(&network, &imaginate_node_path, get("Prompt"), Cow::Borrowed(&editor_api))?,
|
||||||
negative_prompt: self.compute_input(&network, &imaginate_node, get("Negative Prompt"), Cow::Borrowed(&editor_api))?,
|
negative_prompt: self.compute_input(&network, &imaginate_node_path, get("Negative Prompt"), Cow::Borrowed(&editor_api))?,
|
||||||
image_creativity: Some(self.compute_input::<f64>(&network, &imaginate_node, get("Image Creativity"), Cow::Borrowed(&editor_api))? / 100.),
|
image_creativity: Some(self.compute_input::<f64>(&network, &imaginate_node_path, get("Image Creativity"), Cow::Borrowed(&editor_api))? / 100.),
|
||||||
restore_faces: self.compute_input(&network, &imaginate_node, get("Improve Faces"), Cow::Borrowed(&editor_api))?,
|
restore_faces: self.compute_input(&network, &imaginate_node_path, get("Improve Faces"), Cow::Borrowed(&editor_api))?,
|
||||||
tiling: self.compute_input(&network, &imaginate_node, get("Tiling"), Cow::Borrowed(&editor_api))?,
|
tiling: self.compute_input(&network, &imaginate_node_path, get("Tiling"), Cow::Borrowed(&editor_api))?,
|
||||||
};
|
};
|
||||||
let use_base_image = self.compute_input::<bool>(&network, &imaginate_node, get("Adapt Input Image"), Cow::Borrowed(&editor_api))?;
|
let use_base_image = self.compute_input::<bool>(&network, &imaginate_node_path, get("Adapt Input Image"), Cow::Borrowed(&editor_api))?;
|
||||||
|
|
||||||
let input_image_frame: Option<ImageFrame<Color>> = if use_base_image {
|
let input_image_frame: Option<ImageFrame<Color>> = if use_base_image {
|
||||||
Some(self.compute_input::<ImageFrame<Color>>(&network, &imaginate_node, get("Input Image"), Cow::Borrowed(&editor_api))?)
|
Some(self.compute_input::<ImageFrame<Color>>(&network, &imaginate_node_path, get("Input Image"), Cow::Borrowed(&editor_api))?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
@ -180,12 +180,12 @@ impl NodeGraphExecutor {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mask_image = if let Some(transform) = image_transform {
|
let mask_image = if let Some(transform) = image_transform {
|
||||||
let mask_path: Option<Vec<LayerId>> = self.compute_input(&network, &imaginate_node, get("Masking Layer"), Cow::Borrowed(&editor_api))?;
|
let mask_path: Option<Vec<LayerId>> = self.compute_input(&network, &imaginate_node_path, get("Masking Layer"), Cow::Borrowed(&editor_api))?;
|
||||||
|
|
||||||
// Calculate the size of the node graph frame
|
// Calculate the size of the frame
|
||||||
let size = DVec2::new(transform.transform_vector2(DVec2::new(1., 0.)).length(), transform.transform_vector2(DVec2::new(0., 1.)).length());
|
let size = DVec2::new(transform.transform_vector2(DVec2::new(1., 0.)).length(), transform.transform_vector2(DVec2::new(0., 1.)).length());
|
||||||
|
|
||||||
// Render the masking layer within the node graph frame
|
// Render the masking layer within the frame
|
||||||
let old_transforms = document.remove_document_transform();
|
let old_transforms = document.remove_document_transform();
|
||||||
let mask_is_some = mask_path.is_some();
|
let mask_is_some = mask_path.is_some();
|
||||||
let mask_image = mask_path.filter(|mask_layer_path| document.document_legacy.layer(mask_layer_path).is_ok()).map(|mask_layer_path| {
|
let mask_image = mask_path.filter(|mask_layer_path| document.document_legacy.layer(mask_layer_path).is_ok()).map(|mask_layer_path| {
|
||||||
|
|
@ -212,34 +212,34 @@ impl NodeGraphExecutor {
|
||||||
parameters: Box::new(parameters),
|
parameters: Box::new(parameters),
|
||||||
base_image: base_image.map(Box::new),
|
base_image: base_image.map(Box::new),
|
||||||
mask_image: mask_image.map(Box::new),
|
mask_image: mask_image.map(Box::new),
|
||||||
mask_paint_mode: if self.compute_input::<bool>(&network, &imaginate_node, get("Inpaint"), Cow::Borrowed(&editor_api))? {
|
mask_paint_mode: if self.compute_input::<bool>(&network, &imaginate_node_path, get("Inpaint"), Cow::Borrowed(&editor_api))? {
|
||||||
ImaginateMaskPaintMode::Inpaint
|
ImaginateMaskPaintMode::Inpaint
|
||||||
} else {
|
} else {
|
||||||
ImaginateMaskPaintMode::Outpaint
|
ImaginateMaskPaintMode::Outpaint
|
||||||
},
|
},
|
||||||
mask_blur_px: self.compute_input::<f64>(&network, &imaginate_node, get("Mask Blur"), Cow::Borrowed(&editor_api))? as u32,
|
mask_blur_px: self.compute_input::<f64>(&network, &imaginate_node_path, get("Mask Blur"), Cow::Borrowed(&editor_api))? as u32,
|
||||||
imaginate_mask_starting_fill: self.compute_input(&network, &imaginate_node, get("Mask Starting Fill"), Cow::Borrowed(&editor_api))?,
|
imaginate_mask_starting_fill: self.compute_input(&network, &imaginate_node_path, get("Mask Starting Fill"), Cow::Borrowed(&editor_api))?,
|
||||||
hostname: preferences.imaginate_server_hostname.clone(),
|
hostname: preferences.imaginate_server_hostname.clone(),
|
||||||
refresh_frequency: preferences.imaginate_refresh_frequency,
|
refresh_frequency: preferences.imaginate_refresh_frequency,
|
||||||
document_id,
|
document_id,
|
||||||
layer_path,
|
layer_path,
|
||||||
node_path: imaginate_node,
|
node_path: imaginate_node_path,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluates a node graph, computing either the imaginate node or the entire graph
|
/// Evaluates a node graph, computing either the Imaginate node or the entire graph
|
||||||
pub fn evaluate_node_graph(
|
pub fn evaluate_node_graph(
|
||||||
&mut self,
|
&mut self,
|
||||||
(document_id, documents): (u64, &mut HashMap<u64, DocumentMessageHandler>),
|
(document_id, documents): (u64, &mut HashMap<u64, DocumentMessageHandler>),
|
||||||
layer_path: Vec<LayerId>,
|
layer_path: Vec<LayerId>,
|
||||||
(image_data, (width, height)): (Vec<u8>, (u32, u32)),
|
(input_image_data, (width, height)): (Vec<u8>, (u32, u32)),
|
||||||
imaginate_node: Option<Vec<NodeId>>,
|
imaginate_node: Option<Vec<NodeId>>,
|
||||||
persistent_data: (&PreferencesMessageHandler, &PersistentData),
|
persistent_data: (&PreferencesMessageHandler, &PersistentData),
|
||||||
responses: &mut VecDeque<Message>,
|
responses: &mut VecDeque<Message>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// Reformat the input image data into an f32 image
|
// Reformat the input image data into an RGBA f32 image
|
||||||
let image = graphene_core::raster::Image::from_image_data(&image_data, width, height);
|
let image = graphene_core::raster::Image::from_image_data(&input_image_data, width, height);
|
||||||
|
|
||||||
// Get the node graph layer
|
// Get the node graph layer
|
||||||
let document = documents.get_mut(&document_id).ok_or_else(|| "Invalid document".to_string())?;
|
let document = documents.get_mut(&document_id).ok_or_else(|| "Invalid document".to_string())?;
|
||||||
|
|
@ -253,11 +253,11 @@ impl NodeGraphExecutor {
|
||||||
font_cache: Some(&persistent_data.1.font_cache),
|
font_cache: Some(&persistent_data.1.font_cache),
|
||||||
};
|
};
|
||||||
|
|
||||||
let node_graph_frame = match &layer.data {
|
let layer_layer = match &layer.data {
|
||||||
LayerDataType::NodeGraphFrame(frame) => Ok(frame),
|
LayerDataType::Layer(layer) => Ok(layer),
|
||||||
_ => Err("Invalid layer type".to_string()),
|
_ => Err("Invalid layer type".to_string()),
|
||||||
}?;
|
}?;
|
||||||
let network = node_graph_frame.network.clone();
|
let network = layer_layer.network.clone();
|
||||||
|
|
||||||
// Special execution path for generating Imaginate (as generation requires IO from outside node graph)
|
// Special execution path for generating Imaginate (as generation requires IO from outside node graph)
|
||||||
if let Some(imaginate_node) = imaginate_node {
|
if let Some(imaginate_node) = imaginate_node {
|
||||||
|
|
|
||||||
|
|
@ -353,16 +353,15 @@
|
||||||
on:dragstart={(e) => draggable && dragStart(e, listing)}
|
on:dragstart={(e) => draggable && dragStart(e, listing)}
|
||||||
on:click={(e) => selectLayerWithModifiers(e, listing)}
|
on:click={(e) => selectLayerWithModifiers(e, listing)}
|
||||||
>
|
>
|
||||||
{@const layerType = layerTypeData(listing.entry.layerType)}
|
|
||||||
<LayoutRow class="layer-type-icon">
|
<LayoutRow class="layer-type-icon">
|
||||||
<IconLabel icon={layerType.icon} />
|
<IconLabel icon={listing.entry.layerType || "Info"} />
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class="layer-name" on:dblclick={() => onEditLayerName(listing)}>
|
<LayoutRow class="layer-name" on:dblclick={() => onEditLayerName(listing)}>
|
||||||
<input
|
<input
|
||||||
data-text-input
|
data-text-input
|
||||||
type="text"
|
type="text"
|
||||||
value={listing.entry.name}
|
value={listing.entry.name}
|
||||||
placeholder={`Untitled ${layerType.name}`}
|
placeholder={`Untitled ${listing.entry.layerType || "[Unknown Layer Type]"}`}
|
||||||
disabled={!listing.editingName}
|
disabled={!listing.editingName}
|
||||||
on:blur={() => onEditLayerNameDeselect(listing)}
|
on:blur={() => onEditLayerNameDeselect(listing)}
|
||||||
on:keydown={(e) => e.key === "Escape" && onEditLayerNameDeselect(listing)}
|
on:keydown={(e) => e.key === "Escape" && onEditLayerNameDeselect(listing)}
|
||||||
|
|
|
||||||
|
|
@ -129,15 +129,7 @@
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&.open {
|
&.open {
|
||||||
background: var(--color-6-lowergray);
|
background: var(--color-5-dullgray);
|
||||||
|
|
||||||
span {
|
|
||||||
color: var(--color-f-white);
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
fill: var(--color-f-white);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@
|
||||||
<TextLabel italic={true}>{droppable ? "Drop" : "Drag"} Layer Here</TextLabel>
|
<TextLabel italic={true}>{droppable ? "Drop" : "Drag"} Layer Here</TextLabel>
|
||||||
{:else}
|
{:else}
|
||||||
{#if layerName !== undefined && layerType}
|
{#if layerName !== undefined && layerType}
|
||||||
<IconLabel icon={layerTypeData(layerType).icon} class="layer-icon" />
|
<IconLabel icon={layerType} class="layer-icon" />
|
||||||
<TextLabel italic={layerName === ""} class="layer-name">{layerName || `Untitled ${layerTypeData(layerType).name}`}</TextLabel>
|
<TextLabel italic={layerName === ""} class="layer-name">{layerName || `Untitled ${layerType || "[Unknown Layer Type]"}`}</TextLabel>
|
||||||
{:else}
|
{:else}
|
||||||
<TextLabel bold={true} italic={true} class="missing">Layer Missing</TextLabel>
|
<TextLabel bold={true} italic={true} class="missing">Layer Missing</TextLabel>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import {
|
||||||
TriggerImaginateGenerate,
|
TriggerImaginateGenerate,
|
||||||
TriggerImaginateTerminate,
|
TriggerImaginateTerminate,
|
||||||
TriggerImaginateCheckServerStatus,
|
TriggerImaginateCheckServerStatus,
|
||||||
TriggerNodeGraphFrameGenerate,
|
TriggerRasterizeRegionBelowLayer,
|
||||||
UpdateActiveDocument,
|
UpdateActiveDocument,
|
||||||
UpdateOpenDocumentsList,
|
UpdateOpenDocumentsList,
|
||||||
UpdateImageData,
|
UpdateImageData,
|
||||||
|
|
@ -116,21 +116,23 @@ export function createPortfolioState(editor: Editor) {
|
||||||
editor.instance.setImageBlobURL(updateImageData.documentId, element.path, blobURL, image.naturalWidth, image.naturalHeight, element.transform);
|
editor.instance.setImageBlobURL(updateImageData.documentId, element.path, blobURL, image.naturalWidth, image.naturalHeight, element.transform);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
editor.subscriptions.subscribeJsMessage(TriggerNodeGraphFrameGenerate, async (triggerNodeGraphFrameGenerate) => {
|
editor.subscriptions.subscribeJsMessage(TriggerRasterizeRegionBelowLayer, async (triggerRasterizeRegionBelowLayer) => {
|
||||||
const { documentId, layerPath, svg, size, imaginateNode } = triggerNodeGraphFrameGenerate;
|
const { documentId, layerPath, svg, size, imaginateNodePath } = triggerRasterizeRegionBelowLayer;
|
||||||
|
|
||||||
// Rasterize the SVG to an image file
|
// Rasterize the SVG to an image file
|
||||||
let imageData;
|
|
||||||
try {
|
try {
|
||||||
// getImageData may throw an exception if the resolution is too high
|
|
||||||
if (size[0] >= 1 && size[1] >= 1) {
|
if (size[0] >= 1 && size[1] >= 1) {
|
||||||
imageData = (await rasterizeSVGCanvas(svg, size[0], size[1])).getContext("2d")?.getImageData(0, 0, size[0], size[1]);
|
const imageData = (await rasterizeSVGCanvas(svg, size[0], size[1])).getContext("2d")?.getImageData(0, 0, size[0], size[1]);
|
||||||
|
if (!imageData) return;
|
||||||
|
|
||||||
|
editor.instance.renderGraphUsingRasterizedRegionBelowLayer(documentId, layerPath, new Uint8Array(imageData.data), imageData.width, imageData.height, imaginateNodePath);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
// getImageData may throw an exception if the resolution is too high
|
||||||
|
catch (e) {
|
||||||
console.error("Failed to rasterize the SVG canvas in JS to be sent back to Rust:", e);
|
console.error("Failed to rasterize the SVG canvas in JS to be sent back to Rust:", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imageData) editor.instance.processNodeGraphFrame(documentId, layerPath, new Uint8Array(imageData.data), imageData.width, imageData.height, imaginateNode);
|
|
||||||
});
|
});
|
||||||
editor.subscriptions.subscribeJsMessage(TriggerRevokeBlobUrl, async (triggerRevokeBlobUrl) => {
|
editor.subscriptions.subscribeJsMessage(TriggerRevokeBlobUrl, async (triggerRevokeBlobUrl) => {
|
||||||
URL.revokeObjectURL(triggerRevokeBlobUrl.url);
|
URL.revokeObjectURL(triggerRevokeBlobUrl.url);
|
||||||
|
|
|
||||||
|
|
@ -604,7 +604,7 @@ export class TriggerImaginateTerminate extends JsMessage {
|
||||||
readonly hostname!: string;
|
readonly hostname!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TriggerNodeGraphFrameGenerate extends JsMessage {
|
export class TriggerRasterizeRegionBelowLayer extends JsMessage {
|
||||||
readonly documentId!: bigint;
|
readonly documentId!: bigint;
|
||||||
|
|
||||||
readonly layerPath!: BigUint64Array;
|
readonly layerPath!: BigUint64Array;
|
||||||
|
|
@ -613,7 +613,7 @@ export class TriggerNodeGraphFrameGenerate extends JsMessage {
|
||||||
|
|
||||||
readonly size!: [number, number];
|
readonly size!: [number, number];
|
||||||
|
|
||||||
readonly imaginateNode!: BigUint64Array | undefined;
|
readonly imaginateNodePath!: BigUint64Array | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TriggerRefreshBoundsOfViewports extends JsMessage { }
|
export class TriggerRefreshBoundsOfViewports extends JsMessage { }
|
||||||
|
|
@ -751,23 +751,13 @@ export class LayerMetadata {
|
||||||
selected!: boolean;
|
selected!: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LayerType = "Folder" | "NodeGraphFrame";
|
export type LayerType = "Folder" | "Layer";
|
||||||
|
|
||||||
export type LayerTypeData = {
|
export type LayerTypeData = {
|
||||||
name: string;
|
name: string;
|
||||||
icon: IconName;
|
icon: IconName;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Delete this function after renaming NodeGraphFrame to Layer, since it will basically just return its input parameter
|
|
||||||
export function layerTypeData(layerType: LayerType): LayerTypeData {
|
|
||||||
const entries: Record<string, LayerTypeData> = {
|
|
||||||
NodeGraphFrame: { name: "Layer", icon: "Layer" },
|
|
||||||
Folder: { name: "Folder", icon: "Folder" },
|
|
||||||
};
|
|
||||||
|
|
||||||
return entries[layerType] || { name: "Error", icon: "Info" };
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ImaginateImageData {
|
export class ImaginateImageData {
|
||||||
readonly path!: BigUint64Array;
|
readonly path!: BigUint64Array;
|
||||||
|
|
||||||
|
|
@ -1397,7 +1387,7 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||||
TriggerImaginateCheckServerStatus,
|
TriggerImaginateCheckServerStatus,
|
||||||
TriggerImaginateGenerate,
|
TriggerImaginateGenerate,
|
||||||
TriggerImaginateTerminate,
|
TriggerImaginateTerminate,
|
||||||
TriggerNodeGraphFrameGenerate,
|
TriggerRasterizeRegionBelowLayer,
|
||||||
TriggerFileDownload,
|
TriggerFileDownload,
|
||||||
TriggerFontLoad,
|
TriggerFontLoad,
|
||||||
TriggerImport,
|
TriggerImport,
|
||||||
|
|
|
||||||
|
|
@ -580,14 +580,22 @@ impl JsEditorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends the blob URL generated by JS to the Imaginate layer in the respective document
|
/// Sends the blob URL generated by JS to the Imaginate layer in the respective document
|
||||||
#[wasm_bindgen(js_name = processNodeGraphFrame)]
|
#[wasm_bindgen(js_name = renderGraphUsingRasterizedRegionBelowLayer)]
|
||||||
pub fn process_node_graph_frame(&self, document_id: u64, layer_path: Vec<LayerId>, image_data: Vec<u8>, width: u32, height: u32, imaginate_node: Option<Vec<NodeId>>) {
|
pub fn render_graph_using_rasterized_region_below_layer(
|
||||||
let message = PortfolioMessage::ProcessNodeGraphFrame {
|
&self,
|
||||||
|
document_id: u64,
|
||||||
|
layer_path: Vec<LayerId>,
|
||||||
|
input_image_data: Vec<u8>,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
imaginate_node_path: Option<Vec<NodeId>>,
|
||||||
|
) {
|
||||||
|
let message = PortfolioMessage::RenderGraphUsingRasterizedRegionBelowLayer {
|
||||||
document_id,
|
document_id,
|
||||||
layer_path,
|
layer_path,
|
||||||
image_data,
|
input_image_data,
|
||||||
size: (width, height),
|
size: (width, height),
|
||||||
imaginate_node,
|
imaginate_node_path,
|
||||||
};
|
};
|
||||||
self.dispatch(message);
|
self.dispatch(message);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue