Migrate demo artwork and fix all failing CI tests (#1459)

* Initial work on fixing tests

* Fix formatting

* Remove dead code to satisfy rustc warnings

* Insert into an artboard

* Load updated artwork in editor

* Remove popup when importing image

* Fix up demo art

* Change transform app[lication method

* Reduce number of enums called BlendMode

* Finalize the demo artwork upgrade

* Code review pass

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube
2023-11-19 23:06:21 -08:00
committed by Keavon Chambers
co-authored by Keavon Chambers
parent 719c96ecd8
commit 8a1cf3ad5d
40 changed files with 1238 additions and 477 deletions
@@ -6,11 +6,11 @@ use crate::messages::prelude::*;
use document_legacy::document::Document as DocumentLegacy;
use document_legacy::document_metadata::LayerNodeIdentifier;
use document_legacy::layers::blend_mode::BlendMode;
use document_legacy::layers::style::ViewMode;
use document_legacy::LayerId;
use document_legacy::Operation as DocumentOperation;
use graph_craft::document::NodeId;
use graphene_core::raster::BlendMode;
use graphene_core::raster::Image;
use graphene_core::Color;
use serde::{Deserialize, Serialize};
@@ -57,7 +57,7 @@ pub enum DocumentMessage {
layer_path: Vec<LayerId>,
},
CreateEmptyFolder {
container_path: Vec<LayerId>,
parent: LayerNodeIdentifier,
},
DebugPrintDocument,
DeleteLayer {
@@ -19,13 +19,12 @@ use crate::node_graph_executor::NodeGraphExecutor;
use document_legacy::document::Document as DocumentLegacy;
use document_legacy::document_metadata::LayerNodeIdentifier;
use document_legacy::layers::blend_mode::BlendMode;
use document_legacy::layers::layer_info::{LayerDataType, LayerDataTypeDiscriminant};
use document_legacy::layers::style::{RenderData, ViewMode};
use document_legacy::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeInput, NodeNetwork};
use graphene_core::raster::BlendMode;
use graphene_core::raster::ImageFrame;
use glam::{DAffine2, DVec2};
@@ -113,8 +112,8 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
document_id,
ipp,
persistent_data,
preferences,
executor,
..
} = document_inputs;
use DocumentMessage::*;
@@ -273,18 +272,16 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
responses.add(FrontendMessage::TriggerCopyToClipboardBlobUrl { blob_url });
}
}
CreateEmptyFolder { mut container_path } => {
CreateEmptyFolder { parent } => {
let id = generate_uuid();
container_path.push(id);
responses.add(DocumentMessage::DeselectAllLayers);
responses.add(DocumentOperation::CreateFolder {
path: container_path.clone(),
responses.add(GraphOperationMessage::NewCustomLayer {
id,
nodes: HashMap::new(),
parent,
insert_index: -1,
});
responses.add(DocumentMessage::SetLayerExpansion {
layer_path: container_path,
set_expanded: true,
});
}
DebugPrintDocument => {
info!("{:#?}\n{:#?}", self.document_legacy, self.layer_metadata);
@@ -430,7 +427,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
}
GroupSelectedLayers => {
// TODO: Add code that changes the insert index of the new folder based on the selected layer
let parent = self.metadata().deepest_common_ancestor(self.metadata().selected_layers());
let parent = self.metadata().deepest_common_ancestor(self.metadata().selected_layers()).unwrap_or(LayerNodeIdentifier::ROOT);
let folder_id = generate_uuid();
@@ -571,23 +568,18 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
let image_frame = ImageFrame { image, transform: DAffine2::IDENTITY };
let layer_path = self.get_path_for_new_layer();
use crate::messages::tool::common_functionality::graph_modification_utils;
graph_modification_utils::new_image_layer(image_frame, layer_path.clone(), responses);
let layer = graph_modification_utils::new_image_layer(image_frame, generate_uuid(), self.new_layer_parent(), responses);
responses.add(DocumentMessage::SetSelectedLayers {
replacement_selected_layers: vec![layer_path.clone()],
});
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![layer.to_node()] });
responses.add(GraphOperationMessage::TransformSet {
layer: layer_path.clone(),
layer: layer.to_path(),
transform,
transform_in: TransformIn::Local,
skip_rerender: false,
});
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
// Force chosen tool to be Select Tool after importing image.
responses.add(ToolMessage::ActivateTool { tool_type: ToolType::Select });
}
@@ -1420,6 +1412,12 @@ impl DocumentMessageHandler {
path
}
pub fn new_layer_parent(&self) -> LayerNodeIdentifier {
self.metadata()
.deepest_common_ancestor(self.metadata().selected_layers())
.unwrap_or_else(|| self.metadata().active_artboard())
}
/// Loads layer resources such as creating the blob URLs for the images and loading all of the fonts in the document
pub fn load_layer_resources(&self, responses: &mut VecDeque<Message>) {
let mut fonts = HashSet::new();
@@ -1702,7 +1700,7 @@ impl DocumentMessageHandler {
IconButton::new("Folder", 24)
.tooltip("New Folder")
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::CreateEmptyFolder))
.on_update(|_| DocumentMessage::CreateEmptyFolder { container_path: vec![] }.into())
.on_update(|_| DocumentMessage::CreateEmptyFolder { parent: LayerNodeIdentifier::ROOT }.into())
.widget_holder(),
IconButton::new("Trash", 24)
.tooltip("Delete Selected")
@@ -66,6 +66,8 @@ pub enum GraphOperationMessage {
NewBitmapLayer {
id: NodeId,
image_frame: ImageFrame<Color>,
parent: LayerNodeIdentifier,
insert_index: isize,
},
NewCustomLayer {
id: NodeId,
@@ -76,12 +78,16 @@ pub enum GraphOperationMessage {
NewVectorLayer {
id: NodeId,
subpaths: Vec<Subpath<ManipulatorGroupId>>,
parent: LayerNodeIdentifier,
insert_index: isize,
},
NewTextLayer {
id: NodeId,
text: String,
font: Font,
size: f64,
parent: LayerNodeIdentifier,
insert_index: isize,
},
ResizeArtboard {
id: NodeId,
@@ -92,6 +92,17 @@ impl<'a> ModifyInputsContext<'a> {
Some(new_id)
}
pub fn skip_artboards(&self, output: &mut NodeOutput) -> Option<(NodeId, usize)> {
while let NodeInput::Node { node_id, output_index, .. } = &self.network.nodes.get(&output.node_id)?.inputs[output.node_output_index] {
let sibling_node = self.network.nodes.get(node_id)?;
if sibling_node.name != "Artboard" {
return Some((*node_id, *output_index));
}
*output = NodeOutput::new(*node_id, *output_index)
}
return None;
}
pub fn create_layer(&mut self, new_id: NodeId, output_node_id: NodeId, input_index: usize, skip_layer_nodes: usize) -> Option<NodeId> {
assert!(!self.network.nodes.contains_key(&new_id), "Creating already existing layer");
@@ -99,10 +110,8 @@ impl<'a> ModifyInputsContext<'a> {
let mut sibling_layer = None;
let mut shift = IVec2::new(0, 3);
// Locate the node output of the first sibling layer to the new layer
if let NodeInput::Node { node_id, output_index, .. } = &self.network.nodes.get(&output_node_id)?.inputs[input_index] {
let sibling_node = &self.network.nodes.get(node_id)?;
let node_id = *node_id;
let output_index = *output_index;
if let Some((node_id, output_index)) = self.skip_artboards(&mut output) {
let sibling_node = self.network.nodes.get(&node_id)?;
if sibling_node.name == "Layer" {
// There is already a layer node
sibling_layer = Some(NodeOutput::new(node_id, 0));
@@ -150,6 +159,17 @@ impl<'a> ModifyInputsContext<'a> {
new_id
}
fn create_layer_with_insert_index(&mut self, new_id: NodeId, insert_index: isize, parent: LayerNodeIdentifier) -> Option<NodeId> {
let skip_layer_nodes = if insert_index < 0 { (-1 - insert_index) as usize } else { insert_index as usize };
let output_node_id = if parent == LayerNodeIdentifier::ROOT {
self.network.original_outputs()[0].node_id
} else {
parent.to_node()
};
self.create_layer(new_id, output_node_id, 0, skip_layer_nodes)
}
fn insert_artboard(&mut self, artboard: Artboard, layer: NodeId) -> Option<NodeId> {
let artboard_node = resolve_document_node_type("Artboard").expect("Node").to_document_node_default_inputs(
[
@@ -605,10 +625,16 @@ 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.metadata.load_structure(&document.document_network);
}
GraphOperationMessage::NewBitmapLayer { id, image_frame } => {
GraphOperationMessage::NewBitmapLayer {
id,
image_frame,
parent,
insert_index,
} => {
let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses);
if let Some(layer) = modify_inputs.create_layer(id, modify_inputs.network.original_outputs()[0].node_id, 0, 0) {
if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) {
modify_inputs.insert_image_data(image_frame, layer);
}
}
@@ -617,15 +643,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses);
let skip_layer_nodes = if insert_index < 0 { (-1 - insert_index) as usize } else { insert_index as usize };
let output_node_id = if parent == LayerNodeIdentifier::ROOT {
modify_inputs.network.original_outputs()[0].node_id
} else {
parent.to_node()
};
if let Some(layer) = modify_inputs.create_layer(id, output_node_id, 0, skip_layer_nodes) {
if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) {
let new_ids: HashMap<_, _> = nodes.iter().map(|(&id, _)| (id, crate::application::generate_uuid())).collect();
let shift = nodes
@@ -662,17 +680,26 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
document.metadata.load_structure(&document.document_network);
}
GraphOperationMessage::NewVectorLayer { id, subpaths } => {
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(id, modify_inputs.network.original_outputs()[0].node_id, 0, 0) {
if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) {
modify_inputs.insert_vector_data(subpaths, layer);
}
document.metadata.load_structure(&document.document_network);
}
GraphOperationMessage::NewTextLayer { id, text, font, size } => {
GraphOperationMessage::NewTextLayer {
id,
text,
font,
size,
parent,
insert_index,
} => {
let mut modify_inputs = ModifyInputsContext::new(document, node_graph, responses);
if let Some(layer) = modify_inputs.create_layer(id, modify_inputs.network.original_outputs()[0].node_id, 0, 0) {
if let Some(layer) = modify_inputs.create_layer_with_insert_index(id, insert_index, parent) {
modify_inputs.insert_text(text, font, size, layer);
}
document.metadata.load_structure(&document.document_network);
}
GraphOperationMessage::ResizeArtboard { id, location, dimensions } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_layer(&[id], document, node_graph, responses) {
@@ -689,6 +716,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
for id in artboard_nodes {
modify_inputs.delete_layer(id);
}
document.metadata.load_structure(&document.document_network);
}
}
}
@@ -242,7 +242,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
..Default::default()
}),
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Vector Data", TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
DocumentInputType::value("Name", TaggedValue::String(String::new()), false),
DocumentInputType::value("Blend Mode", TaggedValue::BlendMode(BlendMode::Normal), false),
DocumentInputType::value("Opacity", TaggedValue::F32(100.), false),