Clean up some document-legacy code

This commit is contained in:
Keavon Chambers 2023-12-12 22:37:55 -08:00
parent 83af879a7c
commit d5b161e7d1
19 changed files with 281 additions and 241 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
use crate::consts::F64PRECISE; use crate::consts::F64PRECISE;
use crate::intersection::{intersections, line_curve_intersections, valid_t, Intersect, Origin}; use crate::intersection::{intersections, line_curve_intersections, valid_t, Intersect, Origin};
use crate::layers::shape_layer::ShapeLayer; use crate::layers::shape_layer::ShapeLegacyLayer;
use crate::layers::style::PathStyle; use crate::layers::style::PathStyle;
use kurbo::{BezPath, CubicBez, Line, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveExtrema, PathEl, PathSeg, Point, QuadBez, Rect}; use kurbo::{BezPath, CubicBez, Line, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveExtrema, PathEl, PathSeg, Point, QuadBez, Rect};
@ -395,7 +395,7 @@ impl PathGraph {
cycles cycles
} }
pub fn get_shape(&self, cycle: &Cycle, style: &PathStyle) -> ShapeLayer { pub fn get_shape(&self, cycle: &Cycle, style: &PathStyle) -> ShapeLegacyLayer {
let mut curve = Vec::new(); let mut curve = Vec::new();
let vertices = cycle.vertices(); let vertices = cycle.vertices();
for index in 1..vertices.len() { for index in 1..vertices.len() {
@ -403,7 +403,7 @@ impl PathGraph {
concat_paths(&mut curve, &self.edge(vertices[index - 1].0, vertices[index].0, vertices[index].1).unwrap().curve); concat_paths(&mut curve, &self.edge(vertices[index - 1].0, vertices[index].0, vertices[index].1).unwrap().curve);
} }
curve.push(PathEl::ClosePath); curve.push(PathEl::ClosePath);
ShapeLayer::new(BezPath::from_vec(curve).iter().into(), style.clone()) ShapeLegacyLayer::new(BezPath::from_vec(curve).iter().into(), style.clone())
} }
} }
@ -471,7 +471,7 @@ pub fn subdivide_path_seg(p: &PathSeg, t_values: &mut [f64]) -> Vec<Option<PathS
sub_segments sub_segments
} }
pub fn composite_boolean_operation(mut select: BooleanOperation, shapes: &mut Vec<RefCell<ShapeLayer>>) -> Result<Vec<ShapeLayer>, BooleanOperationError> { pub fn composite_boolean_operation(mut select: BooleanOperation, shapes: &mut Vec<RefCell<ShapeLegacyLayer>>) -> Result<Vec<ShapeLegacyLayer>, BooleanOperationError> {
if select == BooleanOperation::SubtractFront { if select == BooleanOperation::SubtractFront {
select = BooleanOperation::SubtractBack; select = BooleanOperation::SubtractBack;
let temp_len = shapes.len(); let temp_len = shapes.len();
@ -537,7 +537,7 @@ pub fn composite_boolean_operation(mut select: BooleanOperation, shapes: &mut Ve
// TODO: check if shapes are filled // TODO: check if shapes are filled
// TODO: Bug: shape with at least two subpaths and comprised of many unions sometimes has erroneous movetos embedded in edges // TODO: Bug: shape with at least two subpaths and comprised of many unions sometimes has erroneous movetos embedded in edges
pub fn boolean_operation(mut select: BooleanOperation, alpha: &mut ShapeLayer, beta: &mut ShapeLayer) -> Result<Vec<ShapeLayer>, BooleanOperationError> { pub fn boolean_operation(mut select: BooleanOperation, alpha: &mut ShapeLegacyLayer, beta: &mut ShapeLegacyLayer) -> Result<Vec<ShapeLegacyLayer>, BooleanOperationError> {
if alpha.shape.manipulator_groups().is_empty() || beta.shape.manipulator_groups().is_empty() { if alpha.shape.manipulator_groups().is_empty() || beta.shape.manipulator_groups().is_empty() {
return Err(BooleanOperationError::InvalidSelection); return Err(BooleanOperationError::InvalidSelection);
} }
@ -685,7 +685,7 @@ pub fn bounding_box(curve: &BezPath) -> Rect {
.unwrap() .unwrap()
} }
fn collect_shapes<'a, F, G>(graph: &PathGraph, cycles: &mut Vec<Cycle>, predicate: F, style: G) -> Result<Vec<ShapeLayer>, BooleanOperationError> fn collect_shapes<'a, F, G>(graph: &PathGraph, cycles: &mut Vec<Cycle>, predicate: F, style: G) -> Result<Vec<ShapeLegacyLayer>, BooleanOperationError>
where where
F: Fn(Direction) -> bool, F: Fn(Direction) -> bool,
G: Fn(Direction) -> &'a PathStyle, G: Fn(Direction) -> &'a PathStyle,

View file

@ -1,11 +1,12 @@
use crate::document_metadata::{is_artboard, DocumentMetadata, LayerNodeIdentifier}; use crate::document_metadata::{is_artboard, DocumentMetadata, LayerNodeIdentifier};
use crate::intersection::Quad; use crate::intersection::Quad;
use crate::layers::folder_layer::FolderLayer; use crate::layers::folder_layer::FolderLegacyLayer;
use crate::layers::layer_info::{Layer, LayerData, LayerDataType, LayerDataTypeDiscriminant}; use crate::layers::layer_info::{LayerData, LayerDataTypeDiscriminant, LegacyLayer, LegacyLayerType};
use crate::layers::layer_layer::{CachedOutputData, LayerLayer}; use crate::layers::layer_layer::{CachedOutputData, LayerLegacyLayer};
use crate::layers::shape_layer::ShapeLayer; use crate::layers::shape_layer::ShapeLegacyLayer;
use crate::layers::style::RenderData; use crate::layers::style::RenderData;
use crate::{DocumentError, DocumentResponse, Operation}; use crate::{DocumentError, DocumentResponse, Operation};
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeNetwork, NodeOutput}; use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeNetwork, NodeOutput};
use graphene_core::renderer::ClickTarget; use graphene_core::renderer::ClickTarget;
use graphene_core::transform::Footprint; use graphene_core::transform::Footprint;
@ -26,16 +27,15 @@ pub type LayerId = u64;
#[derive(Debug, Clone, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Document { pub struct Document {
/// The root layer, usually a [FolderLayer](layers::folder_layer::FolderLayer) that contains all other [Layers](layers::layer_info::Layer). #[serde(default)]
pub root: Layer, pub document_network: NodeNetwork,
/// The root layer, usually a [FolderLegacyLayer](layers::folder_layer::FolderLegacyLayer) that contains all other [LegacyLayers](layers::layer_info::LegacyLayer).
#[serde(skip)]
pub root: LegacyLayer,
/// The state_identifier serves to provide a way to uniquely identify a particular state that the document is in. /// The state_identifier serves to provide a way to uniquely identify a particular state that the document is in.
/// This identifier is not a hash and is not guaranteed to be equal for equivalent documents. /// This identifier is not a hash and is not guaranteed to be equal for equivalent documents.
#[serde(skip)] #[serde(skip)]
pub state_identifier: DefaultHasher, pub state_identifier: DefaultHasher,
#[serde(default)]
pub document_network: NodeNetwork,
#[serde(default)]
pub collapsed_folders: Vec<LayerNodeIdentifier>,
#[serde(skip)] #[serde(skip)]
pub metadata: DocumentMetadata, pub metadata: DocumentMetadata,
} }
@ -49,7 +49,7 @@ impl PartialEq for Document {
impl Default for Document { impl Default for Document {
fn default() -> Self { fn default() -> Self {
Self { Self {
root: Layer::new(LayerDataType::Folder(FolderLayer::default()), DAffine2::IDENTITY.to_cols_array()), root: LegacyLayer::new(LegacyLayerType::Folder(FolderLegacyLayer::default()), DAffine2::IDENTITY.to_cols_array()),
state_identifier: DefaultHasher::new(), state_identifier: DefaultHasher::new(),
document_network: { document_network: {
use graph_craft::document::{value::TaggedValue, NodeInput}; use graph_craft::document::{value::TaggedValue, NodeInput};
@ -105,7 +105,6 @@ impl Default for Document {
network network
}, },
metadata: Default::default(), metadata: Default::default(),
collapsed_folders: Vec::new(),
} }
} }
} }
@ -119,11 +118,6 @@ impl Document {
self.metadata.selected_layers().filter(|&layer| self.layer_visible(layer)) self.metadata.selected_layers().filter(|&layer| self.layer_visible(layer))
} }
pub fn load_network_structure(&mut self) {
self.metadata.load_structure(&self.document_network);
self.collapsed_folders.retain(|&layer| self.metadata.layer_exists(layer));
}
/// Runs an intersection test with all layers and a viewport space quad /// Runs an intersection test with all layers and a viewport space quad
pub fn intersect_quad<'a>(&'a self, viewport_quad: graphene_core::renderer::Quad, network: &'a NodeNetwork) -> impl Iterator<Item = LayerNodeIdentifier> + 'a { pub fn intersect_quad<'a>(&'a self, viewport_quad: graphene_core::renderer::Quad, network: &'a NodeNetwork) -> impl Iterator<Item = LayerNodeIdentifier> + 'a {
let document_quad = self.metadata.document_to_viewport.inverse() * viewport_quad; let document_quad = self.metadata.document_to_viewport.inverse() * viewport_quad;
@ -181,7 +175,7 @@ impl Document {
// Note: it is bad practice to directly clone and modify the document structure, this is a temporary hack until this whole system is replaced by the node graph // Note: it is bad practice to directly clone and modify the document structure, this is a temporary hack until this whole system is replaced by the node graph
let mut temp_subset_folder = self.layer_mut(parent_folder_path).ok()?.clone(); let mut temp_subset_folder = self.layer_mut(parent_folder_path).ok()?.clone();
if let LayerDataType::Folder(ref mut folder) = temp_subset_folder.data { if let LegacyLayerType::Folder(ref mut folder) = temp_subset_folder.data {
// Remove the upper layers to leave behind the lower subset for rendering // Remove the upper layers to leave behind the lower subset for rendering
let count_of_layers_below = folder.layer_ids.iter().position(|id| id == layer_id_to_render_below).unwrap(); let count_of_layers_below = folder.layer_ids.iter().position(|id| id == layer_id_to_render_below).unwrap();
folder.layer_ids.truncate(count_of_layers_below); folder.layer_ids.truncate(count_of_layers_below);
@ -235,7 +229,7 @@ impl Document {
/// Returns a reference to the requested folder. Fails if the path does not exist, /// Returns a reference to the requested folder. Fails if the path does not exist,
/// or if the requested layer is not of type folder. /// or if the requested layer is not of type folder.
pub fn folder(&self, path: impl AsRef<[LayerId]>) -> Result<&FolderLayer, DocumentError> { pub fn folder(&self, path: impl AsRef<[LayerId]>) -> Result<&FolderLegacyLayer, DocumentError> {
let mut root = &self.root; let mut root = &self.root;
for id in path.as_ref() { for id in path.as_ref() {
root = root.as_folder()?.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.as_ref().into()))?; root = root.as_folder()?.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.as_ref().into()))?;
@ -246,7 +240,7 @@ impl Document {
/// Returns a mutable reference to the requested folder. Fails if the path does not exist, /// Returns a mutable reference to the requested folder. Fails if the path does not exist,
/// or if the requested layer is not of type folder. /// or if the requested layer is not of type folder.
/// If you manually edit the folder you have to set the cache_dirty flag yourself. /// If you manually edit the folder you have to set the cache_dirty flag yourself.
fn folder_mut(&mut self, path: &[LayerId]) -> Result<&mut FolderLayer, DocumentError> { fn folder_mut(&mut self, path: &[LayerId]) -> Result<&mut FolderLegacyLayer, DocumentError> {
let mut root = &mut self.root; let mut root = &mut self.root;
for id in path { for id in path {
root = root.as_folder_mut()?.layer_mut(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?; root = root.as_folder_mut()?.layer_mut(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
@ -255,7 +249,7 @@ impl Document {
} }
/// Returns a reference to the layer or folder at the path. /// Returns a reference to the layer or folder at the path.
pub fn layer(&self, path: &[LayerId]) -> Result<&Layer, DocumentError> { pub fn layer(&self, path: &[LayerId]) -> Result<&LegacyLayer, DocumentError> {
if path.is_empty() { if path.is_empty() {
return Ok(&self.root); return Ok(&self.root);
} }
@ -264,7 +258,7 @@ impl Document {
} }
/// Returns a mutable reference to the layer or folder at the path. /// Returns a mutable reference to the layer or folder at the path.
pub fn layer_mut(&mut self, path: &[LayerId]) -> Result<&mut Layer, DocumentError> { pub fn layer_mut(&mut self, path: &[LayerId]) -> Result<&mut LegacyLayer, DocumentError> {
if path.is_empty() { if path.is_empty() {
return Ok(&mut self.root); return Ok(&mut self.root);
} }
@ -290,7 +284,7 @@ impl Document {
let common_prefix_of_path = self.common_layer_path_prefix(layers); let common_prefix_of_path = self.common_layer_path_prefix(layers);
Ok(match self.layer(common_prefix_of_path)?.data { Ok(match self.layer(common_prefix_of_path)?.data {
LayerDataType::Folder(_) => common_prefix_of_path, LegacyLayerType::Folder(_) => common_prefix_of_path,
_ => &common_prefix_of_path[..common_prefix_of_path.len() - 1], _ => &common_prefix_of_path[..common_prefix_of_path.len() - 1],
}) })
} }
@ -402,7 +396,7 @@ impl Document {
} }
/// Replaces the layer at the specified `path` with `layer`. /// Replaces the layer at the specified `path` with `layer`.
pub fn set_layer(&mut self, path: &[LayerId], layer: Layer, insert_index: isize) -> Result<(), DocumentError> { pub fn set_layer(&mut self, path: &[LayerId], layer: LegacyLayer, insert_index: isize) -> Result<(), DocumentError> {
let mut folder = self.root.as_folder_mut()?; let mut folder = self.root.as_folder_mut()?;
let mut layer_id = None; let mut layer_id = None;
if let Ok((path, id)) = split_path(path) { if let Ok((path, id)) = split_path(path) {
@ -419,9 +413,9 @@ impl Document {
} }
/// Visit each layer recursively, marks all children as dirty /// Visit each layer recursively, marks all children as dirty
pub fn mark_children_as_dirty(layer: &mut Layer) -> bool { pub fn mark_children_as_dirty(layer: &mut LegacyLayer) -> bool {
match layer.data { match layer.data {
LayerDataType::Folder(ref mut folder) => { LegacyLayerType::Folder(ref mut folder) => {
for sub_layer in folder.layers_mut() { for sub_layer in folder.layers_mut() {
if Document::mark_children_as_dirty(sub_layer) { if Document::mark_children_as_dirty(sub_layer) {
layer.cache_dirty = true; layer.cache_dirty = true;
@ -436,7 +430,7 @@ impl Document {
/// Adds a new layer to the folder specified by `path`. /// Adds a new layer to the folder specified by `path`.
/// Passing a negative `insert_index` indexes relative to the end. /// Passing a negative `insert_index` indexes relative to the end.
/// -1 is equivalent to adding the layer to the top. /// -1 is equivalent to adding the layer to the top.
pub fn add_layer(&mut self, path: &[LayerId], layer: Layer, insert_index: isize) -> Result<LayerId, DocumentError> { pub fn add_layer(&mut self, path: &[LayerId], layer: LegacyLayer, insert_index: isize) -> Result<LayerId, DocumentError> {
let folder = self.folder_mut(path)?; let folder = self.folder_mut(path)?;
folder.add_layer(layer, None, insert_index).ok_or(DocumentError::IndexOutOfBounds) folder.add_layer(layer, None, insert_index).ok_or(DocumentError::IndexOutOfBounds)
} }
@ -592,7 +586,7 @@ impl Document {
let responses = match operation { let responses = match operation {
Operation::AddEllipse { path, insert_index, transform, style } => { Operation::AddEllipse { path, insert_index, transform, style } => {
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::ellipse(style)), transform); let layer = LegacyLayer::new(LegacyLayerType::Shape(ShapeLegacyLayer::ellipse(style)), transform);
self.set_layer(&path, layer, insert_index)?; self.set_layer(&path, layer, insert_index)?;
@ -608,7 +602,7 @@ impl Document {
Some(responses) Some(responses)
} }
Operation::AddRect { path, insert_index, transform, style } => { Operation::AddRect { path, insert_index, transform, style } => {
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::rectangle(style)), transform); let layer = LegacyLayer::new(LegacyLayerType::Shape(ShapeLegacyLayer::rectangle(style)), transform);
self.set_layer(&path, layer, insert_index)?; self.set_layer(&path, layer, insert_index)?;
@ -624,7 +618,7 @@ impl Document {
Some(responses) Some(responses)
} }
Operation::AddLine { path, insert_index, transform, style } => { Operation::AddLine { path, insert_index, transform, style } => {
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::line(style)), transform); let layer = LegacyLayer::new(LegacyLayerType::Shape(ShapeLegacyLayer::line(style)), transform);
self.set_layer(&path, layer, insert_index)?; self.set_layer(&path, layer, insert_index)?;
@ -646,7 +640,7 @@ impl Document {
transform, transform,
network, network,
} => { } => {
let layer = Layer::new(LayerDataType::Layer(LayerLayer { network, ..Default::default() }), transform); let layer = LegacyLayer::new(LegacyLayerType::Layer(LayerLegacyLayer { network, ..Default::default() }), transform);
self.set_layer(&path, layer, insert_index)?; self.set_layer(&path, layer, insert_index)?;
@ -674,8 +668,8 @@ impl Document {
style, style,
subpath, subpath,
} => { } => {
let shape = ShapeLayer::new(subpath, style); let shape = ShapeLegacyLayer::new(subpath, style);
self.set_layer(&path, Layer::new(LayerDataType::Shape(shape), transform), insert_index)?; self.set_layer(&path, LegacyLayer::new(LegacyLayerType::Shape(shape), transform), insert_index)?;
Some(vec![DocumentChanged, CreatedLayer { path, is_selected: true }]) Some(vec![DocumentChanged, CreatedLayer { path, is_selected: true }])
} }
Operation::AddPolyline { Operation::AddPolyline {
@ -686,7 +680,7 @@ impl Document {
style, style,
} => { } => {
let points: Vec<glam::DVec2> = points.iter().map(|&it| it.into()).collect(); let points: Vec<glam::DVec2> = points.iter().map(|&it| it.into()).collect();
self.set_layer(&path, Layer::new(LayerDataType::Shape(ShapeLayer::poly_line(points, style)), transform), insert_index)?; self.set_layer(&path, LegacyLayer::new(LegacyLayerType::Shape(ShapeLegacyLayer::poly_line(points, style)), transform), insert_index)?;
let mut responses = vec![ let mut responses = vec![
DocumentChanged, DocumentChanged,
@ -700,11 +694,11 @@ impl Document {
Some(responses) Some(responses)
} }
Operation::DeleteLayer { path } => { Operation::DeleteLayer { path } => {
fn aggregate_deletions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) { fn aggregate_deletions(folder: &FolderLegacyLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()) { for (id, layer) in folder.layer_ids.iter().zip(folder.layers()) {
path.push(*id); path.push(*id);
responses.push(DocumentResponse::DeletedLayer { path: path.clone() }); responses.push(DocumentResponse::DeletedLayer { path: path.clone() });
if let LayerDataType::Folder(f) = &layer.data { if let LegacyLayerType::Folder(f) = &layer.data {
aggregate_deletions(f, path, responses); aggregate_deletions(f, path, responses);
} }
path.pop(); path.pop();
@ -753,7 +747,7 @@ impl Document {
self.mark_as_dirty(&destination_path)?; self.mark_as_dirty(&destination_path)?;
// Recursively iterate through each layer in a folder and add it to the responses vector // Recursively iterate through each layer in a folder and add it to the responses vector
fn aggregate_insertions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>, duplicating: bool) { fn aggregate_insertions(folder: &FolderLegacyLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>, duplicating: bool) {
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()) { for (id, layer) in folder.layer_ids.iter().zip(folder.layers()) {
path.push(*id); path.push(*id);
@ -761,7 +755,7 @@ impl Document {
path: path.clone(), path: path.clone(),
is_selected: !duplicating, is_selected: !duplicating,
}); });
if let LayerDataType::Folder(f) = &layer.data { if let LegacyLayerType::Folder(f) = &layer.data {
aggregate_insertions(f, path, responses, duplicating); aggregate_insertions(f, path, responses, duplicating);
} }
@ -811,7 +805,7 @@ impl Document {
let mut indices: Vec<usize> = (0..duplicated_layers.len()).collect(); let mut indices: Vec<usize> = (0..duplicated_layers.len()).collect();
indices.sort_by_key(|&i| duplicated_layers[i].len()); indices.sort_by_key(|&i| duplicated_layers[i].len());
duplicated_layers.sort_by_key(|a| a.len()); duplicated_layers.sort_by_key(|a| a.len());
let duplicate_layer_objects_sorted: Vec<&Layer> = indices.iter().map(|&i| &duplicated_layers_objects[i]).collect(); let duplicate_layer_objects_sorted: Vec<&LegacyLayer> = indices.iter().map(|&i| &duplicated_layers_objects[i]).collect();
let folder = self.folder_mut(folder_path)?; let folder = self.folder_mut(folder_path)?;
@ -857,7 +851,7 @@ impl Document {
// Clear the new folder's layer_ids and layers because they contain the layer_ids/layers of the layer were duplicated // Clear the new folder's layer_ids and layers because they contain the layer_ids/layers of the layer were duplicated
if self.is_folder(duplicate_layer) { if self.is_folder(duplicate_layer) {
let updated_layer_as_folder: &mut FolderLayer = updated_layer.as_folder_mut()?; let updated_layer_as_folder: &mut FolderLegacyLayer = updated_layer.as_folder_mut()?;
updated_layer_as_folder.layer_ids = vec![]; updated_layer_as_folder.layer_ids = vec![];
updated_layer_as_folder.layers = vec![]; updated_layer_as_folder.layers = vec![];
updated_layer_as_folder.generate_new_folder_ids() updated_layer_as_folder.generate_new_folder_ids()
@ -898,7 +892,11 @@ impl Document {
Some(vec![LayerChanged { path }]) Some(vec![LayerChanged { path }])
} }
Operation::CreateFolder { path, insert_index } => { Operation::CreateFolder { path, insert_index } => {
self.set_layer(&path, Layer::new(LayerDataType::Folder(FolderLayer::default()), DAffine2::IDENTITY.to_cols_array()), insert_index)?; self.set_layer(
&path,
LegacyLayer::new(LegacyLayerType::Folder(FolderLegacyLayer::default()), DAffine2::IDENTITY.to_cols_array()),
insert_index,
)?;
self.mark_as_dirty(&path)?; self.mark_as_dirty(&path)?;
let mut responses = vec![ let mut responses = vec![
@ -928,7 +926,7 @@ 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::Layer(layer) = &mut layer.data else { let LegacyLayerType::Layer(layer) = &mut layer.data else {
panic!("Incorrectly trying to set the image blob URL for a layer that is not a 'Layer' layer type"); panic!("Incorrectly trying to set the image blob URL for a layer that is not a 'Layer' layer type");
}; };
@ -940,7 +938,7 @@ 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::Layer(layer) => { LegacyLayerType::Layer(layer) => {
if matches!(layer.cached_output_data, CachedOutputData::BlobURL(_)) { if matches!(layer.cached_output_data, CachedOutputData::BlobURL(_)) {
layer.cached_output_data = CachedOutputData::None; layer.cached_output_data = CachedOutputData::None;
} }
@ -965,25 +963,25 @@ impl Document {
Operation::SetShapePath { path, subpath } => { Operation::SetShapePath { path, subpath } => {
self.mark_as_dirty(&path)?; self.mark_as_dirty(&path)?;
if let LayerDataType::Shape(shape) = &mut self.layer_mut(&path)?.data { if let LegacyLayerType::Shape(shape) = &mut self.layer_mut(&path)?.data {
shape.shape = subpath; shape.shape = subpath;
} }
Some(vec![DocumentChanged, LayerChanged { path }]) Some(vec![DocumentChanged, LayerChanged { path }])
} }
Operation::SetVectorData { path, vector_data } => { Operation::SetVectorData { path, vector_data } => {
if let LayerDataType::Layer(layer) = &mut self.layer_mut(&path)?.data { if let LegacyLayerType::Layer(layer) = &mut self.layer_mut(&path)?.data {
layer.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())
} }
Operation::SetSurface { path, surface_id } => { Operation::SetSurface { path, surface_id } => {
if let LayerDataType::Layer(layer) = &mut self.layer_mut(&path)?.data { if let LegacyLayerType::Layer(layer) = &mut self.layer_mut(&path)?.data {
layer.cached_output_data = CachedOutputData::SurfaceId(surface_id); layer.cached_output_data = CachedOutputData::SurfaceId(surface_id);
} }
Some(Vec::new()) Some(Vec::new())
} }
Operation::SetSvg { path, svg } => { Operation::SetSvg { path, svg } => {
if let LayerDataType::Layer(layer) = &mut self.layer_mut(&path)?.data { if let LegacyLayerType::Layer(layer) = &mut self.layer_mut(&path)?.data {
layer.cached_output_data = CachedOutputData::Svg(svg); layer.cached_output_data = CachedOutputData::Svg(svg);
} }
Some(Vec::new()) Some(Vec::new())
@ -1046,7 +1044,7 @@ impl Document {
Operation::SetLayerStyle { path, style } => { Operation::SetLayerStyle { path, style } => {
let layer = self.layer_mut(&path)?; let layer = self.layer_mut(&path)?;
match &mut layer.data { match &mut layer.data {
LayerDataType::Shape(s) => s.style = style, LegacyLayerType::Shape(s) => s.style = style,
_ => return Err(DocumentError::NotShape), _ => return Err(DocumentError::NotShape),
} }
self.mark_as_dirty(&path)?; self.mark_as_dirty(&path)?;
@ -1083,7 +1081,7 @@ fn update_thumbnails_upstream(path: &[LayerId]) -> Vec<DocumentResponse> {
responses responses
} }
pub fn pick_layer_safe_imaginate_resolution(layer: &Layer, render_data: &RenderData) -> (u64, u64) { pub fn pick_layer_safe_imaginate_resolution(layer: &LegacyLayer, render_data: &RenderData) -> (u64, u64) {
let layer_bounds = layer.bounding_transform(render_data); let layer_bounds = layer.bounding_transform(render_data);
let layer_bounds_size = (layer_bounds.transform_vector2((1., 0.).into()).length(), layer_bounds.transform_vector2((0., 1.).into()).length()); let layer_bounds_size = (layer_bounds.transform_vector2((1., 0.).into()).length(), layer_bounds.transform_vector2((0., 1.).into()).length());

View file

@ -1,4 +1,4 @@
use super::layer_info::{Layer, LayerData, LayerDataType}; use super::layer_info::{LayerData, LegacyLayer, LegacyLayerType};
use super::style::RenderData; use super::style::RenderData;
use crate::intersection::Quad; use crate::intersection::Quad;
use crate::{DocumentError, LayerId}; use crate::{DocumentError, LayerId};
@ -9,19 +9,18 @@ use glam::DVec2;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// A layer that encapsulates other layers, including potentially more folders. /// A layer that encapsulates other layers, including potentially more folders.
/// The contained layers are rendered in the same order they are /// The contained layers are rendered in the same order they are stored.
/// stored in the [layers](FolderLayer::layers) field.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Default)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Default)]
pub struct FolderLayer { pub struct FolderLegacyLayer {
/// The ID that will be assigned to the next layer that is added to the folder /// The ID that will be assigned to the next layer that is added to the folder
next_assignment_id: LayerId, next_assignment_id: LayerId,
/// The IDs of the [Layer]s contained within the Folder /// The IDs of the [Layer]s contained within the Folder
pub layer_ids: Vec<LayerId>, pub layer_ids: Vec<LayerId>,
/// The [Layer]s contained in the folder /// The [Layer]s contained in the folder
pub layers: Vec<Layer>, pub layers: Vec<LegacyLayer>,
} }
impl LayerData for FolderLayer { impl LayerData for FolderLegacyLayer {
fn render(&mut self, svg: &mut String, svg_defs: &mut String, transforms: &mut Vec<glam::DAffine2>, render_data: &RenderData) -> bool { fn render(&mut self, svg: &mut String, svg_defs: &mut String, transforms: &mut Vec<glam::DAffine2>, render_data: &RenderData) -> bool {
let mut any_child_requires_redraw = false; let mut any_child_requires_redraw = false;
for layer in &mut self.layers { for layer in &mut self.layers {
@ -48,7 +47,7 @@ impl LayerData for FolderLayer {
} }
} }
impl FolderLayer { impl FolderLegacyLayer {
/// When a insertion ID is provided, try to insert the layer with the given ID. /// When a insertion ID is provided, try to insert the layer with the given ID.
/// If that ID is already used, return `None`. /// If that ID is already used, return `None`.
/// When no insertion ID is provided, search for the next free ID and insert it with that. /// When no insertion ID is provided, search for the next free ID and insert it with that.
@ -56,20 +55,20 @@ impl FolderLayer {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer; /// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer; /// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
/// # use graphite_document_legacy::layers::style::PathStyle; /// # use graphite_document_legacy::layers::style::PathStyle;
/// # use graphite_document_legacy::layers::layer_info::LayerDataType; /// # use graphite_document_legacy::layers::layer_info::LegacyLayerType;
/// let mut folder = FolderLayer::default(); /// let mut folder = FolderLegacyLayer::default();
/// ///
/// // Create two layers to be added to the folder /// // Create two layers to be added to the folder
/// let mut shape_layer = ShapeLayer::rectangle(PathStyle::default()); /// let mut shape_layer = ShapeLegacyLayer::rectangle(PathStyle::default());
/// let mut folder_layer = FolderLayer::default(); /// let mut folder_layer = FolderLegacyLayer::default();
/// ///
/// folder.add_layer(shape_layer.into(), None, -1); /// folder.add_layer(shape_layer.into(), None, -1);
/// folder.add_layer(folder_layer.into(), Some(123), 0); /// folder.add_layer(folder_layer.into(), Some(123), 0);
/// ``` /// ```
pub fn add_layer(&mut self, layer: Layer, id: Option<LayerId>, insert_index: isize) -> Option<LayerId> { pub fn add_layer(&mut self, layer: LegacyLayer, id: Option<LayerId>, insert_index: isize) -> Option<LayerId> {
let mut insert_index = insert_index as i128; let mut insert_index = insert_index as i128;
// Bounds check for the insert index // Bounds check for the insert index
@ -104,14 +103,14 @@ impl FolderLayer {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer; /// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
/// let mut folder = FolderLayer::default(); /// let mut folder = FolderLegacyLayer::default();
/// ///
/// // Try to remove a layer that does not exist /// // Try to remove a layer that does not exist
/// assert!(folder.remove_layer(123).is_err()); /// assert!(folder.remove_layer(123).is_err());
/// ///
/// // Add another folder to the folder /// // Add another folder to the folder
/// folder.add_layer(FolderLayer::default().into(), Some(123), -1); /// folder.add_layer(FolderLegacyLayer::default().into(), Some(123), -1);
/// ///
/// // Try to remove that folder again /// // Try to remove that folder again
/// assert!(folder.remove_layer(123).is_ok()); /// assert!(folder.remove_layer(123).is_ok());
@ -130,21 +129,21 @@ impl FolderLayer {
} }
/// Get references to all the [Layer]s in the folder. /// Get references to all the [Layer]s in the folder.
pub fn layers(&self) -> &[Layer] { pub fn layers(&self) -> &[LegacyLayer] {
self.layers.as_slice() self.layers.as_slice()
} }
/// Get mutable references to all the [Layer]s in the folder. /// Get mutable references to all the [Layer]s in the folder.
pub fn layers_mut(&mut self) -> &mut [Layer] { pub fn layers_mut(&mut self) -> &mut [LegacyLayer] {
self.layers.as_mut_slice() self.layers.as_mut_slice()
} }
pub fn layer(&self, id: LayerId) -> Option<&Layer> { pub fn layer(&self, id: LayerId) -> Option<&LegacyLayer> {
let pos = self.position_of_layer(id).ok()?; let pos = self.position_of_layer(id).ok()?;
Some(&self.layers[pos]) Some(&self.layers[pos])
} }
pub fn layer_mut(&mut self, id: LayerId) -> Option<&mut Layer> { pub fn layer_mut(&mut self, id: LayerId) -> Option<&mut LegacyLayer> {
let pos = self.position_of_layer(id).ok()?; let pos = self.position_of_layer(id).ok()?;
Some(&mut self.layers[pos]) Some(&mut self.layers[pos])
} }
@ -157,14 +156,14 @@ impl FolderLayer {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer; /// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
/// let mut folder = FolderLayer::default(); /// let mut folder = FolderLegacyLayer::default();
/// ///
/// // Search for an id that does not exist /// // Search for an id that does not exist
/// assert!(!folder.folder_contains(123)); /// assert!(!folder.folder_contains(123));
/// ///
/// // Add layer with the id "123" to the folder /// // Add layer with the id "123" to the folder
/// folder.add_layer(FolderLayer::default().into(), Some(123), -1); /// folder.add_layer(FolderLegacyLayer::default().into(), Some(123), -1);
/// ///
/// // Search for the id "123" /// // Search for the id "123"
/// assert!(folder.folder_contains(123)); /// assert!(folder.folder_contains(123));
@ -178,15 +177,15 @@ impl FolderLayer {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer; /// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
/// let mut folder = FolderLayer::default(); /// let mut folder = FolderLegacyLayer::default();
/// ///
/// // Search for an id that does not exist /// // Search for an id that does not exist
/// assert!(folder.position_of_layer(123).is_err()); /// assert!(folder.position_of_layer(123).is_err());
/// ///
/// // Add layer with the id "123" to the folder /// // Add layer with the id "123" to the folder
/// folder.add_layer(FolderLayer::default().into(), Some(123), -1); /// folder.add_layer(FolderLegacyLayer::default().into(), Some(123), -1);
/// folder.add_layer(FolderLayer::default().into(), Some(42), -1); /// folder.add_layer(FolderLegacyLayer::default().into(), Some(42), -1);
/// ///
/// assert_eq!(folder.position_of_layer(123), Ok(0)); /// assert_eq!(folder.position_of_layer(123), Ok(0));
/// assert_eq!(folder.position_of_layer(42), Ok(1)); /// assert_eq!(folder.position_of_layer(42), Ok(1));
@ -201,26 +200,27 @@ impl FolderLayer {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer; /// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer; /// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
/// # use graphite_document_legacy::layers::style::PathStyle; /// # use graphite_document_legacy::layers::style::PathStyle;
/// let mut folder = FolderLayer::default(); /// let mut folder = FolderLegacyLayer::default();
/// ///
/// // Search for an id that does not exist /// // Search for an id that does not exist
/// assert!(folder.folder(132).is_none()); /// assert!(folder.folder(132).is_none());
/// ///
/// // add a folder and search for it /// // add a folder and search for it
/// folder.add_layer(FolderLayer::default().into(), Some(123), -1); /// folder.add_layer(FolderLegacyLayer::default().into(), Some(123), -1);
/// assert!(folder.folder(123).is_some()); /// assert!(folder.folder(123).is_some());
/// ///
/// // add a non-folder layer and search for it /// // add a non-folder layer and search for it
/// folder.add_layer(ShapeLayer::rectangle(PathStyle::default()).into(), Some(42), -1); /// folder.add_layer(ShapeLegacyLayer::rectangle(PathStyle::default()).into(), Some(42), -1);
/// assert!(folder.folder(42).is_none()); /// assert!(folder.folder(42).is_none());
/// ``` /// ```
pub fn folder(&self, id: LayerId) -> Option<&FolderLayer> { pub fn folder(&self, id: LayerId) -> Option<&FolderLegacyLayer> {
match self.layer(id) { match self.layer(id) {
Some(Layer { Some(LegacyLayer {
data: LayerDataType::Folder(folder), .. data: LegacyLayerType::Folder(folder),
..
}) => Some(folder), }) => Some(folder),
_ => None, _ => None,
} }
@ -229,11 +229,12 @@ impl FolderLayer {
/// Tries to get a mutable reference to folder with the given `id`. /// Tries to get a mutable reference to folder with the given `id`.
/// This operation will return `None` if either no layer with `id` exists /// This operation will return `None` if either no layer with `id` exists
/// in the folder or the layer with matching ID is not a folder. /// in the folder or the layer with matching ID is not a folder.
/// See the [FolderLayer::folder] method for a usage example. /// See the [FolderLegacyLayer::folder] method for a usage example.
pub fn folder_mut(&mut self, id: LayerId) -> Option<&mut FolderLayer> { pub fn folder_mut(&mut self, id: LayerId) -> Option<&mut FolderLegacyLayer> {
match self.layer_mut(id) { match self.layer_mut(id) {
Some(Layer { Some(LegacyLayer {
data: LayerDataType::Folder(folder), .. data: LegacyLayerType::Folder(folder),
..
}) => Some(folder), }) => Some(folder),
_ => None, _ => None,
} }

View file

@ -1,6 +1,6 @@
use super::folder_layer::FolderLayer; use super::folder_layer::FolderLegacyLayer;
use super::layer_layer::LayerLayer; use super::layer_layer::LayerLegacyLayer;
use super::shape_layer::ShapeLayer; use super::shape_layer::ShapeLegacyLayer;
use super::style::{PathStyle, RenderData}; use super::style::{PathStyle, RenderData};
use crate::intersection::Quad; use crate::intersection::Quad;
use crate::DocumentError; use crate::DocumentError;
@ -17,29 +17,35 @@ use std::fmt::Write;
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
/// Represents different types of layers. /// Represents different types of layers.
pub enum LayerDataType { pub enum LegacyLayerType {
/// A layer that wraps a [FolderLayer] struct. /// A layer that wraps a [FolderLegacyLayer] struct.
Folder(FolderLayer), Folder(FolderLegacyLayer),
/// A layer that wraps a [ShapeLayer] struct. Still used by the overlays system, but will be removed in the future. /// A layer that wraps a [ShapeLegacyLayer] struct. Still used by the overlays system, but will be removed in the future.
Shape(ShapeLayer), Shape(ShapeLegacyLayer),
/// A layer that wraps an [LayerLayer] struct. /// A layer that wraps an [LayerLegacyLayer] struct.
Layer(LayerLayer), Layer(LayerLegacyLayer),
} }
impl LayerDataType { impl Default for LegacyLayerType {
fn default() -> Self {
LegacyLayerType::Folder(FolderLegacyLayer::default())
}
}
impl LegacyLayerType {
pub fn inner(&self) -> &dyn LayerData { pub fn inner(&self) -> &dyn LayerData {
match self { match self {
LayerDataType::Shape(shape) => shape, LegacyLayerType::Shape(shape) => shape,
LayerDataType::Folder(folder) => folder, LegacyLayerType::Folder(folder) => folder,
LayerDataType::Layer(layer) => layer, LegacyLayerType::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(shape) => shape, LegacyLayerType::Shape(shape) => shape,
LayerDataType::Folder(folder) => folder, LegacyLayerType::Folder(folder) => folder,
LayerDataType::Layer(layer) => layer, LegacyLayerType::Layer(layer) => layer,
} }
} }
} }
@ -63,9 +69,9 @@ impl fmt::Display for LayerDataTypeDiscriminant {
} }
} }
impl From<&LayerDataType> for LayerDataTypeDiscriminant { impl From<&LegacyLayerType> for LayerDataTypeDiscriminant {
fn from(data: &LayerDataType) -> Self { fn from(data: &LegacyLayerType) -> Self {
use LayerDataType::*; use LegacyLayerType::*;
match data { match data {
Folder(_) => LayerDataTypeDiscriminant::Folder, Folder(_) => LayerDataTypeDiscriminant::Folder,
@ -77,23 +83,23 @@ impl From<&LayerDataType> for LayerDataTypeDiscriminant {
// ** CONVERSIONS ** // ** CONVERSIONS **
impl<'a> TryFrom<&'a mut Layer> for &'a mut Subpath { impl<'a> TryFrom<&'a mut LegacyLayer> for &'a mut Subpath {
type Error = &'static str; type Error = &'static str;
/// Convert a mutable layer into a mutable [Subpath]. /// Convert a mutable layer into a mutable [Subpath].
fn try_from(layer: &'a mut Layer) -> Result<&'a mut Subpath, Self::Error> { fn try_from(layer: &'a mut LegacyLayer) -> Result<&'a mut Subpath, Self::Error> {
match &mut layer.data { match &mut layer.data {
LayerDataType::Shape(layer) => Ok(&mut layer.shape), LegacyLayerType::Shape(layer) => Ok(&mut layer.shape),
_ => Err("Did not find any shape data in the layer"), _ => Err("Did not find any shape data in the layer"),
} }
} }
} }
impl<'a> TryFrom<&'a Layer> for &'a Subpath { impl<'a> TryFrom<&'a LegacyLayer> for &'a Subpath {
type Error = &'static str; type Error = &'static str;
/// Convert a reference to a layer into a reference of a [Subpath]. /// Convert a reference to a layer into a reference of a [Subpath].
fn try_from(layer: &'a Layer) -> Result<&'a Subpath, Self::Error> { fn try_from(layer: &'a LegacyLayer) -> Result<&'a Subpath, Self::Error> {
match &layer.data { match &layer.data {
LayerDataType::Shape(layer) => Ok(&layer.shape), LegacyLayerType::Shape(layer) => Ok(&layer.shape),
_ => Err("Did not find any shape data in the layer"), _ => Err("Did not find any shape data in the layer"),
} }
} }
@ -105,12 +111,12 @@ pub trait LayerData {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer; /// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
/// # use graphite_document_legacy::layers::style::{Fill, PathStyle, ViewMode, RenderData}; /// # use graphite_document_legacy::layers::style::{Fill, PathStyle, ViewMode, RenderData};
/// # use graphite_document_legacy::layers::layer_info::LayerData; /// # use graphite_document_legacy::layers::layer_info::LayerData;
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// ///
/// let mut shape = ShapeLayer::rectangle(PathStyle::new(None, Fill::None)); /// let mut shape = ShapeLegacyLayer::rectangle(PathStyle::new(None, Fill::None));
/// let mut svg = String::new(); /// let mut svg = String::new();
/// ///
/// // Render the shape without any transforms, in normal view mode /// // Render the shape without any transforms, in normal view mode
@ -130,14 +136,14 @@ pub trait LayerData {
/// Determine the layers within this layer that intersect a given quad. /// Determine the layers within this layer that intersect a given quad.
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer; /// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
/// # use graphite_document_legacy::layers::style::{Fill, PathStyle, ViewMode, RenderData}; /// # use graphite_document_legacy::layers::style::{Fill, PathStyle, ViewMode, RenderData};
/// # use graphite_document_legacy::layers::layer_info::LayerData; /// # use graphite_document_legacy::layers::layer_info::LayerData;
/// # use graphite_document_legacy::intersection::Quad; /// # use graphite_document_legacy::intersection::Quad;
/// # use glam::f64::{DAffine2, DVec2}; /// # use glam::f64::{DAffine2, DVec2};
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// ///
/// let mut shape = ShapeLayer::ellipse(PathStyle::new(None, Fill::None)); /// let mut shape = ShapeLegacyLayer::ellipse(PathStyle::new(None, Fill::None));
/// let shape_id = 42; /// let shape_id = 42;
/// let mut svg = String::new(); /// let mut svg = String::new();
/// ///
@ -156,12 +162,12 @@ pub trait LayerData {
/// Calculate the bounding box for the layer's contents after applying a given transform. /// Calculate the bounding box for the layer's contents after applying a given transform.
/// # Example /// # Example
/// ```no_run /// ```no_run
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer; /// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
/// # use graphite_document_legacy::layers::style::{Fill, PathStyle, RenderData}; /// # use graphite_document_legacy::layers::style::{Fill, PathStyle, RenderData};
/// # use graphite_document_legacy::layers::layer_info::LayerData; /// # use graphite_document_legacy::layers::layer_info::LayerData;
/// # use glam::f64::{DAffine2, DVec2}; /// # use glam::f64::{DAffine2, DVec2};
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// let shape = ShapeLayer::ellipse(PathStyle::new(None, Fill::None)); /// let shape = ShapeLegacyLayer::ellipse(PathStyle::new(None, Fill::None));
/// ///
/// // Calculate the bounding box without applying any transformations. /// // Calculate the bounding box without applying any transformations.
/// // (The identity transform maps every vector to itself.) /// // (The identity transform maps every vector to itself.)
@ -175,7 +181,7 @@ pub trait LayerData {
fn bounding_box(&self, transform: glam::DAffine2, render_data: &RenderData) -> Option<[DVec2; 2]>; fn bounding_box(&self, transform: glam::DAffine2, render_data: &RenderData) -> Option<[DVec2; 2]>;
} }
impl LayerData for LayerDataType { impl LayerData for LegacyLayerType {
fn render(&mut self, svg: &mut String, svg_defs: &mut String, transforms: &mut Vec<glam::DAffine2>, render_data: &RenderData) -> bool { fn render(&mut self, svg: &mut String, svg_defs: &mut String, transforms: &mut Vec<glam::DAffine2>, render_data: &RenderData) -> bool {
self.inner_mut().render(svg, svg_defs, transforms, render_data) self.inner_mut().render(svg, svg_defs, transforms, render_data)
} }
@ -203,13 +209,13 @@ fn return_true() -> bool {
} }
#[derive(Debug, PartialEq, Deserialize, Serialize)] #[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct Layer { pub struct LegacyLayer {
/// Whether the layer is currently visible or hidden. /// Whether the layer is currently visible or hidden.
pub visible: bool, pub visible: bool,
/// The user-given name of the layer. /// The user-given name of the layer.
pub name: Option<String>, pub name: Option<String>,
/// The type of layer, such as folder or shape. /// The type of layer, such as folder or shape.
pub data: LayerDataType, pub data: LegacyLayerType,
/// A transformation applied to the layer (translation, rotation, scaling, and shear). /// A transformation applied to the layer (translation, rotation, scaling, and shear).
#[serde(with = "DAffine2Ref")] #[serde(with = "DAffine2Ref")]
pub transform: glam::DAffine2, pub transform: glam::DAffine2,
@ -237,8 +243,27 @@ pub struct Layer {
pub opacity: f64, pub opacity: f64,
} }
impl Layer { impl Default for LegacyLayer {
pub fn new(data: LayerDataType, transform: [f64; 6]) -> Self { fn default() -> Self {
Self {
visible: Default::default(),
name: Default::default(),
data: Default::default(),
transform: Default::default(),
preserve_aspect: Default::default(),
pivot: Default::default(),
thumbnail_cache: Default::default(),
cache: Default::default(),
svg_defs_cache: Default::default(),
cache_dirty: Default::default(),
blend_mode: Default::default(),
opacity: Default::default(),
}
}
}
impl LegacyLayer {
pub fn new(data: LegacyLayerType, transform: [f64; 6]) -> Self {
Self { Self {
visible: true, visible: true,
name: None, name: None,
@ -256,7 +281,7 @@ impl Layer {
} }
/// Gets a child layer of this layer, by a path. If the layer with id 1 is inside a folder with id 0, the path will be [0, 1]. /// Gets a child layer of this layer, by a path. If the layer with id 1 is inside a folder with id 0, the path will be [0, 1].
pub fn child(&self, path: &[LayerId]) -> Option<&Layer> { pub fn child(&self, path: &[LayerId]) -> Option<&LegacyLayer> {
let mut layer = self; let mut layer = self;
for id in path { for id in path {
layer = layer.as_folder().ok()?.layer(*id)?; layer = layer.as_folder().ok()?.layer(*id)?;
@ -265,7 +290,7 @@ impl Layer {
} }
/// Gets a child layer of this layer, by a path. If the layer with id 1 is inside a folder with id 0, the path will be [0, 1]. /// Gets a child layer of this layer, by a path. If the layer with id 1 is inside a folder with id 0, the path will be [0, 1].
pub fn child_mut(&mut self, path: &[LayerId]) -> Option<&mut Layer> { pub fn child_mut(&mut self, path: &[LayerId]) -> Option<&mut LegacyLayer> {
let mut layer = self; let mut layer = self;
for id in path { for id in path {
layer = layer.as_folder_mut().ok()?.layer_mut(*id)?; layer = layer.as_folder_mut().ok()?.layer_mut(*id)?;
@ -275,23 +300,23 @@ impl Layer {
/// Iterate over the layers encapsulated by this layer. /// Iterate over the layers encapsulated by this layer.
/// If the [Layer type](Layer::data) is not a folder, the only item in the iterator will be the layer itself. /// If the [Layer type](Layer::data) is not a folder, the only item in the iterator will be the layer itself.
/// If the [Layer type](Layer::data) wraps a [Folder](LayerDataType::Folder), the iterator will recursively yield all the layers contained in the folder as well as potential sub-folders. /// If the [Layer type](Layer::data) wraps a [Folder](LegacyLayerType::Folder), the iterator will recursively yield all the layers contained in the folder as well as potential sub-folders.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer; /// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
/// # use graphite_document_legacy::layers::layer_info::Layer; /// # use graphite_document_legacy::layers::layer_info::Layer;
/// # use graphite_document_legacy::layers::style::PathStyle; /// # use graphite_document_legacy::layers::style::PathStyle;
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer; /// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
/// let mut root_folder = FolderLayer::default(); /// let mut root_folder = FolderLegacyLayer::default();
/// ///
/// // Add a shape to the root folder /// // Add a shape to the root folder
/// let child_1: Layer = ShapeLayer::rectangle(PathStyle::default()).into(); /// let child_1: Layer = ShapeLegacyLayer::rectangle(PathStyle::default()).into();
/// root_folder.add_layer(child_1.clone(), None, -1); /// root_folder.add_layer(child_1.clone(), None, -1);
/// ///
/// // Add a folder containing another shape to the root layer /// // Add a folder containing another shape to the root layer
/// let mut child_folder = FolderLayer::default(); /// let mut child_folder = FolderLegacyLayer::default();
/// let grandchild: Layer = ShapeLayer::rectangle(PathStyle::default()).into(); /// let grandchild: Layer = ShapeLegacyLayer::rectangle(PathStyle::default()).into();
/// child_folder.add_layer(grandchild.clone(), None, -1); /// child_folder.add_layer(grandchild.clone(), None, -1);
/// let child_2: Layer = child_folder.into(); /// let child_2: Layer = child_folder.into();
/// root_folder.add_layer(child_2.clone(), None, -1); /// root_folder.add_layer(child_2.clone(), None, -1);
@ -371,14 +396,14 @@ impl Layer {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer; /// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
/// # use graphite_document_legacy::layers::layer_info::Layer; /// # use graphite_document_legacy::layers::layer_info::Layer;
/// # use graphite_document_legacy::layers::style::{PathStyle, RenderData}; /// # use graphite_document_legacy::layers::style::{PathStyle, RenderData};
/// # use glam::DVec2; /// # use glam::DVec2;
/// # use glam::f64::DAffine2; /// # use glam::f64::DAffine2;
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// // Create a rectangle with the default dimensions, from `(0|0)` to `(1|1)` /// // Create a rectangle with the default dimensions, from `(0|0)` to `(1|1)`
/// let layer: Layer = ShapeLayer::rectangle(PathStyle::default()).into(); /// let layer: Layer = ShapeLegacyLayer::rectangle(PathStyle::default()).into();
/// ///
/// // Apply the Identity transform, which leaves the points unchanged /// // Apply the Identity transform, which leaves the points unchanged
/// let transform = DAffine2::IDENTITY; /// let transform = DAffine2::IDENTITY;
@ -430,79 +455,79 @@ impl Layer {
} }
/// Get a mutable reference to the Folder wrapped by the layer. /// Get a mutable reference to the Folder wrapped by the layer.
/// This operation will fail if the [Layer type](Layer::data) is not `LayerDataType::Folder`. /// This operation will fail if the [Layer type](Layer::data) is not `LegacyLayerType::Folder`.
pub fn as_folder_mut(&mut self) -> Result<&mut FolderLayer, DocumentError> { pub fn as_folder_mut(&mut self) -> Result<&mut FolderLegacyLayer, DocumentError> {
match &mut self.data { match &mut self.data {
LayerDataType::Folder(f) => Ok(f), LegacyLayerType::Folder(f) => Ok(f),
_ => Err(DocumentError::NotFolder), _ => Err(DocumentError::NotFolder),
} }
} }
pub fn as_vector_data(&self) -> Option<&VectorData> { pub fn as_vector_data(&self) -> Option<&VectorData> {
match &self.data { match &self.data {
LayerDataType::Layer(layer) => layer.as_vector_data(), LegacyLayerType::Layer(layer) => layer.as_vector_data(),
_ => None, _ => None,
} }
} }
pub fn as_subpath_mut(&mut self) -> Option<&mut Subpath> { pub fn as_subpath_mut(&mut self) -> Option<&mut Subpath> {
match &mut self.data { match &mut self.data {
LayerDataType::Shape(s) => Some(&mut s.shape), LegacyLayerType::Shape(s) => Some(&mut s.shape),
_ => None, _ => None,
} }
} }
/// Get a reference to the Folder wrapped by the layer. /// Get a reference to the Folder wrapped by the layer.
/// This operation will fail if the [Layer type](Layer::data) is not `LayerDataType::Folder`. /// This operation will fail if the [Layer type](Layer::data) is not `LegacyLayerType::Folder`.
pub fn as_folder(&self) -> Result<&FolderLayer, DocumentError> { pub fn as_folder(&self) -> Result<&FolderLegacyLayer, DocumentError> {
match &self.data { match &self.data {
LayerDataType::Folder(f) => Ok(f), LegacyLayerType::Folder(f) => Ok(f),
_ => Err(DocumentError::NotFolder), _ => Err(DocumentError::NotFolder),
} }
} }
/// 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::Layer`. /// This operation will fail if the [Layer type](Layer::data) is not `LegacyLayerType::Layer`.
pub fn as_layer_network_mut(&mut self) -> Result<&mut graph_craft::document::NodeNetwork, DocumentError> { pub fn as_layer_network_mut(&mut self) -> Result<&mut graph_craft::document::NodeNetwork, DocumentError> {
match &mut self.data { match &mut self.data {
LayerDataType::Layer(layer) => Ok(&mut layer.network), LegacyLayerType::Layer(layer) => Ok(&mut layer.network),
_ => Err(DocumentError::NotLayer), _ => Err(DocumentError::NotLayer),
} }
} }
/// 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::Layer`. /// This operation will fail if the [Layer type](Layer::data) is not `LegacyLayerType::Layer`.
pub fn as_layer_network(&self) -> Result<&graph_craft::document::NodeNetwork, DocumentError> { pub fn as_layer_network(&self) -> Result<&graph_craft::document::NodeNetwork, DocumentError> {
match &self.data { match &self.data {
LayerDataType::Layer(layer) => Ok(&layer.network), LegacyLayerType::Layer(layer) => Ok(&layer.network),
_ => Err(DocumentError::NotLayer), _ => Err(DocumentError::NotLayer),
} }
} }
pub fn as_layer(&self) -> Result<&LayerLayer, DocumentError> { pub fn as_layer(&self) -> Result<&LayerLegacyLayer, DocumentError> {
match &self.data { match &self.data {
LayerDataType::Layer(layer) => Ok(layer), LegacyLayerType::Layer(layer) => Ok(layer),
_ => Err(DocumentError::NotLayer), _ => Err(DocumentError::NotLayer),
} }
} }
pub fn style(&self) -> Result<&PathStyle, DocumentError> { pub fn style(&self) -> Result<&PathStyle, DocumentError> {
match &self.data { match &self.data {
LayerDataType::Shape(shape) => Ok(&shape.style), LegacyLayerType::Shape(shape) => Ok(&shape.style),
LayerDataType::Layer(layer) => layer.as_vector_data().map(|vector| &vector.style).ok_or(DocumentError::NotShape), LegacyLayerType::Layer(layer) => layer.as_vector_data().map(|vector| &vector.style).ok_or(DocumentError::NotShape),
_ => Err(DocumentError::NotShape), _ => Err(DocumentError::NotShape),
} }
} }
pub fn style_mut(&mut self) -> Result<&mut PathStyle, DocumentError> { pub fn style_mut(&mut self) -> Result<&mut PathStyle, DocumentError> {
match &mut self.data { match &mut self.data {
LayerDataType::Shape(s) => Ok(&mut s.style), LegacyLayerType::Shape(s) => Ok(&mut s.style),
_ => Err(DocumentError::NotShape), _ => Err(DocumentError::NotShape),
} }
} }
} }
impl Clone for Layer { impl Clone for LegacyLayer {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
visible: self.visible, visible: self.visible,
@ -521,20 +546,20 @@ impl Clone for Layer {
} }
} }
impl From<FolderLayer> for Layer { impl From<FolderLegacyLayer> for LegacyLayer {
fn from(from: FolderLayer) -> Layer { fn from(from: FolderLegacyLayer) -> LegacyLayer {
Layer::new(LayerDataType::Folder(from), DAffine2::IDENTITY.to_cols_array()) LegacyLayer::new(LegacyLayerType::Folder(from), DAffine2::IDENTITY.to_cols_array())
} }
} }
impl From<ShapeLayer> for Layer { impl From<ShapeLegacyLayer> for LegacyLayer {
fn from(from: ShapeLayer) -> Layer { fn from(from: ShapeLegacyLayer) -> LegacyLayer {
Layer::new(LayerDataType::Shape(from), DAffine2::IDENTITY.to_cols_array()) LegacyLayer::new(LegacyLayerType::Shape(from), DAffine2::IDENTITY.to_cols_array())
} }
} }
impl<'a> IntoIterator for &'a Layer { impl<'a> IntoIterator for &'a LegacyLayer {
type Item = &'a Layer; type Item = &'a LegacyLayer;
type IntoIter = LayerIter<'a>; type IntoIter = LayerIter<'a>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
@ -546,16 +571,16 @@ impl<'a> IntoIterator for &'a Layer {
/// See [Layer::iter] for more information. /// See [Layer::iter] for more information.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct LayerIter<'a> { pub struct LayerIter<'a> {
pub stack: Vec<&'a Layer>, pub stack: Vec<&'a LegacyLayer>,
} }
impl<'a> Iterator for LayerIter<'a> { impl<'a> Iterator for LayerIter<'a> {
type Item = &'a Layer; type Item = &'a LegacyLayer;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match self.stack.pop() { match self.stack.pop() {
Some(layer) => { Some(layer) => {
if let LayerDataType::Folder(folder) = &layer.data { if let LegacyLayerType::Folder(folder) = &layer.data {
let layers = folder.layers(); let layers = folder.layers();
self.stack.extend(layers); self.stack.extend(layers);
}; };

View file

@ -21,7 +21,7 @@ pub enum CachedOutputData {
} }
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)] #[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
pub struct LayerLayer { pub struct LayerLegacyLayer {
/// 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,
@ -29,7 +29,7 @@ pub struct LayerLayer {
pub cached_output_data: CachedOutputData, pub cached_output_data: CachedOutputData,
} }
impl LayerData for LayerLayer { impl LayerData for LayerLegacyLayer {
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();
@ -138,7 +138,7 @@ impl LayerData for LayerLayer {
} }
} }
impl LayerLayer { impl LayerLegacyLayer {
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,

View file

@ -2,9 +2,9 @@
//! A document consists of a set of [Layers](layer_info::Layer). //! A document consists of a set of [Layers](layer_info::Layer).
//! Layers allow the user to mutate part of the document while leaving the rest unchanged. //! Layers allow the user to mutate part of the document while leaving the rest unchanged.
//! 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::FolderLegacyLayer), 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 (deprecated but still used by the overlays system). //! * [Shape layers](shape_layer::ShapeLegacyLayer), which contain generic SVG [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)s (deprecated but still used by the overlays system).
//! * [Layer layers](layer_layer::LayerLayer), which contain a node graph layer //! * [Layer layers](layer_layer::LayerLegacyLayer), 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.
//! //!
@ -14,14 +14,14 @@
//! using the CSS [`mix-blend-mode`](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode) property and the layer opacity. //! using the CSS [`mix-blend-mode`](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode) property and the layer opacity.
pub mod base64_serde; pub mod base64_serde;
/// Contains the [FolderLayer](folder_layer::FolderLayer) type that encapsulates other layers, including more folders. /// Contains the [FolderLegacyLayer](folder_layer::FolderLegacyLayer) type that encapsulates other layers, including more folders.
pub mod folder_layer; 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 [LayerLayer](nodegraph_layer::LayerLayer) type that contains a node graph. /// Contains the [LayerLegacyLayer](nodegraph_layer::LayerLegacyLayer) type that contains a node graph.
pub mod layer_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 [ShapeLegacyLayer](shape_layer::ShapeLegacyLayer) type, a generic SVG element defined using Bezier paths.
pub mod shape_layer; pub mod shape_layer;
mod render_data; mod render_data;

View file

@ -16,7 +16,7 @@ use std::fmt::Write;
/// [`<g>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g) /// [`<g>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g)
/// group that the transformation matrix is applied to. /// group that the transformation matrix is applied to.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, specta::Type)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, specta::Type)]
pub struct ShapeLayer { pub struct ShapeLegacyLayer {
/// The geometry of the layer. /// The geometry of the layer.
pub shape: Subpath, pub shape: Subpath,
/// The visual style of the shape. /// The visual style of the shape.
@ -25,7 +25,7 @@ pub struct ShapeLayer {
pub render_index: i32, pub render_index: i32,
} }
impl LayerData for ShapeLayer { impl LayerData for ShapeLegacyLayer {
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 mut subpath = self.shape.clone(); let mut subpath = self.shape.clone();
@ -76,8 +76,8 @@ impl LayerData for ShapeLayer {
} }
} }
impl ShapeLayer { impl ShapeLegacyLayer {
/// Construct a new [ShapeLayer] with the specified [Subpath] and [PathStyle] /// Construct a new [ShapeLegacyLayer] with the specified [Subpath] and [PathStyle]
pub fn new(shape: Subpath, style: PathStyle) -> Self { pub fn new(shape: Subpath, style: PathStyle) -> Self {
Self { shape, style, render_index: 1 } Self { shape, style, render_index: 1 }
} }

View file

@ -1,4 +1,4 @@
use crate::layers::layer_info::Layer; use crate::layers::layer_info::LegacyLayer;
use crate::layers::style::{self, Stroke}; use crate::layers::style::{self, Stroke};
use crate::LayerId; use crate::LayerId;
@ -48,7 +48,7 @@ pub enum Operation {
new_name: String, new_name: String,
}, },
InsertLayer { InsertLayer {
layer: Box<Layer>, layer: Box<LegacyLayer>,
destination_path: Vec<LayerId>, destination_path: Vec<LayerId>,
insert_index: isize, insert_index: isize,
duplicating: bool, duplicating: bool,

View file

@ -18,7 +18,7 @@ use crate::node_graph_executor::NodeGraphExecutor;
use document_legacy::document::Document as DocumentLegacy; use document_legacy::document::Document as DocumentLegacy;
use document_legacy::document_metadata::LayerNodeIdentifier; use document_legacy::document_metadata::LayerNodeIdentifier;
use document_legacy::layers::layer_info::{LayerDataType, LayerDataTypeDiscriminant}; use document_legacy::layers::layer_info::{LayerDataTypeDiscriminant, LegacyLayerType};
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;
@ -44,7 +44,8 @@ pub struct DocumentMessageHandler {
pub version: String, pub version: String,
#[serde(default)] #[serde(default)]
pub commit_hash: String, pub commit_hash: String,
#[serde(default)]
pub collapsed_folders: Vec<LayerNodeIdentifier>,
pub document_mode: DocumentMode, pub document_mode: DocumentMode,
pub view_mode: ViewMode, pub view_mode: ViewMode,
#[serde(skip)] #[serde(skip)]
@ -52,7 +53,6 @@ pub struct DocumentMessageHandler {
pub overlays_visible: bool, pub overlays_visible: bool,
#[serde(default = "return_true")] #[serde(default = "return_true")]
pub rulers_visible: bool, pub rulers_visible: bool,
#[serde(skip)] #[serde(skip)]
pub document_undo_history: VecDeque<DocumentSave>, pub document_undo_history: VecDeque<DocumentSave>,
#[serde(skip)] #[serde(skip)]
@ -60,12 +60,10 @@ pub struct DocumentMessageHandler {
/// Don't allow aborting transactions whilst undoing to avoid #559 /// Don't allow aborting transactions whilst undoing to avoid #559
#[serde(skip)] #[serde(skip)]
undo_in_progress: bool, undo_in_progress: bool,
#[serde(with = "vectorize_layer_metadata")] #[serde(with = "vectorize_layer_metadata")]
pub layer_metadata: HashMap<Vec<LayerId>, LayerMetadata>, pub layer_metadata: HashMap<Vec<LayerId>, LayerMetadata>,
#[serde(skip)] #[serde(skip)]
layer_range_selection_reference: Option<LayerNodeIdentifier>, layer_range_selection_reference: Option<LayerNodeIdentifier>,
navigation_handler: NavigationMessageHandler, navigation_handler: NavigationMessageHandler,
#[serde(skip)] #[serde(skip)]
overlays_message_handler: OverlaysMessageHandler, overlays_message_handler: OverlaysMessageHandler,
@ -84,20 +82,17 @@ impl Default for DocumentMessageHandler {
name: DEFAULT_DOCUMENT_NAME.to_string(), name: DEFAULT_DOCUMENT_NAME.to_string(),
version: GRAPHITE_DOCUMENT_VERSION.to_string(), version: GRAPHITE_DOCUMENT_VERSION.to_string(),
commit_hash: crate::application::GRAPHITE_GIT_COMMIT_HASH.to_string(), commit_hash: crate::application::GRAPHITE_GIT_COMMIT_HASH.to_string(),
collapsed_folders: Vec::new(),
document_mode: DocumentMode::DesignMode, document_mode: DocumentMode::DesignMode,
view_mode: ViewMode::default(), view_mode: ViewMode::default(),
snapping_state: SnappingState::default(), snapping_state: SnappingState::default(),
overlays_visible: true, overlays_visible: true,
rulers_visible: true, rulers_visible: true,
document_undo_history: VecDeque::new(), document_undo_history: VecDeque::new(),
document_redo_history: VecDeque::new(), document_redo_history: VecDeque::new(),
undo_in_progress: false, undo_in_progress: false,
layer_metadata: vec![(vec![], LayerMetadata::new(true))].into_iter().collect(), layer_metadata: vec![(vec![], LayerMetadata::new(true))].into_iter().collect(),
layer_range_selection_reference: None, layer_range_selection_reference: None,
navigation_handler: NavigationMessageHandler::default(), navigation_handler: NavigationMessageHandler::default(),
overlays_message_handler: OverlaysMessageHandler::default(), overlays_message_handler: OverlaysMessageHandler::default(),
properties_panel_message_handler: PropertiesPanelMessageHandler::default(), properties_panel_message_handler: PropertiesPanelMessageHandler::default(),
@ -199,13 +194,14 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
document: &mut self.document_legacy, document: &mut self.document_legacy,
document_id, document_id,
document_name: self.name.as_str(), document_name: self.name.as_str(),
collapsed_folders: &mut self.collapsed_folders,
input: ipp, input: ipp,
graph_view_overlay_open, graph_view_overlay_open,
}, },
); );
} }
#[remain::unsorted] #[remain::unsorted]
GraphOperation(message) => GraphOperationMessageHandler.process_message(message, responses, (&mut self.document_legacy, &mut self.node_graph_handler)), GraphOperation(message) => GraphOperationMessageHandler.process_message(message, responses, (&mut self.document_legacy, &mut self.collapsed_folders, &mut self.node_graph_handler)),
// Messages // Messages
AbortTransaction => { AbortTransaction => {
@ -388,7 +384,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
let layer = self.document_legacy.layer(layer_path).expect("Clearing Layer 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::Layer(layer) => layer.as_blob_url(), LegacyLayerType::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)),
}; };
@ -715,7 +711,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
// Revoke the old blob URL // Revoke the old blob URL
match &layer.data { match &layer.data {
LayerDataType::Layer(layer) => { LegacyLayerType::Layer(layer) => {
if let Some(url) = layer.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() });
} }
@ -785,10 +781,10 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
StartTransaction => self.backup(responses), StartTransaction => self.backup(responses),
ToggleLayerExpansion { layer } => { ToggleLayerExpansion { layer } => {
let layer = LayerNodeIdentifier::new(layer, self.network()); let layer = LayerNodeIdentifier::new(layer, self.network());
if self.document_legacy.collapsed_folders.contains(&layer) { if self.collapsed_folders.contains(&layer) {
self.document_legacy.collapsed_folders.retain(|&collapsed_layer| collapsed_layer != layer); self.collapsed_folders.retain(|&collapsed_layer| collapsed_layer != layer);
} else { } else {
self.document_legacy.collapsed_folders.push(layer); self.collapsed_folders.push(layer);
} }
responses.add(NodeGraphMessage::RunDocumentGraph); responses.add(NodeGraphMessage::RunDocumentGraph);
} }
@ -900,6 +896,7 @@ impl DocumentMessageHandler {
pub fn network(&self) -> &NodeNetwork { pub fn network(&self) -> &NodeNetwork {
&self.document_legacy.document_network &self.document_legacy.document_network
} }
pub fn metadata(&self) -> &document_legacy::document_metadata::DocumentMetadata { pub fn metadata(&self) -> &document_legacy::document_metadata::DocumentMetadata {
&self.document_legacy.metadata &self.document_legacy.metadata
} }
@ -1013,7 +1010,7 @@ impl DocumentMessageHandler {
for layer_node in folder.children(self.metadata()) { for layer_node in folder.children(self.metadata()) {
data.push(layer_node.to_node()); data.push(layer_node.to_node());
space += 1; space += 1;
if layer_node.has_children(self.metadata()) && !self.document_legacy.collapsed_folders.contains(&layer_node) { if layer_node.has_children(self.metadata()) && !self.collapsed_folders.contains(&layer_node) {
path.push(layer_node.to_node()); path.push(layer_node.to_node());
// TODO: Skip if folder is not expanded. // TODO: Skip if folder is not expanded.

View file

@ -571,8 +571,13 @@ impl<'a> ModifyInputsContext<'a> {
} }
} }
impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessageHandler)> for GraphOperationMessageHandler { impl MessageHandler<GraphOperationMessage, (&mut Document, &mut Vec<LayerNodeIdentifier>, &mut NodeGraphMessageHandler)> for GraphOperationMessageHandler {
fn process_message(&mut self, message: GraphOperationMessage, responses: &mut VecDeque<Message>, (document, node_graph): (&mut Document, &mut NodeGraphMessageHandler)) { fn process_message(
&mut self,
message: GraphOperationMessage,
responses: &mut VecDeque<Message>,
(document, collapsed_folders, node_graph): (&mut Document, &mut Vec<LayerNodeIdentifier>, &mut NodeGraphMessageHandler),
) {
match message { match message {
GraphOperationMessage::FillSet { layer, fill } => { GraphOperationMessage::FillSet { layer, fill } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document, node_graph, responses) { if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document, node_graph, responses) {
@ -652,7 +657,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
if let Some(layer) = modify_inputs.create_layer(id, modify_inputs.network.original_outputs()[0].node_id, 0, 0) { if let Some(layer) = modify_inputs.create_layer(id, modify_inputs.network.original_outputs()[0].node_id, 0, 0) {
modify_inputs.insert_artboard(artboard, layer); modify_inputs.insert_artboard(artboard, layer);
} }
document.load_network_structure(); load_network_structure(document, collapsed_folders);
} }
GraphOperationMessage::NewBitmapLayer { GraphOperationMessage::NewBitmapLayer {
id, id,
@ -705,14 +710,14 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
modify_inputs.responses.add(NodeGraphMessage::SendGraph { should_rerender: true }); modify_inputs.responses.add(NodeGraphMessage::SendGraph { should_rerender: true });
} }
document.load_network_structure(); load_network_structure(document, collapsed_folders);
} }
GraphOperationMessage::NewVectorLayer { id, subpaths, parent, insert_index } => { GraphOperationMessage::NewVectorLayer { id, subpaths, parent, insert_index } => {
let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses); let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses);
if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) { if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) {
modify_inputs.insert_vector_data(subpaths, layer); modify_inputs.insert_vector_data(subpaths, layer);
} }
document.load_network_structure(); load_network_structure(document, collapsed_folders);
} }
GraphOperationMessage::NewTextLayer { GraphOperationMessage::NewTextLayer {
id, id,
@ -726,7 +731,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) { if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) {
modify_inputs.insert_text(text, font, size, layer); modify_inputs.insert_text(text, font, size, layer);
} }
document.load_network_structure(); load_network_structure(document, collapsed_folders);
} }
GraphOperationMessage::ResizeArtboard { id, location, dimensions } => { GraphOperationMessage::ResizeArtboard { id, location, dimensions } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&[id], document, node_graph, responses) { if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&[id], document, node_graph, responses) {
@ -736,7 +741,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
GraphOperationMessage::DeleteLayer { id } => { GraphOperationMessage::DeleteLayer { id } => {
let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses); let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses);
modify_inputs.delete_layer(id); modify_inputs.delete_layer(id);
document.load_network_structure(); load_network_structure(document, collapsed_folders);
} }
GraphOperationMessage::ClearArtboards => { GraphOperationMessage::ClearArtboards => {
let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses); let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses);
@ -746,7 +751,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
modify_inputs.delete_layer(layer); modify_inputs.delete_layer(layer);
} }
} }
document.load_network_structure(); load_network_structure(document, collapsed_folders);
} }
} }
} }
@ -755,3 +760,8 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
actions!(GraphOperationMessage; ) actions!(GraphOperationMessage; )
} }
} }
pub fn load_network_structure(document: &mut Document, collapsed_folders: &mut Vec<LayerNodeIdentifier>) {
document.metadata.load_structure(&document.document_network);
collapsed_folders.retain(|&layer| document.metadata.layer_exists(layer));
}

View file

@ -1,10 +1,12 @@
pub use self::document_node_types::*; pub use self::document_node_types::*;
use super::load_network_structure;
use crate::messages::input_mapper::utility_types::macros::action_keys; use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::node_graph_executor::GraphIdentifier; use crate::node_graph_executor::GraphIdentifier;
use document_legacy::document::Document; use document_legacy::document::Document;
use document_legacy::document_metadata::LayerNodeIdentifier;
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, NodeId, NodeInput, NodeNetwork, NodeOutput}; use graph_craft::document::{DocumentNode, NodeId, NodeInput, NodeNetwork, NodeOutput};
@ -453,15 +455,20 @@ pub struct NodeGraphHandlerData<'a> {
pub document: &'a mut Document, pub document: &'a mut Document,
pub document_id: u64, pub document_id: u64,
pub document_name: &'a str, pub document_name: &'a str,
pub collapsed_folders: &'a mut Vec<LayerNodeIdentifier>,
pub input: &'a InputPreprocessorMessageHandler, pub input: &'a InputPreprocessorMessageHandler,
pub graph_view_overlay_open: bool, pub graph_view_overlay_open: bool,
} }
impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGraphMessageHandler { impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGraphMessageHandler {
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, data: NodeGraphHandlerData<'a>) { fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, data: NodeGraphHandlerData<'a>) {
let document = data.document; let NodeGraphHandlerData {
let document_id = data.document_id; document,
let graph_view_overlay_open = data.graph_view_overlay_open; document_id,
collapsed_folders,
graph_view_overlay_open,
..
} = data;
match message { match message {
// TODO: automatically remove broadcast messages. // TODO: automatically remove broadcast messages.
NodeGraphMessage::Init => { NodeGraphMessage::Init => {
@ -469,7 +476,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
on: BroadcastEvent::SelectionChanged, on: BroadcastEvent::SelectionChanged,
send: Box::new(NodeGraphMessage::SelectedNodesUpdated.into()), send: Box::new(NodeGraphMessage::SelectedNodesUpdated.into()),
}); });
document.load_network_structure(); load_network_structure(document, collapsed_folders);
responses.add(DocumentMessage::DocumentStructureChanged); responses.add(DocumentMessage::DocumentStructureChanged);
} }
NodeGraphMessage::SelectedNodesUpdated => { NodeGraphMessage::SelectedNodesUpdated => {
@ -811,7 +818,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
let structure_changed = node_input.as_node().is_some() || input.as_node().is_some(); let structure_changed = node_input.as_node().is_some() || input.as_node().is_some();
*node_input = input; *node_input = input;
if structure_changed { if structure_changed {
document.load_network_structure(); load_network_structure(document, collapsed_folders);
} }
} }
} }

View file

@ -7,7 +7,7 @@ use crate::messages::prelude::*;
use crate::node_graph_executor::NodeGraphExecutor; use crate::node_graph_executor::NodeGraphExecutor;
use document_legacy::document::Document; use document_legacy::document::Document;
use document_legacy::layers::layer_info::{Layer, LayerDataType}; use document_legacy::layers::layer_info::{LegacyLayer, LegacyLayerType};
use document_legacy::layers::style::{Fill, Gradient, GradientType, LineCap, LineJoin, RenderData, Stroke, ViewMode}; use document_legacy::layers::style::{Fill, Gradient, GradientType, LineCap, LineJoin, RenderData, Stroke, ViewMode};
use graphene_core::raster::color::Color; use graphene_core::raster::color::Color;
@ -15,7 +15,7 @@ use glam::{DAffine2, DVec2};
use std::f64::consts::PI; use std::f64::consts::PI;
use std::sync::Arc; use std::sync::Arc;
pub fn apply_transform_operation(layer: &Layer, transform_op: TransformOp, value: f64, render_data: &RenderData) -> [f64; 6] { pub fn apply_transform_operation(layer: &LegacyLayer, transform_op: TransformOp, value: f64, render_data: &RenderData) -> [f64; 6] {
let transformation = match transform_op { let transformation = match transform_op {
TransformOp::X => DAffine2::update_x, TransformOp::X => DAffine2::update_x,
TransformOp::Y => DAffine2::update_y, TransformOp::Y => DAffine2::update_y,
@ -67,7 +67,7 @@ pub fn apply_transform_operation(layer: &Layer, transform_op: TransformOp, value
pub fn register_artwork_layer_properties( pub fn register_artwork_layer_properties(
document: &Document, document: &Document,
layer_path: Vec<document_legacy::LayerId>, layer_path: Vec<document_legacy::LayerId>,
layer: &Layer, layer: &LegacyLayer,
responses: &mut VecDeque<Message>, responses: &mut VecDeque<Message>,
persistent_data: &PersistentData, persistent_data: &PersistentData,
node_graph_message_handler: &NodeGraphMessageHandler, node_graph_message_handler: &NodeGraphMessageHandler,
@ -76,9 +76,9 @@ pub fn register_artwork_layer_properties(
let options_bar = vec![LayoutGroup::Row { let options_bar = vec![LayoutGroup::Row {
widgets: vec![ widgets: vec![
match &layer.data { match &layer.data {
LayerDataType::Folder(_) => IconLabel::new("Folder").tooltip("Folder").widget_holder(), LegacyLayerType::Folder(_) => IconLabel::new("Folder").tooltip("Folder").widget_holder(),
LayerDataType::Shape(_) => IconLabel::new("NodeShape").tooltip("Shape").widget_holder(), LegacyLayerType::Shape(_) => IconLabel::new("NodeShape").tooltip("Shape").widget_holder(),
LayerDataType::Layer(_) => IconLabel::new("Layer").tooltip("Layer").widget_holder(), LegacyLayerType::Layer(_) => IconLabel::new("Layer").tooltip("Layer").widget_holder(),
}, },
Separator::new(SeparatorType::Unrelated).widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder(),
TextInput::new(layer.name.clone().unwrap_or_else(|| "Untitled Layer".to_string())) TextInput::new(layer.name.clone().unwrap_or_else(|| "Untitled Layer".to_string()))
@ -90,7 +90,7 @@ pub fn register_artwork_layer_properties(
}]; }];
let properties_body = match &layer.data { let properties_body = match &layer.data {
LayerDataType::Shape(shape) => { LegacyLayerType::Shape(shape) => {
if let Some(fill_layout) = node_section_fill(shape.style.fill()) { if let Some(fill_layout) = node_section_fill(shape.style.fill()) {
vec![ vec![
node_section_transform(layer, persistent_data), node_section_transform(layer, persistent_data),
@ -101,7 +101,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::Layer(layer) => { LegacyLayerType::Layer(layer) => {
let mut context = NodePropertiesContext { let mut context = NodePropertiesContext {
persistent_data, persistent_data,
document, document,
@ -115,7 +115,7 @@ pub fn register_artwork_layer_properties(
properties_sections properties_sections
} }
LayerDataType::Folder(_) => { LegacyLayerType::Folder(_) => {
vec![node_section_transform(layer, persistent_data)] vec![node_section_transform(layer, persistent_data)]
} }
}; };
@ -155,7 +155,7 @@ pub fn register_document_graph_properties(mut context: NodePropertiesContext, no
}); });
} }
fn node_section_transform(layer: &Layer, persistent_data: &PersistentData) -> LayoutGroup { fn node_section_transform(layer: &LegacyLayer, persistent_data: &PersistentData) -> LayoutGroup {
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::default(), None); let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::default(), None);
let pivot = layer.transform.transform_vector2(layer.layerspace_pivot(&render_data)); let pivot = layer.transform.transform_vector2(layer.layerspace_pivot(&render_data));
LayoutGroup::Section { LayoutGroup::Section {

View file

@ -1,4 +1,4 @@
use document_legacy::layers::layer_info::{Layer, LayerData, LayerDataTypeDiscriminant}; use document_legacy::layers::layer_info::{LayerData, LayerDataTypeDiscriminant, LegacyLayer};
use document_legacy::layers::style::RenderData; use document_legacy::layers::style::RenderData;
use document_legacy::LayerId; use document_legacy::LayerId;
@ -60,7 +60,7 @@ pub struct LayerPanelEntry {
impl LayerPanelEntry { impl LayerPanelEntry {
// TODO: Deprecate this because it's using document-legacy layer data which is no longer linked to data from the node graph, // TODO: Deprecate this because it's using document-legacy layer data which is no longer linked to data from the node graph,
// TODO: so this doesn't feed `name` (that's fed elsewhere) or `visible` (that's broken entirely), etc. // TODO: so this doesn't feed `name` (that's fed elsewhere) or `visible` (that's broken entirely), etc.
pub fn new(layer_metadata: &LayerMetadata, transform: DAffine2, layer: &Layer, path: Vec<LayerId>, render_data: &RenderData) -> Self { pub fn new(layer_metadata: &LayerMetadata, transform: DAffine2, layer: &LegacyLayer, path: Vec<LayerId>, render_data: &RenderData) -> Self {
let name = layer.name.clone().unwrap_or_else(|| String::from("")); let name = layer.name.clone().unwrap_or_else(|| String::from(""));
let mut tooltip = name.clone(); let mut tooltip = name.clone();

View file

@ -719,8 +719,10 @@ impl PortfolioMessageHandler {
return; return;
}; };
self.executor.poll_node_graph_evaluation(&mut active_document.document_legacy, responses).unwrap_or_else(|e| { self.executor
log::error!("Error while evaluating node graph: {e}"); .poll_node_graph_evaluation(&mut active_document.document_legacy, &mut active_document.collapsed_folders, responses)
}); .unwrap_or_else(|e| {
log::error!("Error while evaluating node graph: {e}");
});
} }
} }

View file

@ -7,7 +7,7 @@ use crate::consts::{
use crate::messages::prelude::*; use crate::messages::prelude::*;
use document_legacy::document_metadata::LayerNodeIdentifier; use document_legacy::document_metadata::LayerNodeIdentifier;
use document_legacy::layers::layer_info::Layer; use document_legacy::layers::layer_info::LegacyLayer;
use document_legacy::layers::style::{self, Stroke}; use document_legacy::layers::style::{self, Stroke};
use document_legacy::{LayerId, Operation}; use document_legacy::{LayerId, Operation};
use graphene_core::vector::{ManipulatorPointId, SelectedType}; use graphene_core::vector::{ManipulatorPointId, SelectedType};
@ -262,7 +262,7 @@ impl SnapManager {
&mut self, &mut self,
document_message_handler: &DocumentMessageHandler, document_message_handler: &DocumentMessageHandler,
input: &InputPreprocessorMessageHandler, input: &InputPreprocessorMessageHandler,
layer: &Layer, layer: &LegacyLayer,
path: &[LayerId], path: &[LayerId],
include_handles: bool, include_handles: bool,
ignore_points: &[ManipulatorPointInfo], ignore_points: &[ManipulatorPointInfo],

View file

@ -6,7 +6,7 @@ use crate::messages::portfolio::document::utility_types::misc::{LayerMetadata, L
use crate::messages::prelude::*; use crate::messages::prelude::*;
use document_legacy::document::Document as DocumentLegacy; use document_legacy::document::Document as DocumentLegacy;
use document_legacy::document_metadata::LayerNodeIdentifier; use document_legacy::document_metadata::LayerNodeIdentifier;
use document_legacy::layers::layer_info::{LayerDataType, LayerDataTypeDiscriminant}; use document_legacy::layers::layer_info::{LayerDataTypeDiscriminant, LegacyLayerType};
use document_legacy::{LayerId, Operation}; use document_legacy::{LayerId, Operation};
use graph_craft::document::value::TaggedValue; use graph_craft::document::value::TaggedValue;
use graph_craft::document::{generate_uuid, DocumentNodeImplementation, NodeId, NodeNetwork}; use graph_craft::document::{generate_uuid, DocumentNodeImplementation, NodeId, NodeNetwork};
@ -499,7 +499,7 @@ 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 layer_layer = match &layer.data { let layer_layer = match &layer.data {
LayerDataType::Layer(layer) => Ok(layer), LegacyLayerType::Layer(layer) => Ok(layer),
_ => Err("Invalid layer type".to_string()), _ => Err("Invalid layer type".to_string()),
}?; }?;
layer_layer.network.clone() layer_layer.network.clone()
@ -595,7 +595,7 @@ impl NodeGraphExecutor {
Ok(()) Ok(())
} }
pub fn poll_node_graph_evaluation(&mut self, document: &mut DocumentLegacy, responses: &mut VecDeque<Message>) -> Result<(), String> { pub fn poll_node_graph_evaluation(&mut self, document: &mut DocumentLegacy, collapsed_folders: &mut Vec<LayerNodeIdentifier>, responses: &mut VecDeque<Message>) -> Result<(), String> {
let results = self.receiver.try_iter().collect::<Vec<_>>(); let results = self.receiver.try_iter().collect::<Vec<_>>();
for response in results { for response in results {
match response { match response {
@ -634,7 +634,7 @@ impl NodeGraphExecutor {
LayerDataTypeDiscriminant::Layer LayerDataTypeDiscriminant::Layer
}, },
layer_metadata: LayerMetadata { layer_metadata: LayerMetadata {
expanded: layer.has_children(&document.metadata) && !document.collapsed_folders.contains(&layer), expanded: layer.has_children(&document.metadata) && !collapsed_folders.contains(&layer),
selected: document.metadata.selected_layers_contains(layer), selected: document.metadata.selected_layers_contains(layer),
}, },
path: vec![node_id], path: vec![node_id],

View file

@ -1,7 +1,7 @@
use fern::colors::{Color, ColoredLevelConfig}; use fern::colors::{Color, ColoredLevelConfig};
use std::{error::Error, sync::Arc}; use std::{error::Error, sync::Arc};
use document_legacy::{document::Document, layers::layer_info::LayerDataType}; use document_legacy::{document::Document, layers::layer_info::LegacyLayerType};
use futures::executor::block_on; use futures::executor::block_on;
use graph_craft::{ use graph_craft::{
concrete, concrete,
@ -88,7 +88,7 @@ fn init_logging() {
fn create_executor(document_string: String) -> Result<DynamicExecutor, Box<dyn Error>> { fn create_executor(document_string: String) -> Result<DynamicExecutor, Box<dyn Error>> {
let document: serde_json::Value = serde_json::from_str(&document_string).expect("Failed to parse document"); let document: serde_json::Value = serde_json::from_str(&document_string).expect("Failed to parse document");
let document = serde_json::from_value::<Document>(document["document_legacy"].clone()).expect("Failed to parse document"); let document = serde_json::from_value::<Document>(document["document_legacy"].clone()).expect("Failed to parse document");
let Some(LayerDataType::Layer(ref node_graph)) = document.root.iter().find(|layer| matches!(layer.data, LayerDataType::Layer(_))).map(|x| &x.data) else { let Some(LegacyLayerType::Layer(ref node_graph)) = document.root.iter().find(|layer| matches!(layer.data, LegacyLayerType::Layer(_))).map(|x| &x.data) else {
panic!("failed to extract node graph from docmuent") panic!("failed to extract node graph from docmuent")
}; };
let network = &node_graph.network; let network = &node_graph.network;