mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-23 15:45:05 +00:00
Clean up some document-legacy code
This commit is contained in:
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
|
@ -1,6 +1,6 @@
|
|||
use crate::consts::F64PRECISE;
|
||||
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 kurbo::{BezPath, CubicBez, Line, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveExtrema, PathEl, PathSeg, Point, QuadBez, Rect};
|
||||
|
@ -395,7 +395,7 @@ impl PathGraph {
|
|||
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 vertices = cycle.vertices();
|
||||
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);
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
select = BooleanOperation::SubtractBack;
|
||||
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: 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() {
|
||||
return Err(BooleanOperationError::InvalidSelection);
|
||||
}
|
||||
|
@ -685,7 +685,7 @@ pub fn bounding_box(curve: &BezPath) -> Rect {
|
|||
.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
|
||||
F: Fn(Direction) -> bool,
|
||||
G: Fn(Direction) -> &'a PathStyle,
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use crate::document_metadata::{is_artboard, DocumentMetadata, LayerNodeIdentifier};
|
||||
use crate::intersection::Quad;
|
||||
use crate::layers::folder_layer::FolderLayer;
|
||||
use crate::layers::layer_info::{Layer, LayerData, LayerDataType, LayerDataTypeDiscriminant};
|
||||
use crate::layers::layer_layer::{CachedOutputData, LayerLayer};
|
||||
use crate::layers::shape_layer::ShapeLayer;
|
||||
use crate::layers::folder_layer::FolderLegacyLayer;
|
||||
use crate::layers::layer_info::{LayerData, LayerDataTypeDiscriminant, LegacyLayer, LegacyLayerType};
|
||||
use crate::layers::layer_layer::{CachedOutputData, LayerLegacyLayer};
|
||||
use crate::layers::shape_layer::ShapeLegacyLayer;
|
||||
use crate::layers::style::RenderData;
|
||||
use crate::{DocumentError, DocumentResponse, Operation};
|
||||
|
||||
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeNetwork, NodeOutput};
|
||||
use graphene_core::renderer::ClickTarget;
|
||||
use graphene_core::transform::Footprint;
|
||||
|
@ -26,16 +27,15 @@ pub type LayerId = u64;
|
|||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct Document {
|
||||
/// The root layer, usually a [FolderLayer](layers::folder_layer::FolderLayer) that contains all other [Layers](layers::layer_info::Layer).
|
||||
pub root: Layer,
|
||||
#[serde(default)]
|
||||
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.
|
||||
/// This identifier is not a hash and is not guaranteed to be equal for equivalent documents.
|
||||
#[serde(skip)]
|
||||
pub state_identifier: DefaultHasher,
|
||||
#[serde(default)]
|
||||
pub document_network: NodeNetwork,
|
||||
#[serde(default)]
|
||||
pub collapsed_folders: Vec<LayerNodeIdentifier>,
|
||||
#[serde(skip)]
|
||||
pub metadata: DocumentMetadata,
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ impl PartialEq for Document {
|
|||
impl Default for Document {
|
||||
fn default() -> 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(),
|
||||
document_network: {
|
||||
use graph_craft::document::{value::TaggedValue, NodeInput};
|
||||
|
@ -105,7 +105,6 @@ impl Default for Document {
|
|||
network
|
||||
},
|
||||
metadata: Default::default(),
|
||||
collapsed_folders: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,11 +118,6 @@ impl Document {
|
|||
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
|
||||
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;
|
||||
|
@ -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
|
||||
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
|
||||
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);
|
||||
|
@ -235,7 +229,7 @@ impl Document {
|
|||
|
||||
/// Returns a reference to the requested folder. Fails if the path does not exist,
|
||||
/// 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;
|
||||
for id in path.as_ref() {
|
||||
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,
|
||||
/// 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.
|
||||
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;
|
||||
for id in path {
|
||||
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.
|
||||
pub fn layer(&self, path: &[LayerId]) -> Result<&Layer, DocumentError> {
|
||||
pub fn layer(&self, path: &[LayerId]) -> Result<&LegacyLayer, DocumentError> {
|
||||
if path.is_empty() {
|
||||
return Ok(&self.root);
|
||||
}
|
||||
|
@ -264,7 +258,7 @@ impl Document {
|
|||
}
|
||||
|
||||
/// 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() {
|
||||
return Ok(&mut self.root);
|
||||
}
|
||||
|
@ -290,7 +284,7 @@ impl Document {
|
|||
let common_prefix_of_path = self.common_layer_path_prefix(layers);
|
||||
|
||||
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],
|
||||
})
|
||||
}
|
||||
|
@ -402,7 +396,7 @@ impl Document {
|
|||
}
|
||||
|
||||
/// 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 layer_id = None;
|
||||
if let Ok((path, id)) = split_path(path) {
|
||||
|
@ -419,9 +413,9 @@ impl Document {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
LayerDataType::Folder(ref mut folder) => {
|
||||
LegacyLayerType::Folder(ref mut folder) => {
|
||||
for sub_layer in folder.layers_mut() {
|
||||
if Document::mark_children_as_dirty(sub_layer) {
|
||||
layer.cache_dirty = true;
|
||||
|
@ -436,7 +430,7 @@ impl Document {
|
|||
/// Adds a new layer to the folder specified by `path`.
|
||||
/// Passing a negative `insert_index` indexes relative to the end.
|
||||
/// -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)?;
|
||||
folder.add_layer(layer, None, insert_index).ok_or(DocumentError::IndexOutOfBounds)
|
||||
}
|
||||
|
@ -592,7 +586,7 @@ impl Document {
|
|||
|
||||
let responses = match operation {
|
||||
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)?;
|
||||
|
||||
|
@ -608,7 +602,7 @@ impl Document {
|
|||
Some(responses)
|
||||
}
|
||||
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)?;
|
||||
|
||||
|
@ -624,7 +618,7 @@ impl Document {
|
|||
Some(responses)
|
||||
}
|
||||
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)?;
|
||||
|
||||
|
@ -646,7 +640,7 @@ impl Document {
|
|||
transform,
|
||||
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)?;
|
||||
|
||||
|
@ -674,8 +668,8 @@ impl Document {
|
|||
style,
|
||||
subpath,
|
||||
} => {
|
||||
let shape = ShapeLayer::new(subpath, style);
|
||||
self.set_layer(&path, Layer::new(LayerDataType::Shape(shape), transform), insert_index)?;
|
||||
let shape = ShapeLegacyLayer::new(subpath, style);
|
||||
self.set_layer(&path, LegacyLayer::new(LegacyLayerType::Shape(shape), transform), insert_index)?;
|
||||
Some(vec![DocumentChanged, CreatedLayer { path, is_selected: true }])
|
||||
}
|
||||
Operation::AddPolyline {
|
||||
|
@ -686,7 +680,7 @@ impl Document {
|
|||
style,
|
||||
} => {
|
||||
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![
|
||||
DocumentChanged,
|
||||
|
@ -700,11 +694,11 @@ impl Document {
|
|||
Some(responses)
|
||||
}
|
||||
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()) {
|
||||
path.push(*id);
|
||||
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);
|
||||
}
|
||||
path.pop();
|
||||
|
@ -753,7 +747,7 @@ impl Document {
|
|||
self.mark_as_dirty(&destination_path)?;
|
||||
|
||||
// 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()) {
|
||||
path.push(*id);
|
||||
|
||||
|
@ -761,7 +755,7 @@ impl Document {
|
|||
path: path.clone(),
|
||||
is_selected: !duplicating,
|
||||
});
|
||||
if let LayerDataType::Folder(f) = &layer.data {
|
||||
if let LegacyLayerType::Folder(f) = &layer.data {
|
||||
aggregate_insertions(f, path, responses, duplicating);
|
||||
}
|
||||
|
||||
|
@ -811,7 +805,7 @@ impl Document {
|
|||
let mut indices: Vec<usize> = (0..duplicated_layers.len()).collect();
|
||||
indices.sort_by_key(|&i| duplicated_layers[i].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)?;
|
||||
|
||||
|
@ -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
|
||||
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.layers = vec![];
|
||||
updated_layer_as_folder.generate_new_folder_ids()
|
||||
|
@ -898,7 +892,11 @@ impl Document {
|
|||
Some(vec![LayerChanged { path }])
|
||||
}
|
||||
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)?;
|
||||
|
||||
let mut responses = vec![
|
||||
|
@ -928,7 +926,7 @@ impl Document {
|
|||
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 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");
|
||||
};
|
||||
|
||||
|
@ -940,7 +938,7 @@ impl Document {
|
|||
Operation::ClearBlobURL { path } => {
|
||||
let layer = self.layer_mut(&path).expect("Clearing node graph image for invalid layer");
|
||||
match &mut layer.data {
|
||||
LayerDataType::Layer(layer) => {
|
||||
LegacyLayerType::Layer(layer) => {
|
||||
if matches!(layer.cached_output_data, CachedOutputData::BlobURL(_)) {
|
||||
layer.cached_output_data = CachedOutputData::None;
|
||||
}
|
||||
|
@ -965,25 +963,25 @@ impl Document {
|
|||
Operation::SetShapePath { path, subpath } => {
|
||||
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;
|
||||
}
|
||||
Some(vec![DocumentChanged, LayerChanged { path }])
|
||||
}
|
||||
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));
|
||||
}
|
||||
Some(Vec::new())
|
||||
}
|
||||
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);
|
||||
}
|
||||
Some(Vec::new())
|
||||
}
|
||||
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);
|
||||
}
|
||||
Some(Vec::new())
|
||||
|
@ -1046,7 +1044,7 @@ impl Document {
|
|||
Operation::SetLayerStyle { path, style } => {
|
||||
let layer = self.layer_mut(&path)?;
|
||||
match &mut layer.data {
|
||||
LayerDataType::Shape(s) => s.style = style,
|
||||
LegacyLayerType::Shape(s) => s.style = style,
|
||||
_ => return Err(DocumentError::NotShape),
|
||||
}
|
||||
self.mark_as_dirty(&path)?;
|
||||
|
@ -1083,7 +1081,7 @@ fn update_thumbnails_upstream(path: &[LayerId]) -> Vec<DocumentResponse> {
|
|||
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_size = (layer_bounds.transform_vector2((1., 0.).into()).length(), layer_bounds.transform_vector2((0., 1.).into()).length());
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::layer_info::{Layer, LayerData, LayerDataType};
|
||||
use super::layer_info::{LayerData, LegacyLayer, LegacyLayerType};
|
||||
use super::style::RenderData;
|
||||
use crate::intersection::Quad;
|
||||
use crate::{DocumentError, LayerId};
|
||||
|
@ -9,19 +9,18 @@ use glam::DVec2;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A layer that encapsulates other layers, including potentially more folders.
|
||||
/// The contained layers are rendered in the same order they are
|
||||
/// stored in the [layers](FolderLayer::layers) field.
|
||||
/// The contained layers are rendered in the same order they are stored.
|
||||
#[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
|
||||
next_assignment_id: LayerId,
|
||||
/// The IDs of the [Layer]s contained within the Folder
|
||||
pub layer_ids: Vec<LayerId>,
|
||||
/// 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 {
|
||||
let mut any_child_requires_redraw = false;
|
||||
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.
|
||||
/// 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.
|
||||
|
@ -56,20 +55,20 @@ impl FolderLayer {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer;
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer;
|
||||
/// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
|
||||
/// # use graphite_document_legacy::layers::style::PathStyle;
|
||||
/// # use graphite_document_legacy::layers::layer_info::LayerDataType;
|
||||
/// let mut folder = FolderLayer::default();
|
||||
/// # use graphite_document_legacy::layers::layer_info::LegacyLayerType;
|
||||
/// let mut folder = FolderLegacyLayer::default();
|
||||
///
|
||||
/// // Create two layers to be added to the folder
|
||||
/// let mut shape_layer = ShapeLayer::rectangle(PathStyle::default());
|
||||
/// let mut folder_layer = FolderLayer::default();
|
||||
/// let mut shape_layer = ShapeLegacyLayer::rectangle(PathStyle::default());
|
||||
/// let mut folder_layer = FolderLegacyLayer::default();
|
||||
///
|
||||
/// folder.add_layer(shape_layer.into(), None, -1);
|
||||
/// 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;
|
||||
|
||||
// Bounds check for the insert index
|
||||
|
@ -104,14 +103,14 @@ impl FolderLayer {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer;
|
||||
/// let mut folder = FolderLayer::default();
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
|
||||
/// let mut folder = FolderLegacyLayer::default();
|
||||
///
|
||||
/// // Try to remove a layer that does not exist
|
||||
/// assert!(folder.remove_layer(123).is_err());
|
||||
///
|
||||
/// // 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
|
||||
/// assert!(folder.remove_layer(123).is_ok());
|
||||
|
@ -130,21 +129,21 @@ impl FolderLayer {
|
|||
}
|
||||
|
||||
/// Get references to all the [Layer]s in the folder.
|
||||
pub fn layers(&self) -> &[Layer] {
|
||||
pub fn layers(&self) -> &[LegacyLayer] {
|
||||
self.layers.as_slice()
|
||||
}
|
||||
|
||||
/// 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()
|
||||
}
|
||||
|
||||
pub fn layer(&self, id: LayerId) -> Option<&Layer> {
|
||||
pub fn layer(&self, id: LayerId) -> Option<&LegacyLayer> {
|
||||
let pos = self.position_of_layer(id).ok()?;
|
||||
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()?;
|
||||
Some(&mut self.layers[pos])
|
||||
}
|
||||
|
@ -157,14 +156,14 @@ impl FolderLayer {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer;
|
||||
/// let mut folder = FolderLayer::default();
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
|
||||
/// let mut folder = FolderLegacyLayer::default();
|
||||
///
|
||||
/// // Search for an id that does not exist
|
||||
/// assert!(!folder.folder_contains(123));
|
||||
///
|
||||
/// // 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"
|
||||
/// assert!(folder.folder_contains(123));
|
||||
|
@ -178,15 +177,15 @@ impl FolderLayer {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer;
|
||||
/// let mut folder = FolderLayer::default();
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
|
||||
/// let mut folder = FolderLegacyLayer::default();
|
||||
///
|
||||
/// // Search for an id that does not exist
|
||||
/// assert!(folder.position_of_layer(123).is_err());
|
||||
///
|
||||
/// // Add layer with the id "123" to the folder
|
||||
/// folder.add_layer(FolderLayer::default().into(), Some(123), -1);
|
||||
/// folder.add_layer(FolderLayer::default().into(), Some(42), -1);
|
||||
/// folder.add_layer(FolderLegacyLayer::default().into(), Some(123), -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(42), Ok(1));
|
||||
|
@ -201,26 +200,27 @@ impl FolderLayer {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer;
|
||||
/// # use graphite_document_legacy::layers::shape_layer::ShapeLayer;
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
|
||||
/// # use graphite_document_legacy::layers::shape_layer::ShapeLegacyLayer;
|
||||
/// # 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
|
||||
/// assert!(folder.folder(132).is_none());
|
||||
///
|
||||
/// // 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());
|
||||
///
|
||||
/// // 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());
|
||||
/// ```
|
||||
pub fn folder(&self, id: LayerId) -> Option<&FolderLayer> {
|
||||
pub fn folder(&self, id: LayerId) -> Option<&FolderLegacyLayer> {
|
||||
match self.layer(id) {
|
||||
Some(Layer {
|
||||
data: LayerDataType::Folder(folder), ..
|
||||
Some(LegacyLayer {
|
||||
data: LegacyLayerType::Folder(folder),
|
||||
..
|
||||
}) => Some(folder),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -229,11 +229,12 @@ impl FolderLayer {
|
|||
/// Tries to get a mutable reference to folder with the given `id`.
|
||||
/// 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.
|
||||
/// See the [FolderLayer::folder] method for a usage example.
|
||||
pub fn folder_mut(&mut self, id: LayerId) -> Option<&mut FolderLayer> {
|
||||
/// See the [FolderLegacyLayer::folder] method for a usage example.
|
||||
pub fn folder_mut(&mut self, id: LayerId) -> Option<&mut FolderLegacyLayer> {
|
||||
match self.layer_mut(id) {
|
||||
Some(Layer {
|
||||
data: LayerDataType::Folder(folder), ..
|
||||
Some(LegacyLayer {
|
||||
data: LegacyLayerType::Folder(folder),
|
||||
..
|
||||
}) => Some(folder),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::folder_layer::FolderLayer;
|
||||
use super::layer_layer::LayerLayer;
|
||||
use super::shape_layer::ShapeLayer;
|
||||
use super::folder_layer::FolderLegacyLayer;
|
||||
use super::layer_layer::LayerLegacyLayer;
|
||||
use super::shape_layer::ShapeLegacyLayer;
|
||||
use super::style::{PathStyle, RenderData};
|
||||
use crate::intersection::Quad;
|
||||
use crate::DocumentError;
|
||||
|
@ -17,29 +17,35 @@ use std::fmt::Write;
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
/// Represents different types of layers.
|
||||
pub enum LayerDataType {
|
||||
/// A layer that wraps a [FolderLayer] struct.
|
||||
Folder(FolderLayer),
|
||||
/// A layer that wraps a [ShapeLayer] struct. Still used by the overlays system, but will be removed in the future.
|
||||
Shape(ShapeLayer),
|
||||
/// A layer that wraps an [LayerLayer] struct.
|
||||
Layer(LayerLayer),
|
||||
pub enum LegacyLayerType {
|
||||
/// A layer that wraps a [FolderLegacyLayer] struct.
|
||||
Folder(FolderLegacyLayer),
|
||||
/// A layer that wraps a [ShapeLegacyLayer] struct. Still used by the overlays system, but will be removed in the future.
|
||||
Shape(ShapeLegacyLayer),
|
||||
/// A layer that wraps an [LayerLegacyLayer] struct.
|
||||
Layer(LayerLegacyLayer),
|
||||
}
|
||||
|
||||
impl LayerDataType {
|
||||
impl Default for LegacyLayerType {
|
||||
fn default() -> Self {
|
||||
LegacyLayerType::Folder(FolderLegacyLayer::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl LegacyLayerType {
|
||||
pub fn inner(&self) -> &dyn LayerData {
|
||||
match self {
|
||||
LayerDataType::Shape(shape) => shape,
|
||||
LayerDataType::Folder(folder) => folder,
|
||||
LayerDataType::Layer(layer) => layer,
|
||||
LegacyLayerType::Shape(shape) => shape,
|
||||
LegacyLayerType::Folder(folder) => folder,
|
||||
LegacyLayerType::Layer(layer) => layer,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner_mut(&mut self) -> &mut dyn LayerData {
|
||||
match self {
|
||||
LayerDataType::Shape(shape) => shape,
|
||||
LayerDataType::Folder(folder) => folder,
|
||||
LayerDataType::Layer(layer) => layer,
|
||||
LegacyLayerType::Shape(shape) => shape,
|
||||
LegacyLayerType::Folder(folder) => folder,
|
||||
LegacyLayerType::Layer(layer) => layer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,9 +69,9 @@ impl fmt::Display for LayerDataTypeDiscriminant {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&LayerDataType> for LayerDataTypeDiscriminant {
|
||||
fn from(data: &LayerDataType) -> Self {
|
||||
use LayerDataType::*;
|
||||
impl From<&LegacyLayerType> for LayerDataTypeDiscriminant {
|
||||
fn from(data: &LegacyLayerType) -> Self {
|
||||
use LegacyLayerType::*;
|
||||
|
||||
match data {
|
||||
Folder(_) => LayerDataTypeDiscriminant::Folder,
|
||||
|
@ -77,23 +83,23 @@ impl From<&LayerDataType> for LayerDataTypeDiscriminant {
|
|||
|
||||
// ** 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;
|
||||
/// 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 {
|
||||
LayerDataType::Shape(layer) => Ok(&mut layer.shape),
|
||||
LegacyLayerType::Shape(layer) => Ok(&mut layer.shape),
|
||||
_ => 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;
|
||||
/// 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 {
|
||||
LayerDataType::Shape(layer) => Ok(&layer.shape),
|
||||
LegacyLayerType::Shape(layer) => Ok(&layer.shape),
|
||||
_ => Err("Did not find any shape data in the layer"),
|
||||
}
|
||||
}
|
||||
|
@ -105,12 +111,12 @@ pub trait LayerData {
|
|||
///
|
||||
/// # 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::layer_info::LayerData;
|
||||
/// # 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();
|
||||
///
|
||||
/// // 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.
|
||||
/// # 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::layer_info::LayerData;
|
||||
/// # use graphite_document_legacy::intersection::Quad;
|
||||
/// # use glam::f64::{DAffine2, DVec2};
|
||||
/// # 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 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.
|
||||
/// # Example
|
||||
/// ```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::layer_info::LayerData;
|
||||
/// # use glam::f64::{DAffine2, DVec2};
|
||||
/// # 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.
|
||||
/// // (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]>;
|
||||
}
|
||||
|
||||
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 {
|
||||
self.inner_mut().render(svg, svg_defs, transforms, render_data)
|
||||
}
|
||||
|
@ -203,13 +209,13 @@ fn return_true() -> bool {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize, Serialize)]
|
||||
pub struct Layer {
|
||||
pub struct LegacyLayer {
|
||||
/// Whether the layer is currently visible or hidden.
|
||||
pub visible: bool,
|
||||
/// The user-given name of the layer.
|
||||
pub name: Option<String>,
|
||||
/// 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).
|
||||
#[serde(with = "DAffine2Ref")]
|
||||
pub transform: glam::DAffine2,
|
||||
|
@ -237,8 +243,27 @@ pub struct Layer {
|
|||
pub opacity: f64,
|
||||
}
|
||||
|
||||
impl Layer {
|
||||
pub fn new(data: LayerDataType, transform: [f64; 6]) -> Self {
|
||||
impl Default for LegacyLayer {
|
||||
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 {
|
||||
visible: true,
|
||||
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].
|
||||
pub fn child(&self, path: &[LayerId]) -> Option<&Layer> {
|
||||
pub fn child(&self, path: &[LayerId]) -> Option<&LegacyLayer> {
|
||||
let mut layer = self;
|
||||
for id in path {
|
||||
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].
|
||||
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;
|
||||
for id in path {
|
||||
layer = layer.as_folder_mut().ok()?.layer_mut(*id)?;
|
||||
|
@ -275,23 +300,23 @@ impl 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) 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
|
||||
/// ```
|
||||
/// # 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::style::PathStyle;
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLayer;
|
||||
/// let mut root_folder = FolderLayer::default();
|
||||
/// # use graphite_document_legacy::layers::folder_layer::FolderLegacyLayer;
|
||||
/// let mut root_folder = FolderLegacyLayer::default();
|
||||
///
|
||||
/// // 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);
|
||||
///
|
||||
/// // Add a folder containing another shape to the root layer
|
||||
/// let mut child_folder = FolderLayer::default();
|
||||
/// let grandchild: Layer = ShapeLayer::rectangle(PathStyle::default()).into();
|
||||
/// let mut child_folder = FolderLegacyLayer::default();
|
||||
/// let grandchild: Layer = ShapeLegacyLayer::rectangle(PathStyle::default()).into();
|
||||
/// child_folder.add_layer(grandchild.clone(), None, -1);
|
||||
/// let child_2: Layer = child_folder.into();
|
||||
/// root_folder.add_layer(child_2.clone(), None, -1);
|
||||
|
@ -371,14 +396,14 @@ impl Layer {
|
|||
///
|
||||
/// # 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::style::{PathStyle, RenderData};
|
||||
/// # use glam::DVec2;
|
||||
/// # use glam::f64::DAffine2;
|
||||
/// # use std::collections::HashMap;
|
||||
/// // 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
|
||||
/// let transform = DAffine2::IDENTITY;
|
||||
|
@ -430,79 +455,79 @@ impl 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`.
|
||||
pub fn as_folder_mut(&mut self) -> Result<&mut FolderLayer, DocumentError> {
|
||||
/// This operation will fail if the [Layer type](Layer::data) is not `LegacyLayerType::Folder`.
|
||||
pub fn as_folder_mut(&mut self) -> Result<&mut FolderLegacyLayer, DocumentError> {
|
||||
match &mut self.data {
|
||||
LayerDataType::Folder(f) => Ok(f),
|
||||
LegacyLayerType::Folder(f) => Ok(f),
|
||||
_ => Err(DocumentError::NotFolder),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_vector_data(&self) -> Option<&VectorData> {
|
||||
match &self.data {
|
||||
LayerDataType::Layer(layer) => layer.as_vector_data(),
|
||||
LegacyLayerType::Layer(layer) => layer.as_vector_data(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_subpath_mut(&mut self) -> Option<&mut Subpath> {
|
||||
match &mut self.data {
|
||||
LayerDataType::Shape(s) => Some(&mut s.shape),
|
||||
LegacyLayerType::Shape(s) => Some(&mut s.shape),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the Folder wrapped by the layer.
|
||||
/// This operation will fail if the [Layer type](Layer::data) is not `LayerDataType::Folder`.
|
||||
pub fn as_folder(&self) -> Result<&FolderLayer, DocumentError> {
|
||||
/// This operation will fail if the [Layer type](Layer::data) is not `LegacyLayerType::Folder`.
|
||||
pub fn as_folder(&self) -> Result<&FolderLegacyLayer, DocumentError> {
|
||||
match &self.data {
|
||||
LayerDataType::Folder(f) => Ok(f),
|
||||
LegacyLayerType::Folder(f) => Ok(f),
|
||||
_ => Err(DocumentError::NotFolder),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
match &mut self.data {
|
||||
LayerDataType::Layer(layer) => Ok(&mut layer.network),
|
||||
LegacyLayerType::Layer(layer) => Ok(&mut layer.network),
|
||||
_ => Err(DocumentError::NotLayer),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
match &self.data {
|
||||
LayerDataType::Layer(layer) => Ok(&layer.network),
|
||||
LegacyLayerType::Layer(layer) => Ok(&layer.network),
|
||||
_ => Err(DocumentError::NotLayer),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_layer(&self) -> Result<&LayerLayer, DocumentError> {
|
||||
pub fn as_layer(&self) -> Result<&LayerLegacyLayer, DocumentError> {
|
||||
match &self.data {
|
||||
LayerDataType::Layer(layer) => Ok(layer),
|
||||
LegacyLayerType::Layer(layer) => Ok(layer),
|
||||
_ => Err(DocumentError::NotLayer),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn style(&self) -> Result<&PathStyle, DocumentError> {
|
||||
match &self.data {
|
||||
LayerDataType::Shape(shape) => Ok(&shape.style),
|
||||
LayerDataType::Layer(layer) => layer.as_vector_data().map(|vector| &vector.style).ok_or(DocumentError::NotShape),
|
||||
LegacyLayerType::Shape(shape) => Ok(&shape.style),
|
||||
LegacyLayerType::Layer(layer) => layer.as_vector_data().map(|vector| &vector.style).ok_or(DocumentError::NotShape),
|
||||
_ => Err(DocumentError::NotShape),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn style_mut(&mut self) -> Result<&mut PathStyle, DocumentError> {
|
||||
match &mut self.data {
|
||||
LayerDataType::Shape(s) => Ok(&mut s.style),
|
||||
LegacyLayerType::Shape(s) => Ok(&mut s.style),
|
||||
_ => Err(DocumentError::NotShape),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Layer {
|
||||
impl Clone for LegacyLayer {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
visible: self.visible,
|
||||
|
@ -521,20 +546,20 @@ impl Clone for Layer {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<FolderLayer> for Layer {
|
||||
fn from(from: FolderLayer) -> Layer {
|
||||
Layer::new(LayerDataType::Folder(from), DAffine2::IDENTITY.to_cols_array())
|
||||
impl From<FolderLegacyLayer> for LegacyLayer {
|
||||
fn from(from: FolderLegacyLayer) -> LegacyLayer {
|
||||
LegacyLayer::new(LegacyLayerType::Folder(from), DAffine2::IDENTITY.to_cols_array())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ShapeLayer> for Layer {
|
||||
fn from(from: ShapeLayer) -> Layer {
|
||||
Layer::new(LayerDataType::Shape(from), DAffine2::IDENTITY.to_cols_array())
|
||||
impl From<ShapeLegacyLayer> for LegacyLayer {
|
||||
fn from(from: ShapeLegacyLayer) -> LegacyLayer {
|
||||
LegacyLayer::new(LegacyLayerType::Shape(from), DAffine2::IDENTITY.to_cols_array())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a Layer {
|
||||
type Item = &'a Layer;
|
||||
impl<'a> IntoIterator for &'a LegacyLayer {
|
||||
type Item = &'a LegacyLayer;
|
||||
type IntoIter = LayerIter<'a>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
|
@ -546,16 +571,16 @@ impl<'a> IntoIterator for &'a Layer {
|
|||
/// See [Layer::iter] for more information.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct LayerIter<'a> {
|
||||
pub stack: Vec<&'a Layer>,
|
||||
pub stack: Vec<&'a LegacyLayer>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for LayerIter<'a> {
|
||||
type Item = &'a Layer;
|
||||
type Item = &'a LegacyLayer;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.stack.pop() {
|
||||
Some(layer) => {
|
||||
if let LayerDataType::Folder(folder) = &layer.data {
|
||||
if let LegacyLayerType::Folder(folder) = &layer.data {
|
||||
let layers = folder.layers();
|
||||
self.stack.extend(layers);
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ pub enum CachedOutputData {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
|
||||
pub struct LayerLayer {
|
||||
pub struct LayerLegacyLayer {
|
||||
/// The document node network that this layer contains
|
||||
pub network: graph_craft::document::NodeNetwork,
|
||||
|
||||
|
@ -29,7 +29,7 @@ pub struct LayerLayer {
|
|||
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 {
|
||||
let transform = self.transform(transforms, render_data.view_mode);
|
||||
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 {
|
||||
let start = match mode {
|
||||
ViewMode::Outline => 0,
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
//! 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.
|
||||
//! There are currently these different types of layers:
|
||||
//! * [Folder layers](folder_layer::FolderLayer), which encapsulate sub-layers
|
||||
//! * [Shape layers](shape_layer::ShapeLayer), which contain generic SVG [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)s (deprecated but still used by the overlays system).
|
||||
//! * [Layer layers](layer_layer::LayerLayer), which contain a node graph layer
|
||||
//! * [Folder layers](folder_layer::FolderLegacyLayer), which encapsulate sub-layers
|
||||
//! * [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::LayerLegacyLayer), which contain a node graph 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.
|
||||
|
||||
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;
|
||||
/// Contains the base [Layer](layer_info::Layer) type, an abstraction over the different types of layers.
|
||||
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;
|
||||
// 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;
|
||||
|
||||
mod render_data;
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::fmt::Write;
|
|||
/// [`<g>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g)
|
||||
/// group that the transformation matrix is applied to.
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, specta::Type)]
|
||||
pub struct ShapeLayer {
|
||||
pub struct ShapeLegacyLayer {
|
||||
/// The geometry of the layer.
|
||||
pub shape: Subpath,
|
||||
/// The visual style of the shape.
|
||||
|
@ -25,7 +25,7 @@ pub struct ShapeLayer {
|
|||
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 {
|
||||
let mut subpath = self.shape.clone();
|
||||
|
||||
|
@ -76,8 +76,8 @@ impl LayerData for ShapeLayer {
|
|||
}
|
||||
}
|
||||
|
||||
impl ShapeLayer {
|
||||
/// Construct a new [ShapeLayer] with the specified [Subpath] and [PathStyle]
|
||||
impl ShapeLegacyLayer {
|
||||
/// Construct a new [ShapeLegacyLayer] with the specified [Subpath] and [PathStyle]
|
||||
pub fn new(shape: Subpath, style: PathStyle) -> Self {
|
||||
Self { shape, style, render_index: 1 }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::layers::layer_info::Layer;
|
||||
use crate::layers::layer_info::LegacyLayer;
|
||||
use crate::layers::style::{self, Stroke};
|
||||
use crate::LayerId;
|
||||
|
||||
|
@ -48,7 +48,7 @@ pub enum Operation {
|
|||
new_name: String,
|
||||
},
|
||||
InsertLayer {
|
||||
layer: Box<Layer>,
|
||||
layer: Box<LegacyLayer>,
|
||||
destination_path: Vec<LayerId>,
|
||||
insert_index: isize,
|
||||
duplicating: bool,
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::node_graph_executor::NodeGraphExecutor;
|
|||
|
||||
use document_legacy::document::Document as DocumentLegacy;
|
||||
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::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
|
@ -44,7 +44,8 @@ pub struct DocumentMessageHandler {
|
|||
pub version: String,
|
||||
#[serde(default)]
|
||||
pub commit_hash: String,
|
||||
|
||||
#[serde(default)]
|
||||
pub collapsed_folders: Vec<LayerNodeIdentifier>,
|
||||
pub document_mode: DocumentMode,
|
||||
pub view_mode: ViewMode,
|
||||
#[serde(skip)]
|
||||
|
@ -52,7 +53,6 @@ pub struct DocumentMessageHandler {
|
|||
pub overlays_visible: bool,
|
||||
#[serde(default = "return_true")]
|
||||
pub rulers_visible: bool,
|
||||
|
||||
#[serde(skip)]
|
||||
pub document_undo_history: VecDeque<DocumentSave>,
|
||||
#[serde(skip)]
|
||||
|
@ -60,12 +60,10 @@ pub struct DocumentMessageHandler {
|
|||
/// Don't allow aborting transactions whilst undoing to avoid #559
|
||||
#[serde(skip)]
|
||||
undo_in_progress: bool,
|
||||
|
||||
#[serde(with = "vectorize_layer_metadata")]
|
||||
pub layer_metadata: HashMap<Vec<LayerId>, LayerMetadata>,
|
||||
#[serde(skip)]
|
||||
layer_range_selection_reference: Option<LayerNodeIdentifier>,
|
||||
|
||||
navigation_handler: NavigationMessageHandler,
|
||||
#[serde(skip)]
|
||||
overlays_message_handler: OverlaysMessageHandler,
|
||||
|
@ -84,20 +82,17 @@ impl Default for DocumentMessageHandler {
|
|||
name: DEFAULT_DOCUMENT_NAME.to_string(),
|
||||
version: GRAPHITE_DOCUMENT_VERSION.to_string(),
|
||||
commit_hash: crate::application::GRAPHITE_GIT_COMMIT_HASH.to_string(),
|
||||
|
||||
collapsed_folders: Vec::new(),
|
||||
document_mode: DocumentMode::DesignMode,
|
||||
view_mode: ViewMode::default(),
|
||||
snapping_state: SnappingState::default(),
|
||||
overlays_visible: true,
|
||||
rulers_visible: true,
|
||||
|
||||
document_undo_history: VecDeque::new(),
|
||||
document_redo_history: VecDeque::new(),
|
||||
undo_in_progress: false,
|
||||
|
||||
layer_metadata: vec![(vec![], LayerMetadata::new(true))].into_iter().collect(),
|
||||
layer_range_selection_reference: None,
|
||||
|
||||
navigation_handler: NavigationMessageHandler::default(),
|
||||
overlays_message_handler: OverlaysMessageHandler::default(),
|
||||
properties_panel_message_handler: PropertiesPanelMessageHandler::default(),
|
||||
|
@ -199,13 +194,14 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
|||
document: &mut self.document_legacy,
|
||||
document_id,
|
||||
document_name: self.name.as_str(),
|
||||
collapsed_folders: &mut self.collapsed_folders,
|
||||
input: ipp,
|
||||
graph_view_overlay_open,
|
||||
},
|
||||
);
|
||||
}
|
||||
#[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
|
||||
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 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)),
|
||||
};
|
||||
|
||||
|
@ -715,7 +711,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
|||
|
||||
// Revoke the old blob URL
|
||||
match &layer.data {
|
||||
LayerDataType::Layer(layer) => {
|
||||
LegacyLayerType::Layer(layer) => {
|
||||
if let Some(url) = layer.as_blob_url() {
|
||||
responses.add(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() });
|
||||
}
|
||||
|
@ -785,10 +781,10 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
|||
StartTransaction => self.backup(responses),
|
||||
ToggleLayerExpansion { layer } => {
|
||||
let layer = LayerNodeIdentifier::new(layer, self.network());
|
||||
if self.document_legacy.collapsed_folders.contains(&layer) {
|
||||
self.document_legacy.collapsed_folders.retain(|&collapsed_layer| collapsed_layer != layer);
|
||||
if self.collapsed_folders.contains(&layer) {
|
||||
self.collapsed_folders.retain(|&collapsed_layer| collapsed_layer != layer);
|
||||
} else {
|
||||
self.document_legacy.collapsed_folders.push(layer);
|
||||
self.collapsed_folders.push(layer);
|
||||
}
|
||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||
}
|
||||
|
@ -900,6 +896,7 @@ impl DocumentMessageHandler {
|
|||
pub fn network(&self) -> &NodeNetwork {
|
||||
&self.document_legacy.document_network
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> &document_legacy::document_metadata::DocumentMetadata {
|
||||
&self.document_legacy.metadata
|
||||
}
|
||||
|
@ -1013,7 +1010,7 @@ impl DocumentMessageHandler {
|
|||
for layer_node in folder.children(self.metadata()) {
|
||||
data.push(layer_node.to_node());
|
||||
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());
|
||||
|
||||
// TODO: Skip if folder is not expanded.
|
||||
|
|
|
@ -571,8 +571,13 @@ impl<'a> ModifyInputsContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessageHandler)> for GraphOperationMessageHandler {
|
||||
fn process_message(&mut self, message: GraphOperationMessage, responses: &mut VecDeque<Message>, (document, node_graph): (&mut Document, &mut NodeGraphMessageHandler)) {
|
||||
impl MessageHandler<GraphOperationMessage, (&mut Document, &mut Vec<LayerNodeIdentifier>, &mut NodeGraphMessageHandler)> for GraphOperationMessageHandler {
|
||||
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 {
|
||||
GraphOperationMessage::FillSet { layer, fill } => {
|
||||
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) {
|
||||
modify_inputs.insert_artboard(artboard, layer);
|
||||
}
|
||||
document.load_network_structure();
|
||||
load_network_structure(document, collapsed_folders);
|
||||
}
|
||||
GraphOperationMessage::NewBitmapLayer {
|
||||
id,
|
||||
|
@ -705,14 +710,14 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
|
|||
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 } => {
|
||||
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) {
|
||||
modify_inputs.insert_vector_data(subpaths, layer);
|
||||
}
|
||||
document.load_network_structure();
|
||||
load_network_structure(document, collapsed_folders);
|
||||
}
|
||||
GraphOperationMessage::NewTextLayer {
|
||||
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) {
|
||||
modify_inputs.insert_text(text, font, size, layer);
|
||||
}
|
||||
document.load_network_structure();
|
||||
load_network_structure(document, collapsed_folders);
|
||||
}
|
||||
GraphOperationMessage::ResizeArtboard { id, location, dimensions } => {
|
||||
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 } => {
|
||||
let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses);
|
||||
modify_inputs.delete_layer(id);
|
||||
document.load_network_structure();
|
||||
load_network_structure(document, collapsed_folders);
|
||||
}
|
||||
GraphOperationMessage::ClearArtboards => {
|
||||
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);
|
||||
}
|
||||
}
|
||||
document.load_network_structure();
|
||||
load_network_structure(document, collapsed_folders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -755,3 +760,8 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
pub use self::document_node_types::*;
|
||||
use super::load_network_structure;
|
||||
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
use crate::messages::prelude::*;
|
||||
use crate::node_graph_executor::GraphIdentifier;
|
||||
|
||||
use document_legacy::document::Document;
|
||||
use document_legacy::document_metadata::LayerNodeIdentifier;
|
||||
use document_legacy::LayerId;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::{DocumentNode, NodeId, NodeInput, NodeNetwork, NodeOutput};
|
||||
|
@ -453,15 +455,20 @@ pub struct NodeGraphHandlerData<'a> {
|
|||
pub document: &'a mut Document,
|
||||
pub document_id: u64,
|
||||
pub document_name: &'a str,
|
||||
pub collapsed_folders: &'a mut Vec<LayerNodeIdentifier>,
|
||||
pub input: &'a InputPreprocessorMessageHandler,
|
||||
pub graph_view_overlay_open: bool,
|
||||
}
|
||||
|
||||
impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGraphMessageHandler {
|
||||
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, data: NodeGraphHandlerData<'a>) {
|
||||
let document = data.document;
|
||||
let document_id = data.document_id;
|
||||
let graph_view_overlay_open = data.graph_view_overlay_open;
|
||||
let NodeGraphHandlerData {
|
||||
document,
|
||||
document_id,
|
||||
collapsed_folders,
|
||||
graph_view_overlay_open,
|
||||
..
|
||||
} = data;
|
||||
match message {
|
||||
// TODO: automatically remove broadcast messages.
|
||||
NodeGraphMessage::Init => {
|
||||
|
@ -469,7 +476,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||
on: BroadcastEvent::SelectionChanged,
|
||||
send: Box::new(NodeGraphMessage::SelectedNodesUpdated.into()),
|
||||
});
|
||||
document.load_network_structure();
|
||||
load_network_structure(document, collapsed_folders);
|
||||
responses.add(DocumentMessage::DocumentStructureChanged);
|
||||
}
|
||||
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();
|
||||
*node_input = input;
|
||||
if structure_changed {
|
||||
document.load_network_structure();
|
||||
load_network_structure(document, collapsed_folders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::messages::prelude::*;
|
|||
use crate::node_graph_executor::NodeGraphExecutor;
|
||||
|
||||
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 graphene_core::raster::color::Color;
|
||||
|
||||
|
@ -15,7 +15,7 @@ use glam::{DAffine2, DVec2};
|
|||
use std::f64::consts::PI;
|
||||
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 {
|
||||
TransformOp::X => DAffine2::update_x,
|
||||
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(
|
||||
document: &Document,
|
||||
layer_path: Vec<document_legacy::LayerId>,
|
||||
layer: &Layer,
|
||||
layer: &LegacyLayer,
|
||||
responses: &mut VecDeque<Message>,
|
||||
persistent_data: &PersistentData,
|
||||
node_graph_message_handler: &NodeGraphMessageHandler,
|
||||
|
@ -76,9 +76,9 @@ pub fn register_artwork_layer_properties(
|
|||
let options_bar = vec![LayoutGroup::Row {
|
||||
widgets: vec![
|
||||
match &layer.data {
|
||||
LayerDataType::Folder(_) => IconLabel::new("Folder").tooltip("Folder").widget_holder(),
|
||||
LayerDataType::Shape(_) => IconLabel::new("NodeShape").tooltip("Shape").widget_holder(),
|
||||
LayerDataType::Layer(_) => IconLabel::new("Layer").tooltip("Layer").widget_holder(),
|
||||
LegacyLayerType::Folder(_) => IconLabel::new("Folder").tooltip("Folder").widget_holder(),
|
||||
LegacyLayerType::Shape(_) => IconLabel::new("NodeShape").tooltip("Shape").widget_holder(),
|
||||
LegacyLayerType::Layer(_) => IconLabel::new("Layer").tooltip("Layer").widget_holder(),
|
||||
},
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
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 {
|
||||
LayerDataType::Shape(shape) => {
|
||||
LegacyLayerType::Shape(shape) => {
|
||||
if let Some(fill_layout) = node_section_fill(shape.style.fill()) {
|
||||
vec![
|
||||
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())]
|
||||
}
|
||||
}
|
||||
LayerDataType::Layer(layer) => {
|
||||
LegacyLayerType::Layer(layer) => {
|
||||
let mut context = NodePropertiesContext {
|
||||
persistent_data,
|
||||
document,
|
||||
|
@ -115,7 +115,7 @@ pub fn register_artwork_layer_properties(
|
|||
|
||||
properties_sections
|
||||
}
|
||||
LayerDataType::Folder(_) => {
|
||||
LegacyLayerType::Folder(_) => {
|
||||
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 pivot = layer.transform.transform_vector2(layer.layerspace_pivot(&render_data));
|
||||
LayoutGroup::Section {
|
||||
|
|
|
@ -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::LayerId;
|
||||
|
||||
|
@ -60,7 +60,7 @@ pub struct 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: 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 mut tooltip = name.clone();
|
||||
|
|
|
@ -719,8 +719,10 @@ impl PortfolioMessageHandler {
|
|||
return;
|
||||
};
|
||||
|
||||
self.executor.poll_node_graph_evaluation(&mut active_document.document_legacy, responses).unwrap_or_else(|e| {
|
||||
log::error!("Error while evaluating node graph: {e}");
|
||||
});
|
||||
self.executor
|
||||
.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}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::consts::{
|
|||
use crate::messages::prelude::*;
|
||||
|
||||
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::{LayerId, Operation};
|
||||
use graphene_core::vector::{ManipulatorPointId, SelectedType};
|
||||
|
@ -262,7 +262,7 @@ impl SnapManager {
|
|||
&mut self,
|
||||
document_message_handler: &DocumentMessageHandler,
|
||||
input: &InputPreprocessorMessageHandler,
|
||||
layer: &Layer,
|
||||
layer: &LegacyLayer,
|
||||
path: &[LayerId],
|
||||
include_handles: bool,
|
||||
ignore_points: &[ManipulatorPointInfo],
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::messages::portfolio::document::utility_types::misc::{LayerMetadata, L
|
|||
use crate::messages::prelude::*;
|
||||
use document_legacy::document::Document as DocumentLegacy;
|
||||
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 graph_craft::document::value::TaggedValue;
|
||||
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_layer = match &layer.data {
|
||||
LayerDataType::Layer(layer) => Ok(layer),
|
||||
LegacyLayerType::Layer(layer) => Ok(layer),
|
||||
_ => Err("Invalid layer type".to_string()),
|
||||
}?;
|
||||
layer_layer.network.clone()
|
||||
|
@ -595,7 +595,7 @@ impl NodeGraphExecutor {
|
|||
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<_>>();
|
||||
for response in results {
|
||||
match response {
|
||||
|
@ -634,7 +634,7 @@ impl NodeGraphExecutor {
|
|||
LayerDataTypeDiscriminant::Layer
|
||||
},
|
||||
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),
|
||||
},
|
||||
path: vec![node_id],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
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 graph_craft::{
|
||||
concrete,
|
||||
|
@ -88,7 +88,7 @@ fn init_logging() {
|
|||
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::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")
|
||||
};
|
||||
let network = &node_graph.network;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue