mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 06:48:11 +08:00
Remove dead code from document-legacy
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
use crate::boolean_ops::composite_boolean_operation;
|
|
||||||
use crate::intersection::Quad;
|
use crate::intersection::Quad;
|
||||||
use crate::layers::folder_layer::FolderLayer;
|
use crate::layers::folder_layer::FolderLayer;
|
||||||
use crate::layers::layer_info::{Layer, LayerData, LayerDataType, LayerDataTypeDiscriminant};
|
use crate::layers::layer_info::{Layer, LayerData, LayerDataType, LayerDataTypeDiscriminant};
|
||||||
@@ -9,7 +8,6 @@ use crate::{DocumentError, DocumentResponse, Operation};
|
|||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
@@ -155,25 +153,6 @@ impl Document {
|
|||||||
self.folder_mut(path)?.layer_mut(id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))
|
self.folder_mut(path)?.layer_mut(id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns vector `Shape`s for each specified in `paths`.
|
|
||||||
/// If any path is not a shape, or does not exist, `DocumentError::InvalidPath` is returned.
|
|
||||||
fn transformed_shapes(&self, paths: &[Vec<LayerId>]) -> Result<Vec<ShapeLayer>, DocumentError> {
|
|
||||||
let mut shapes: Vec<ShapeLayer> = Vec::new();
|
|
||||||
let undo_viewport = self.root.transform.inverse();
|
|
||||||
for path in paths {
|
|
||||||
match (self.multiply_transforms(path), &self.layer(path)?.data) {
|
|
||||||
(Ok(shape_transform), LayerDataType::Shape(shape)) => {
|
|
||||||
let mut new_shape = shape.clone();
|
|
||||||
new_shape.shape.apply_affine(undo_viewport * shape_transform);
|
|
||||||
shapes.push(new_shape);
|
|
||||||
}
|
|
||||||
(Ok(_), _) => return Err(DocumentError::InvalidPath),
|
|
||||||
(Err(err), _) => return Err(err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(shapes)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn common_layer_path_prefix<'a>(&self, layers: impl Iterator<Item = &'a [LayerId]>) -> &'a [LayerId] {
|
pub fn common_layer_path_prefix<'a>(&self, layers: impl Iterator<Item = &'a [LayerId]>) -> &'a [LayerId] {
|
||||||
layers.reduce(|a, b| &a[..a.iter().zip(b.iter()).take_while(|&(a, b)| a == b).count()]).unwrap_or_default()
|
layers.reduce(|a, b| &a[..a.iter().zip(b.iter()).take_while(|&(a, b)| a == b).count()]).unwrap_or_default()
|
||||||
}
|
}
|
||||||
@@ -487,7 +466,7 @@ impl Document {
|
|||||||
|
|
||||||
/// Mutate the document by applying the `operation` to it. If the operation necessitates a
|
/// Mutate the document by applying the `operation` to it. If the operation necessitates a
|
||||||
/// reaction from the frontend, responses may be returned.
|
/// reaction from the frontend, responses may be returned.
|
||||||
pub fn handle_operation(&mut self, operation: Operation, render_data: &RenderData) -> Result<Option<Vec<DocumentResponse>>, DocumentError> {
|
pub fn handle_operation(&mut self, operation: Operation) -> Result<Option<Vec<DocumentResponse>>, DocumentError> {
|
||||||
use DocumentResponse::*;
|
use DocumentResponse::*;
|
||||||
|
|
||||||
operation.pseudo_hash().hash(&mut self.state_identifier);
|
operation.pseudo_hash().hash(&mut self.state_identifier);
|
||||||
@@ -532,19 +511,6 @@ impl Document {
|
|||||||
}
|
}
|
||||||
Some(vec![LayerChanged { path: layer_path.clone() }])
|
Some(vec![LayerChanged { path: layer_path.clone() }])
|
||||||
}
|
}
|
||||||
Operation::AddNgon {
|
|
||||||
path,
|
|
||||||
insert_index,
|
|
||||||
transform,
|
|
||||||
style,
|
|
||||||
sides,
|
|
||||||
} => {
|
|
||||||
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::ngon(sides, style)), transform);
|
|
||||||
|
|
||||||
self.set_layer(&path, layer, insert_index)?;
|
|
||||||
|
|
||||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
|
||||||
}
|
|
||||||
Operation::AddShape {
|
Operation::AddShape {
|
||||||
path,
|
path,
|
||||||
transform,
|
transform,
|
||||||
@@ -567,33 +533,6 @@ impl Document {
|
|||||||
self.set_layer(&path, Layer::new(LayerDataType::Shape(ShapeLayer::poly_line(points, style)), transform), insert_index)?;
|
self.set_layer(&path, Layer::new(LayerDataType::Shape(ShapeLayer::poly_line(points, style)), transform), insert_index)?;
|
||||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||||
}
|
}
|
||||||
Operation::BooleanOperation { operation, selected } => {
|
|
||||||
let mut responses = Vec::new();
|
|
||||||
if selected.len() > 1 {
|
|
||||||
let new_shapes = composite_boolean_operation(operation, &mut self.transformed_shapes(&selected)?.into_iter().rev().map(RefCell::new).collect())?;
|
|
||||||
|
|
||||||
for path in selected {
|
|
||||||
self.delete(&path)?;
|
|
||||||
responses.push(DocumentResponse::DeletedLayer { path })
|
|
||||||
}
|
|
||||||
for new_shape in new_shapes {
|
|
||||||
let new_id = self.add_layer(&[], Layer::new(LayerDataType::Shape(new_shape), DAffine2::IDENTITY.to_cols_array()), -1)?;
|
|
||||||
responses.push(DocumentResponse::CreatedLayer { path: vec![new_id] })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some([vec![DocumentChanged, DocumentResponse::FolderChanged { path: vec![] }], responses].concat())
|
|
||||||
}
|
|
||||||
Operation::AddSpline {
|
|
||||||
path,
|
|
||||||
insert_index,
|
|
||||||
points,
|
|
||||||
transform,
|
|
||||||
style,
|
|
||||||
} => {
|
|
||||||
let points: Vec<glam::DVec2> = points.iter().map(|&it| it.into()).collect();
|
|
||||||
self.set_layer(&path, Layer::new(LayerDataType::Shape(ShapeLayer::spline(points, style)), transform), insert_index)?;
|
|
||||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
|
||||||
}
|
|
||||||
Operation::DeleteLayer { path } => {
|
Operation::DeleteLayer { path } => {
|
||||||
fn aggregate_deletions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
|
fn aggregate_deletions(folder: &FolderLayer, 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()) {
|
||||||
@@ -742,83 +681,6 @@ impl Document {
|
|||||||
}
|
}
|
||||||
Some(Vec::new())
|
Some(Vec::new())
|
||||||
}
|
}
|
||||||
Operation::InsertManipulatorGroup {
|
|
||||||
layer_path,
|
|
||||||
manipulator_group,
|
|
||||||
after_id,
|
|
||||||
} => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
shape.manipulator_groups_mut().insert(manipulator_group, after_id);
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::PushManipulatorGroup { layer_path, manipulator_group } => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
shape.manipulator_groups_mut().push(manipulator_group);
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::PushFrontManipulatorGroup { layer_path, manipulator_group } => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
shape.manipulator_groups_mut().push_front(manipulator_group);
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::RemoveManipulatorGroup { layer_path, id } => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
shape.manipulator_groups_mut().remove(id);
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::MoveManipulatorPoint {
|
|
||||||
layer_path,
|
|
||||||
id,
|
|
||||||
manipulator_type: control_type,
|
|
||||||
position,
|
|
||||||
} => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
if let Some(manipulator_group) = shape.manipulator_groups_mut().by_id_mut(id) {
|
|
||||||
manipulator_group.set_point_position(control_type as usize, position.into());
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::SetManipulatorPoints {
|
|
||||||
layer_path,
|
|
||||||
id,
|
|
||||||
manipulator_type,
|
|
||||||
position,
|
|
||||||
} => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
if let Some(manipulator_group) = shape.manipulator_groups_mut().by_id_mut(id) {
|
|
||||||
if let Some(position) = position {
|
|
||||||
manipulator_group.set_point_position(manipulator_type as usize, position.into());
|
|
||||||
} else {
|
|
||||||
manipulator_group.points[manipulator_type] = None;
|
|
||||||
}
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::RemoveManipulatorPoint {
|
|
||||||
layer_path,
|
|
||||||
id,
|
|
||||||
manipulator_type: control_type,
|
|
||||||
} => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
if let Some(manipulator_group) = shape.manipulator_groups_mut().by_id_mut(id) {
|
|
||||||
manipulator_group.points[control_type as usize] = None;
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::TransformLayerInScope { path, transform, scope } => {
|
Operation::TransformLayerInScope { path, transform, scope } => {
|
||||||
let transform = DAffine2::from_cols_array(&transform);
|
let transform = DAffine2::from_cols_array(&transform);
|
||||||
let scope = DAffine2::from_cols_array(&scope);
|
let scope = DAffine2::from_cols_array(&scope);
|
||||||
@@ -833,17 +695,6 @@ impl Document {
|
|||||||
self.mark_as_dirty(&path)?;
|
self.mark_as_dirty(&path)?;
|
||||||
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
||||||
}
|
}
|
||||||
Operation::TransformLayerScaleAroundPivot { path, scale_factor } => {
|
|
||||||
let layer = self.layer_mut(&path)?;
|
|
||||||
|
|
||||||
let offset = DAffine2::from_translation(-layer.pivot);
|
|
||||||
let scale = DAffine2::from_scale(scale_factor.into());
|
|
||||||
let offset_back = DAffine2::from_translation(layer.pivot);
|
|
||||||
layer.transform = layer.transform * offset_back * scale * offset;
|
|
||||||
|
|
||||||
self.mark_as_dirty(&path)?;
|
|
||||||
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
|
||||||
}
|
|
||||||
Operation::SetLayerScaleAroundPivot { path, new_scale } => {
|
Operation::SetLayerScaleAroundPivot { path, new_scale } => {
|
||||||
let layer = self.layer_mut(&path)?;
|
let layer = self.layer_mut(&path)?;
|
||||||
|
|
||||||
@@ -867,12 +718,6 @@ impl Document {
|
|||||||
self.mark_as_dirty(&path)?;
|
self.mark_as_dirty(&path)?;
|
||||||
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
||||||
}
|
}
|
||||||
Operation::ToggleLayerVisibility { path } => {
|
|
||||||
self.mark_as_dirty(&path)?;
|
|
||||||
let layer = self.layer_mut(&path)?;
|
|
||||||
layer.visible = !layer.visible;
|
|
||||||
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
|
||||||
}
|
|
||||||
Operation::SetLayerVisibility { path, visible } => {
|
Operation::SetLayerVisibility { path, visible } => {
|
||||||
self.mark_as_dirty(&path)?;
|
self.mark_as_dirty(&path)?;
|
||||||
let layer = self.layer_mut(&path)?;
|
let layer = self.layer_mut(&path)?;
|
||||||
@@ -919,101 +764,6 @@ impl Document {
|
|||||||
self.mark_as_dirty(&path)?;
|
self.mark_as_dirty(&path)?;
|
||||||
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may not want the concept of selection here. For now leaving though.
|
|
||||||
Operation::SelectManipulatorPoints { layer_path, point_ids, add } => {
|
|
||||||
let layer = self.layer_mut(&layer_path)?;
|
|
||||||
if let Some(shape) = layer.as_subpath_mut() {
|
|
||||||
if !add {
|
|
||||||
shape.clear_selected_manipulator_groups();
|
|
||||||
}
|
|
||||||
shape.select_points(&point_ids, true);
|
|
||||||
}
|
|
||||||
Some(vec![LayerChanged { path: layer_path.clone() }])
|
|
||||||
}
|
|
||||||
Operation::DeselectManipulatorPoints { layer_path, point_ids } => {
|
|
||||||
let layer = self.layer_mut(&layer_path)?;
|
|
||||||
if let Some(shape) = layer.as_subpath_mut() {
|
|
||||||
shape.select_points(&point_ids, false);
|
|
||||||
}
|
|
||||||
Some(vec![LayerChanged { path: layer_path.clone() }])
|
|
||||||
}
|
|
||||||
Operation::SelectAllAnchors { layer_path } => {
|
|
||||||
let layer = self.layer_mut(&layer_path)?;
|
|
||||||
if let Some(subpath) = layer.as_subpath_mut() {
|
|
||||||
subpath.select_all_anchors();
|
|
||||||
}
|
|
||||||
Some(vec![LayerChanged { path: layer_path.clone() }])
|
|
||||||
}
|
|
||||||
Operation::DeselectAllManipulatorPoints { layer_path } => {
|
|
||||||
let layer = self.layer_mut(&layer_path)?;
|
|
||||||
if let Some(shape) = layer.as_subpath_mut() {
|
|
||||||
shape.clear_selected_manipulator_groups();
|
|
||||||
}
|
|
||||||
Some(vec![LayerChanged { path: layer_path.clone() }])
|
|
||||||
}
|
|
||||||
Operation::DeleteSelectedManipulatorPoints { layer_paths } => {
|
|
||||||
let mut responses = vec![];
|
|
||||||
for layer_path in layer_paths {
|
|
||||||
let layer = self.layer_mut(&layer_path)?;
|
|
||||||
if let Some(shape) = layer.as_subpath_mut() {
|
|
||||||
// Delete the selected points.
|
|
||||||
shape.delete_selected();
|
|
||||||
|
|
||||||
// Delete the layer if there are no longer any manipulator groups
|
|
||||||
if (shape.manipulator_groups().len() - 1) == 0 {
|
|
||||||
// Delegate deletion to DeleteLayer to update Layer Tree in frontend
|
|
||||||
match self.handle_operation(Operation::DeleteLayer { path: layer_path.clone() }, render_data) {
|
|
||||||
Ok(Some(delete_responses)) => {
|
|
||||||
responses.extend(delete_responses);
|
|
||||||
responses.push(DocumentResponse::DeletedSelectedManipulatorPoints);
|
|
||||||
return Ok(Some(responses));
|
|
||||||
}
|
|
||||||
Err(e) => error!("DocumentError: {:?}", e),
|
|
||||||
Ok(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we still have manipulator groups, update the layer and thumbnails
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
responses.push(DocumentChanged);
|
|
||||||
responses.push(LayerChanged { path: layer_path.clone() });
|
|
||||||
responses.append(&mut update_thumbnails_upstream(&layer_path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(responses)
|
|
||||||
}
|
|
||||||
Operation::MoveSelectedManipulatorPoints { layer_path, delta, mirror_distance } => {
|
|
||||||
if let Ok(viewspace) = self.generate_transform_relative_to_viewport(&layer_path) {
|
|
||||||
let objectspace = &viewspace.inverse();
|
|
||||||
let delta = objectspace.transform_vector2(DVec2::new(delta.0, delta.1));
|
|
||||||
let layer = self.layer_mut(&layer_path)?;
|
|
||||||
if let Some(shape) = layer.as_subpath_mut() {
|
|
||||||
shape.move_selected(delta, mirror_distance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
Some([vec![DocumentChanged, LayerChanged { path: layer_path.clone() }], update_thumbnails_upstream(&layer_path)].concat())
|
|
||||||
}
|
|
||||||
Operation::SetManipulatorHandleMirroring { layer_path, id, mirror_angle } => {
|
|
||||||
if let Ok(Some(shape)) = self.layer_mut(&layer_path).map(|layer| layer.as_subpath_mut()) {
|
|
||||||
if let Some(manipulator_group) = shape.manipulator_groups_mut().by_id_mut(id) {
|
|
||||||
manipulator_group.editor_state.mirror_angle_between_handles = mirror_angle;
|
|
||||||
self.mark_as_dirty(&layer_path)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some([update_thumbnails_upstream(&layer_path), vec![DocumentChanged, LayerChanged { path: layer_path }]].concat())
|
|
||||||
}
|
|
||||||
Operation::SetSelectedHandleMirroring { layer_path, toggle_angle } => {
|
|
||||||
let layer = self.layer_mut(&layer_path)?;
|
|
||||||
if let Some(shape) = layer.as_subpath_mut() {
|
|
||||||
for manipulator_group in shape.selected_manipulator_groups_any_points_mut() {
|
|
||||||
manipulator_group.toggle_mirroring(toggle_angle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This does nothing visually so we don't need to send any messages
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Ok(responses)
|
Ok(responses)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use super::LayerId;
|
use super::LayerId;
|
||||||
use crate::boolean_ops::BooleanOperationError;
|
|
||||||
|
|
||||||
/// A set of different errors that can occur when using this crate.
|
/// A set of different errors that can occur when using this crate.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@@ -13,11 +12,4 @@ pub enum DocumentError {
|
|||||||
NotText,
|
NotText,
|
||||||
NotNodeGraph,
|
NotNodeGraph,
|
||||||
InvalidFile(String),
|
InvalidFile(String),
|
||||||
BooleanOperationError(BooleanOperationError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<BooleanOperationError> for DocumentError {
|
|
||||||
fn from(err: BooleanOperationError) -> Self {
|
|
||||||
DocumentError::BooleanOperationError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
use crate::boolean_ops::BooleanOperation as BooleanOperationType;
|
|
||||||
use crate::layers::blend_mode::BlendMode;
|
use crate::layers::blend_mode::BlendMode;
|
||||||
use crate::layers::layer_info::Layer;
|
use crate::layers::layer_info::Layer;
|
||||||
use crate::layers::style::{self, Stroke};
|
use crate::layers::style::{self, Stroke};
|
||||||
use crate::LayerId;
|
use crate::LayerId;
|
||||||
|
|
||||||
use graphene_core::vector::SelectedType;
|
|
||||||
use graphene_std::vector::consts::ManipulatorType;
|
|
||||||
use graphene_std::vector::manipulator_group::ManipulatorGroup;
|
|
||||||
use graphene_std::vector::subpath::Subpath;
|
use graphene_std::vector::subpath::Subpath;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -18,24 +14,6 @@ use std::hash::{Hash, Hasher};
|
|||||||
// TODO: Rename all instances of `path` to `layer_path`
|
// TODO: Rename all instances of `path` to `layer_path`
|
||||||
/// Operations that can be performed to mutate the document.
|
/// Operations that can be performed to mutate the document.
|
||||||
pub enum Operation {
|
pub enum Operation {
|
||||||
AddEllipse {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
insert_index: isize,
|
|
||||||
transform: [f64; 6],
|
|
||||||
style: style::PathStyle,
|
|
||||||
},
|
|
||||||
AddRect {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
insert_index: isize,
|
|
||||||
transform: [f64; 6],
|
|
||||||
style: style::PathStyle,
|
|
||||||
},
|
|
||||||
AddLine {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
insert_index: isize,
|
|
||||||
transform: [f64; 6],
|
|
||||||
style: style::PathStyle,
|
|
||||||
},
|
|
||||||
AddFrame {
|
AddFrame {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
insert_index: isize,
|
insert_index: isize,
|
||||||
@@ -58,75 +36,12 @@ pub enum Operation {
|
|||||||
layer_path: Vec<LayerId>,
|
layer_path: Vec<LayerId>,
|
||||||
pivot: (f64, f64),
|
pivot: (f64, f64),
|
||||||
},
|
},
|
||||||
AddPolyline {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
insert_index: isize,
|
|
||||||
transform: [f64; 6],
|
|
||||||
style: style::PathStyle,
|
|
||||||
points: Vec<(f64, f64)>,
|
|
||||||
},
|
|
||||||
AddSpline {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
insert_index: isize,
|
|
||||||
transform: [f64; 6],
|
|
||||||
style: style::PathStyle,
|
|
||||||
points: Vec<(f64, f64)>,
|
|
||||||
},
|
|
||||||
AddNgon {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
insert_index: isize,
|
|
||||||
transform: [f64; 6],
|
|
||||||
style: style::PathStyle,
|
|
||||||
sides: u32,
|
|
||||||
},
|
|
||||||
AddShape {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
insert_index: isize,
|
|
||||||
transform: [f64; 6],
|
|
||||||
style: style::PathStyle,
|
|
||||||
// TODO This will become a compound path once we support them.
|
|
||||||
subpath: Subpath,
|
|
||||||
},
|
|
||||||
BooleanOperation {
|
|
||||||
operation: BooleanOperationType,
|
|
||||||
selected: Vec<Vec<LayerId>>,
|
|
||||||
},
|
|
||||||
DeleteLayer {
|
DeleteLayer {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
},
|
},
|
||||||
DeleteSelectedManipulatorPoints {
|
|
||||||
layer_paths: Vec<Vec<LayerId>>,
|
|
||||||
},
|
|
||||||
DeselectManipulatorPoints {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
point_ids: Vec<(u64, ManipulatorType)>,
|
|
||||||
},
|
|
||||||
DeselectAllManipulatorPoints {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
},
|
|
||||||
SelectAllAnchors {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
},
|
|
||||||
DuplicateLayer {
|
DuplicateLayer {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
},
|
},
|
||||||
MoveSelectedManipulatorPoints {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
delta: (f64, f64),
|
|
||||||
mirror_distance: bool,
|
|
||||||
},
|
|
||||||
MoveManipulatorPoint {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
id: u64,
|
|
||||||
manipulator_type: SelectedType,
|
|
||||||
position: (f64, f64),
|
|
||||||
},
|
|
||||||
SetManipulatorPoints {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
id: u64,
|
|
||||||
manipulator_type: ManipulatorType,
|
|
||||||
position: Option<(f64, f64)>,
|
|
||||||
},
|
|
||||||
RenameLayer {
|
RenameLayer {
|
||||||
layer_path: Vec<LayerId>,
|
layer_path: Vec<LayerId>,
|
||||||
new_name: String,
|
new_name: String,
|
||||||
@@ -151,11 +66,6 @@ pub enum Operation {
|
|||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
transform: [f64; 6],
|
transform: [f64; 6],
|
||||||
},
|
},
|
||||||
SelectManipulatorPoints {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
point_ids: Vec<(u64, ManipulatorType)>,
|
|
||||||
add: bool,
|
|
||||||
},
|
|
||||||
SetShapePath {
|
SetShapePath {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
subpath: Subpath,
|
subpath: Subpath,
|
||||||
@@ -164,28 +74,6 @@ pub enum Operation {
|
|||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
vector_data: graphene_core::vector::VectorData,
|
vector_data: graphene_core::vector::VectorData,
|
||||||
},
|
},
|
||||||
InsertManipulatorGroup {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
manipulator_group: ManipulatorGroup,
|
|
||||||
after_id: u64,
|
|
||||||
},
|
|
||||||
PushManipulatorGroup {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
manipulator_group: ManipulatorGroup,
|
|
||||||
},
|
|
||||||
PushFrontManipulatorGroup {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
manipulator_group: ManipulatorGroup,
|
|
||||||
},
|
|
||||||
RemoveManipulatorGroup {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
id: u64,
|
|
||||||
},
|
|
||||||
RemoveManipulatorPoint {
|
|
||||||
layer_path: Vec<LayerId>,
|
|
||||||
id: u64,
|
|
||||||
manipulator_type: ManipulatorType,
|
|
||||||
},
|
|
||||||
TransformLayerInScope {
|
TransformLayerInScope {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
transform: [f64; 6],
|
transform: [f64; 6],
|
||||||
@@ -196,10 +84,6 @@ pub enum Operation {
|
|||||||
transform: [f64; 6],
|
transform: [f64; 6],
|
||||||
scope: [f64; 6],
|
scope: [f64; 6],
|
||||||
},
|
},
|
||||||
TransformLayerScaleAroundPivot {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
scale_factor: (f64, f64),
|
|
||||||
},
|
|
||||||
SetLayerScaleAroundPivot {
|
SetLayerScaleAroundPivot {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
new_scale: (f64, f64),
|
new_scale: (f64, f64),
|
||||||
@@ -208,9 +92,6 @@ pub enum Operation {
|
|||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
transform: [f64; 6],
|
transform: [f64; 6],
|
||||||
},
|
},
|
||||||
ToggleLayerVisibility {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
},
|
|
||||||
SetLayerVisibility {
|
SetLayerVisibility {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
visible: bool,
|
visible: bool,
|
||||||
@@ -231,10 +112,6 @@ pub enum Operation {
|
|||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
opacity: f64,
|
opacity: f64,
|
||||||
},
|
},
|
||||||
SetLayerStyle {
|
|
||||||
path: Vec<LayerId>,
|
|
||||||
style: style::PathStyle,
|
|
||||||
},
|
|
||||||
SetLayerFill {
|
SetLayerFill {
|
||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
fill: style::Fill,
|
fill: style::Fill,
|
||||||
@@ -243,14 +120,43 @@ pub enum Operation {
|
|||||||
path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
stroke: Stroke,
|
stroke: Stroke,
|
||||||
},
|
},
|
||||||
SetManipulatorHandleMirroring {
|
|
||||||
layer_path: Vec<LayerId>,
|
// The following are used only by the legacy overlays system
|
||||||
id: u64,
|
AddEllipse {
|
||||||
mirror_angle: bool,
|
path: Vec<LayerId>,
|
||||||
|
insert_index: isize,
|
||||||
|
transform: [f64; 6],
|
||||||
|
style: style::PathStyle,
|
||||||
},
|
},
|
||||||
SetSelectedHandleMirroring {
|
AddRect {
|
||||||
layer_path: Vec<LayerId>,
|
path: Vec<LayerId>,
|
||||||
toggle_angle: bool,
|
insert_index: isize,
|
||||||
|
transform: [f64; 6],
|
||||||
|
style: style::PathStyle,
|
||||||
|
},
|
||||||
|
AddLine {
|
||||||
|
path: Vec<LayerId>,
|
||||||
|
insert_index: isize,
|
||||||
|
transform: [f64; 6],
|
||||||
|
style: style::PathStyle,
|
||||||
|
},
|
||||||
|
AddPolyline {
|
||||||
|
path: Vec<LayerId>,
|
||||||
|
insert_index: isize,
|
||||||
|
transform: [f64; 6],
|
||||||
|
style: style::PathStyle,
|
||||||
|
points: Vec<(f64, f64)>,
|
||||||
|
},
|
||||||
|
AddShape {
|
||||||
|
path: Vec<LayerId>,
|
||||||
|
insert_index: isize,
|
||||||
|
transform: [f64; 6],
|
||||||
|
style: style::PathStyle,
|
||||||
|
subpath: Subpath,
|
||||||
|
},
|
||||||
|
SetLayerStyle {
|
||||||
|
path: Vec<LayerId>,
|
||||||
|
style: style::PathStyle,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,25 +27,21 @@ impl MessageHandler<ArtboardMessage, &PersistentData> for ArtboardMessageHandler
|
|||||||
match message {
|
match message {
|
||||||
// Sub-messages
|
// Sub-messages
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
DispatchOperation(operation) => {
|
DispatchOperation(operation) => match self.artboards_document.handle_operation(*operation) {
|
||||||
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, None);
|
Ok(Some(document_responses)) => {
|
||||||
|
for response in document_responses {
|
||||||
match self.artboards_document.handle_operation(*operation, &render_data) {
|
match &response {
|
||||||
Ok(Some(document_responses)) => {
|
DocumentResponse::LayerChanged { path } => responses.add(PropertiesPanelMessage::CheckSelectedWasUpdated { path: path.clone() }),
|
||||||
for response in document_responses {
|
DocumentResponse::DeletedLayer { path } => responses.add(PropertiesPanelMessage::CheckSelectedWasDeleted { path: path.clone() }),
|
||||||
match &response {
|
DocumentResponse::DocumentChanged => responses.add(ArtboardMessage::RenderArtboards),
|
||||||
DocumentResponse::LayerChanged { path } => responses.add(PropertiesPanelMessage::CheckSelectedWasUpdated { path: path.clone() }),
|
_ => {}
|
||||||
DocumentResponse::DeletedLayer { path } => responses.add(PropertiesPanelMessage::CheckSelectedWasDeleted { path: path.clone() }),
|
};
|
||||||
DocumentResponse::DocumentChanged => responses.add(ArtboardMessage::RenderArtboards),
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(None) => {}
|
|
||||||
Err(e) => error!("Artboard Error: {:?}", e),
|
|
||||||
}
|
}
|
||||||
}
|
Ok(None) => {}
|
||||||
|
Err(e) => error!("Artboard Error: {:?}", e),
|
||||||
|
},
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
AddArtboard { id, position, size } => {
|
AddArtboard { id, position, size } => {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use crate::messages::portfolio::document::utility_types::layer_panel::LayerMetad
|
|||||||
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis};
|
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use document_legacy::boolean_ops::BooleanOperation as BooleanOperationType;
|
|
||||||
use document_legacy::document::Document as DocumentLegacy;
|
use document_legacy::document::Document as DocumentLegacy;
|
||||||
use document_legacy::layers::blend_mode::BlendMode;
|
use document_legacy::layers::blend_mode::BlendMode;
|
||||||
use document_legacy::layers::style::ViewMode;
|
use document_legacy::layers::style::ViewMode;
|
||||||
@@ -55,7 +54,6 @@ pub enum DocumentMessage {
|
|||||||
artboard: Box<ArtboardMessageHandler>,
|
artboard: Box<ArtboardMessageHandler>,
|
||||||
layer_metadata: HashMap<Vec<LayerId>, LayerMetadata>,
|
layer_metadata: HashMap<Vec<LayerId>, LayerMetadata>,
|
||||||
},
|
},
|
||||||
BooleanOperation(BooleanOperationType),
|
|
||||||
ClearLayerTree,
|
ClearLayerTree,
|
||||||
CommitTransaction,
|
CommitTransaction,
|
||||||
CopyToClipboardLayerImageOutput {
|
CopyToClipboardLayerImageOutput {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ use crate::messages::prelude::*;
|
|||||||
use crate::messages::tool::utility_types::ToolType;
|
use crate::messages::tool::utility_types::ToolType;
|
||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
use crate::node_graph_executor::NodeGraphExecutor;
|
||||||
|
|
||||||
use document_legacy::boolean_ops::BooleanOperationError;
|
|
||||||
use document_legacy::document::Document as DocumentLegacy;
|
use document_legacy::document::Document as DocumentLegacy;
|
||||||
use document_legacy::layers::blend_mode::BlendMode;
|
use document_legacy::layers::blend_mode::BlendMode;
|
||||||
use document_legacy::layers::folder_layer::FolderLayer;
|
use document_legacy::layers::folder_layer::FolderLayer;
|
||||||
@@ -120,7 +119,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
// Sub-messages
|
// Sub-messages
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
DispatchOperation(op) => {
|
DispatchOperation(op) => {
|
||||||
match self.document_legacy.handle_operation(*op, &render_data) {
|
match self.document_legacy.handle_operation(*op) {
|
||||||
Ok(Some(document_responses)) => {
|
Ok(Some(document_responses)) => {
|
||||||
for response in document_responses {
|
for response in document_responses {
|
||||||
match &response {
|
match &response {
|
||||||
@@ -157,13 +156,6 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Display boolean operation error to the user (except if it is a nothing done error).
|
|
||||||
Err(DocumentError::BooleanOperationError(boolean_operation_error)) if boolean_operation_error != BooleanOperationError::NothingDone => {
|
|
||||||
responses.add(DialogMessage::DisplayDialogError {
|
|
||||||
title: "Failed to calculate boolean operation".into(),
|
|
||||||
description: format!("Unfortunately, this feature not that robust yet.\n\nError: {boolean_operation_error:?}"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(e) => error!("DocumentError: {:?}", e),
|
Err(e) => error!("DocumentError: {:?}", e),
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
}
|
}
|
||||||
@@ -256,16 +248,6 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
BackupDocument { document, artboard, layer_metadata } => self.backup_with_document(document, *artboard, layer_metadata, responses),
|
BackupDocument { document, artboard, layer_metadata } => self.backup_with_document(document, *artboard, layer_metadata, responses),
|
||||||
BooleanOperation(op) => {
|
|
||||||
// Convert Vec<&[LayerId]> to Vec<Vec<&LayerId>> because Vec<&[LayerId]> does not implement several traits (Debug, Serialize, Deserialize, ...) required by DocumentOperation enum
|
|
||||||
responses.add(StartTransaction);
|
|
||||||
responses.add(BroadcastEvent::ToolAbort);
|
|
||||||
responses.add(DocumentOperation::BooleanOperation {
|
|
||||||
operation: op,
|
|
||||||
selected: self.selected_layers_sorted().iter().map(|slice| (*slice).into()).collect(),
|
|
||||||
});
|
|
||||||
responses.add(CommitTransaction);
|
|
||||||
}
|
|
||||||
ClearLayerTree => {
|
ClearLayerTree => {
|
||||||
// Send an empty layer tree
|
// Send an empty layer tree
|
||||||
let data_buffer: RawBuffer = Self::default().serialize_root().as_slice().into();
|
let data_buffer: RawBuffer = Self::default().serialize_root().as_slice().into();
|
||||||
@@ -874,8 +856,11 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
responses.add(LayerChanged { affected_layer_path: layer_path })
|
responses.add(LayerChanged { affected_layer_path: layer_path })
|
||||||
}
|
}
|
||||||
ToggleLayerVisibility { layer_path } => {
|
ToggleLayerVisibility { layer_path } => {
|
||||||
responses.add(DocumentOperation::ToggleLayerVisibility { path: layer_path });
|
if let Ok(layer) = self.document_legacy.layer(&layer_path) {
|
||||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
let visible = layer.visible;
|
||||||
|
responses.add(DocumentOperation::SetLayerVisibility { path: layer_path, visible: !visible });
|
||||||
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Undo => {
|
Undo => {
|
||||||
self.undo_in_progress = true;
|
self.undo_in_progress = true;
|
||||||
|
|||||||
@@ -18,14 +18,10 @@ impl MessageHandler<OverlaysMessage, (bool, &PersistentData, &InputPreprocessorM
|
|||||||
match message {
|
match message {
|
||||||
// Sub-messages
|
// Sub-messages
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
DispatchOperation(operation) => {
|
DispatchOperation(operation) => match self.overlays_document.handle_operation(*operation) {
|
||||||
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, Some(ipp.document_bounds()));
|
Ok(_) => responses.add(OverlaysMessage::Rerender),
|
||||||
|
Err(e) => error!("OverlaysError: {:?}", e),
|
||||||
match self.overlays_document.handle_operation(*operation, &render_data) {
|
},
|
||||||
Ok(_) => responses.add(OverlaysMessage::Rerender),
|
|
||||||
Err(e) => error!("OverlaysError: {:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
ClearAllOverlays => {
|
ClearAllOverlays => {
|
||||||
|
|||||||
@@ -8,18 +8,13 @@ use crate::messages::prelude::*;
|
|||||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||||
use crate::messages::tool::utility_types::{DocumentToolData, EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
|
use crate::messages::tool::utility_types::{DocumentToolData, EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
|
||||||
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
|
||||||
|
|
||||||
use document_legacy::LayerId;
|
use document_legacy::LayerId;
|
||||||
use dyn_any::downcast_ref;
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeInput, NodeNetwork};
|
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeInput, NodeNetwork};
|
||||||
|
|
||||||
use graphene_core::Color;
|
|
||||||
|
|
||||||
use glam::DVec2;
|
|
||||||
use graphene_core::raster::ImageFrame;
|
use graphene_core::raster::ImageFrame;
|
||||||
|
|
||||||
|
use glam::DVec2;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@@ -177,9 +172,6 @@ impl ToolTransition for BrushTool {
|
|||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
struct BrushToolData {
|
struct BrushToolData {
|
||||||
points: Vec<Vec<DVec2>>,
|
points: Vec<Vec<DVec2>>,
|
||||||
diameter: f64,
|
|
||||||
hardness: f64,
|
|
||||||
flow: f64,
|
|
||||||
path: Option<Vec<LayerId>>,
|
path: Option<Vec<LayerId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,21 +187,23 @@ impl BrushToolData {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn update_image(&self, node_graph: &NodeGraphExecutor, responses: &mut VecDeque<Message>) {
|
|
||||||
let Some(image) = node_graph.introspect_node(&[1]) else { return; };
|
// fn update_image(&self, node_graph: &NodeGraphExecutor, responses: &mut VecDeque<Message>) {
|
||||||
let image: &ImageFrame<Color> = image.downcast_ref().unwrap();
|
// let Some(image) = node_graph.introspect_node(&[1]) else { return; };
|
||||||
self.set_image(image.clone(), responses)
|
// let image: &ImageFrame<Color> = image.downcast_ref().unwrap();
|
||||||
}
|
// self.set_image(image.clone(), responses)
|
||||||
fn set_image(&self, image_frame: ImageFrame<Color>, responses: &mut VecDeque<Message>) {
|
// }
|
||||||
if let Some(layer_path) = self.path.clone() {
|
//
|
||||||
responses.add(NodeGraphMessage::SetQualifiedInputValue {
|
// fn set_image(&self, image_frame: ImageFrame<Color>, responses: &mut VecDeque<Message>) {
|
||||||
layer_path,
|
// if let Some(layer_path) = self.path.clone() {
|
||||||
node_path: vec![0],
|
// responses.add(NodeGraphMessage::SetQualifiedInputValue {
|
||||||
input_index: 1,
|
// layer_path,
|
||||||
value: TaggedValue::ImageFrame(image_frame),
|
// node_path: vec![0],
|
||||||
});
|
// input_index: 1,
|
||||||
}
|
// value: TaggedValue::ImageFrame(image_frame),
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fsm for BrushToolFsmState {
|
impl Fsm for BrushToolFsmState {
|
||||||
@@ -221,11 +215,7 @@ impl Fsm for BrushToolFsmState {
|
|||||||
event: ToolMessage,
|
event: ToolMessage,
|
||||||
tool_data: &mut Self::ToolData,
|
tool_data: &mut Self::ToolData,
|
||||||
ToolActionHandlerData {
|
ToolActionHandlerData {
|
||||||
document,
|
document, global_tool_data, input, ..
|
||||||
global_tool_data,
|
|
||||||
input,
|
|
||||||
node_graph,
|
|
||||||
..
|
|
||||||
}: &mut ToolActionHandlerData,
|
}: &mut ToolActionHandlerData,
|
||||||
tool_options: &Self::ToolOptions,
|
tool_options: &Self::ToolOptions,
|
||||||
responses: &mut VecDeque<Message>,
|
responses: &mut VecDeque<Message>,
|
||||||
@@ -241,7 +231,7 @@ impl Fsm for BrushToolFsmState {
|
|||||||
responses.add(DocumentMessage::StartTransaction);
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let existing_points = load_existing_points(document);
|
let existing_points = load_existing_points(document);
|
||||||
let new_layer = existing_points.is_none();
|
let new_layer = existing_points.is_none();
|
||||||
if let Some((layer_path, points, image)) = existing_points {
|
if let Some((layer_path, points)) = existing_points {
|
||||||
tool_data.path = Some(layer_path);
|
tool_data.path = Some(layer_path);
|
||||||
//tool_data.set_image(image, responses);
|
//tool_data.set_image(image, responses);
|
||||||
if tool_data.points.is_empty() {
|
if tool_data.points.is_empty() {
|
||||||
@@ -256,12 +246,8 @@ impl Fsm for BrushToolFsmState {
|
|||||||
|
|
||||||
tool_data.points.push(vec![pos]);
|
tool_data.points.push(vec![pos]);
|
||||||
|
|
||||||
tool_data.diameter = tool_options.diameter;
|
|
||||||
tool_data.hardness = tool_options.hardness;
|
|
||||||
tool_data.flow = tool_options.flow;
|
|
||||||
|
|
||||||
if new_layer {
|
if new_layer {
|
||||||
add_brush_render(tool_data, global_tool_data, responses);
|
add_brush_render(tool_options, tool_data, global_tool_data, responses);
|
||||||
} else {
|
} else {
|
||||||
//tool_data.update_image(node_graph, responses);
|
//tool_data.update_image(node_graph, responses);
|
||||||
tool_data.update_points(responses);
|
tool_data.update_points(responses);
|
||||||
@@ -276,7 +262,7 @@ impl Fsm for BrushToolFsmState {
|
|||||||
// Linear interpolation for when the mouse has moved a lot between frames
|
// Linear interpolation for when the mouse has moved a lot between frames
|
||||||
if let Some(&last_point) = tool_data.points.last().and_then(|x| x.last()) {
|
if let Some(&last_point) = tool_data.points.last().and_then(|x| x.last()) {
|
||||||
let distance = (last_point - pos).length();
|
let distance = (last_point - pos).length();
|
||||||
let extra_points = (distance / (tool_data.diameter / 2.)).floor() as usize;
|
let extra_points = (distance / (tool_options.diameter / 2.)).floor() as usize;
|
||||||
tool_data
|
tool_data
|
||||||
.points
|
.points
|
||||||
.last_mut()
|
.last_mut()
|
||||||
@@ -326,7 +312,7 @@ impl Fsm for BrushToolFsmState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_brush_render(data: &BrushToolData, tool_data: &DocumentToolData, responses: &mut VecDeque<Message>) {
|
fn add_brush_render(tool_options: &BrushOptions, data: &BrushToolData, tool_data: &DocumentToolData, responses: &mut VecDeque<Message>) {
|
||||||
let layer_path = data.path.clone().unwrap();
|
let layer_path = data.path.clone().unwrap();
|
||||||
|
|
||||||
let brush_node = DocumentNode {
|
let brush_node = DocumentNode {
|
||||||
@@ -337,11 +323,11 @@ fn add_brush_render(data: &BrushToolData, tool_data: &DocumentToolData, response
|
|||||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||||
NodeInput::value(TaggedValue::VecDVec2(data.points.last().cloned().unwrap_or_default()), false),
|
NodeInput::value(TaggedValue::VecDVec2(data.points.last().cloned().unwrap_or_default()), false),
|
||||||
// Diameter
|
// Diameter
|
||||||
NodeInput::value(TaggedValue::F64(data.diameter), false),
|
NodeInput::value(TaggedValue::F64(tool_options.diameter), false),
|
||||||
// Hardness
|
// Hardness
|
||||||
NodeInput::value(TaggedValue::F64(data.hardness), false),
|
NodeInput::value(TaggedValue::F64(tool_options.hardness), false),
|
||||||
// Flow
|
// Flow
|
||||||
NodeInput::value(TaggedValue::F64(data.flow), false),
|
NodeInput::value(TaggedValue::F64(tool_options.flow), false),
|
||||||
// Color
|
// Color
|
||||||
NodeInput::value(TaggedValue::Color(tool_data.primary_color), false),
|
NodeInput::value(TaggedValue::Color(tool_data.primary_color), false),
|
||||||
],
|
],
|
||||||
@@ -349,18 +335,18 @@ fn add_brush_render(data: &BrushToolData, tool_data: &DocumentToolData, response
|
|||||||
metadata: graph_craft::document::DocumentNodeMetadata { position: (8, 4).into() },
|
metadata: graph_craft::document::DocumentNodeMetadata { position: (8, 4).into() },
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let monitor_node = DocumentNode {
|
// let monitor_node = DocumentNode {
|
||||||
name: "Monitor".to_string(),
|
// name: "Monitor".to_string(),
|
||||||
implementation: DocumentNodeImplementation::Unresolved("graphene_std::memo::MonitorNode<_>".into()),
|
// implementation: DocumentNodeImplementation::Unresolved("graphene_std::memo::MonitorNode<_>".into()),
|
||||||
..Default::default()
|
// ..Default::default()
|
||||||
};
|
// };
|
||||||
let mut network = NodeNetwork::value_network(brush_node);
|
let mut network = NodeNetwork::value_network(brush_node);
|
||||||
//network.push_node(monitor_node, true);
|
//network.push_node(monitor_node, true);
|
||||||
network.push_output_node();
|
network.push_output_node();
|
||||||
graph_modification_utils::new_custom_layer(network, layer_path, responses);
|
graph_modification_utils::new_custom_layer(network, layer_path, responses);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_existing_points(document: &DocumentMessageHandler) -> Option<(Vec<LayerId>, Vec<DVec2>, ImageFrame<Color>)> {
|
fn load_existing_points(document: &DocumentMessageHandler) -> Option<(Vec<LayerId>, Vec<DVec2>)> {
|
||||||
if document.selected_layers().count() != 1 {
|
if document.selected_layers().count() != 1 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -370,11 +356,6 @@ fn load_existing_points(document: &DocumentMessageHandler) -> Option<(Vec<LayerI
|
|||||||
if brush_node.implementation != DocumentNodeImplementation::Unresolved("graphene_std::brush::BrushNode".into()) {
|
if brush_node.implementation != DocumentNodeImplementation::Unresolved("graphene_std::brush::BrushNode".into()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let image_input = brush_node.inputs.get(1)?;
|
|
||||||
let NodeInput::Value {
|
|
||||||
tagged_value: TaggedValue::ImageFrame(image_frame),
|
|
||||||
..
|
|
||||||
} = image_input else { return None };
|
|
||||||
let points_input = brush_node.inputs.get(3)?;
|
let points_input = brush_node.inputs.get(3)?;
|
||||||
let NodeInput::Value {
|
let NodeInput::Value {
|
||||||
tagged_value: TaggedValue::VecDVec2(points),
|
tagged_value: TaggedValue::VecDVec2(points),
|
||||||
@@ -382,5 +363,5 @@ fn load_existing_points(document: &DocumentMessageHandler) -> Option<(Vec<LayerI
|
|||||||
} = points_input else {
|
} = points_input else {
|
||||||
return None };
|
return None };
|
||||||
|
|
||||||
Some((layer_path, points.clone(), image_frame.clone()))
|
Some((layer_path, points.clone()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ use crate::messages::tool::common_functionality::resize::Resize;
|
|||||||
use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
|
use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
|
||||||
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||||
|
|
||||||
use glam::DVec2;
|
|
||||||
use graphene_core::vector::style::Fill;
|
use graphene_core::vector::style::Fill;
|
||||||
|
|
||||||
|
use glam::DVec2;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@@ -25,7 +26,7 @@ pub struct ShapeOptions {
|
|||||||
|
|
||||||
impl Default for ShapeOptions {
|
impl Default for ShapeOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { vertices: 6 }
|
Self { vertices: 5 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +126,6 @@ enum ShapeToolFsmState {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
struct ShapeToolData {
|
struct ShapeToolData {
|
||||||
sides: u32,
|
|
||||||
data: Resize,
|
data: Resize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,9 +159,8 @@ impl Fsm for ShapeToolFsmState {
|
|||||||
responses.add(DocumentMessage::StartTransaction);
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let layer_path = document.get_path_for_new_layer();
|
let layer_path = document.get_path_for_new_layer();
|
||||||
shape_data.path = Some(layer_path.clone());
|
shape_data.path = Some(layer_path.clone());
|
||||||
tool_data.sides = tool_options.vertices;
|
|
||||||
|
|
||||||
let subpath = bezier_rs::Subpath::new_regular_polygon(DVec2::ZERO, tool_data.sides as u64, 1.);
|
let subpath = bezier_rs::Subpath::new_regular_polygon(DVec2::ZERO, tool_options.vertices as u64, 1.);
|
||||||
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
||||||
responses.add(GraphOperationMessage::FillSet {
|
responses.add(GraphOperationMessage::FillSet {
|
||||||
layer: layer_path,
|
layer: layer_path,
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ use document_legacy::layers::layer_info::Layer;
|
|||||||
use document_legacy::layers::style::{self, Fill, RenderData, Stroke};
|
use document_legacy::layers::style::{self, Fill, RenderData, Stroke};
|
||||||
use document_legacy::LayerId;
|
use document_legacy::LayerId;
|
||||||
use document_legacy::Operation;
|
use document_legacy::Operation;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNode, NodeId, NodeInput, NodeNetwork};
|
use graph_craft::document::{DocumentNode, NodeId, NodeInput, NodeNetwork};
|
||||||
use graphene_core::text::{load_face, Font};
|
use graphene_core::text::{load_face, Font};
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
|
||||||
|
use glam::{DAffine2, DVec2};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use graphene_core::Node;
|
use graphene_core::Node;
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|||||||
Reference in New Issue
Block a user