Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thumbnails for the layer node #1210

Merged
merged 10 commits into from
May 18, 2023
Merged
4 changes: 2 additions & 2 deletions document-legacy/src/layers/layer_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ impl LayerData for LayerLayer {
match &self.cached_output_data {
CachedOutputData::VectorPath(vector_data) => {
let layer_bounds = vector_data.bounding_box().unwrap_or_default();
let transfomed_bounds = vector_data.bounding_box_with_transform(transform).unwrap_or_default();
let transformed_bounds = vector_data.bounding_box_with_transform(transform).unwrap_or_default();

let _ = write!(svg, "<path d=\"");
for subpath in &vector_data.subpaths {
let _ = subpath.subpath_to_svg(svg, transform);
}
svg.push('"');

svg.push_str(&vector_data.style.render(render_data.view_mode, svg_defs, transform, layer_bounds, transfomed_bounds));
svg.push_str(&vector_data.style.render(render_data.view_mode, svg_defs, transform, layer_bounds, transformed_bounds));
let _ = write!(svg, "/>");
}
CachedOutputData::BlobURL(blob_url) => {
Expand Down
2 changes: 2 additions & 0 deletions editor/src/messages/frontend/utility_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub struct FrontendImageData {
#[serde(skip)]
pub image_data: std::sync::Arc<Vec<u8>>,
pub transform: Option<[f64; 6]>,
#[serde(rename = "nodeId")]
pub node_id: Option<graph_craft::document::NodeId>,
}

#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, specta::Type)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
}
#[remain::unsorted]
NodeGraph(message) => {
let selected_layers = &mut self.layer_metadata.iter().filter_map(|(path, data)| data.selected.then_some(path.as_slice()));
self.node_graph_handler.process_message(message, responses, (&mut self.document_legacy, selected_layers));
self.node_graph_handler.process_message(message, responses, (&mut self.document_legacy, executor));
}
#[remain::unsorted]
GraphOperation(message) => GraphOperationMessageHandler.process_message(message, responses, (&mut self.document_legacy, &mut self.node_graph_handler)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::layout::utility_types::layout_widget::{Layout, LayoutGroup, Widget, WidgetCallback, WidgetHolder, WidgetLayout};
use crate::messages::layout::utility_types::widgets::button_widgets::TextButton;
use crate::messages::prelude::*;
use crate::node_graph_executor::NodeGraphExecutor;

use document_legacy::document::Document;
use document_legacy::layers::layer_layer::LayerLayer;
Expand Down Expand Up @@ -84,6 +85,8 @@ pub struct FrontendNode {
pub position: (i32, i32),
pub disabled: bool,
pub previewed: bool,
#[serde(rename = "thumbnailSvg")]
pub thumbnail_svg: Option<String>,
}

// (link_start, link_end, link_end_input_index)
Expand Down Expand Up @@ -254,9 +257,11 @@ impl NodeGraphMessageHandler {
}
}

fn send_graph(network: &NodeNetwork, responses: &mut VecDeque<Message>) {
fn send_graph(network: &NodeNetwork, executor: &NodeGraphExecutor, layer_path: &Option<Vec<LayerId>>, responses: &mut VecDeque<Message>) {
responses.add(PropertiesPanelMessage::ResendActiveProperties);

let layer_id = layer_path.as_ref().and_then(|path| path.last().copied());

// List of links in format (link_start, link_end, link_end_input_index)
let links = network
.nodes
Expand Down Expand Up @@ -288,37 +293,49 @@ impl NodeGraphMessageHandler {
warn!("Node '{}' does not exist in library", node.name);
continue;
};

let primary_input = node
.inputs
.first()
.filter(|input| input.is_exposed())
.and_then(|_| node_type.inputs.get(0))
.map(|input_type| input_type.data_type);
let exposed_inputs = node
.inputs
.iter()
.zip(node_type.inputs.iter())
.skip(1)
.filter(|(input, _)| input.is_exposed())
.map(|(_, input_type)| NodeGraphInput {
data_type: input_type.data_type,
name: input_type.name.to_string(),
})
.collect();

let outputs = node_type
.outputs
.iter()
.map(|output_type| NodeGraphOutput {
data_type: output_type.data_type,
name: output_type.name.to_string(),
})
.collect();

let thumbnail_svg = layer_id
.and_then(|layer_id| executor.thumbnails.get(&layer_id))
.and_then(|layer| layer.get(id))
.map(|svg| svg.to_string());

nodes.push(FrontendNode {
id: *id,
display_name: node.name.clone(),
primary_input: node
.inputs
.first()
.filter(|input| input.is_exposed())
.and_then(|_| node_type.inputs.get(0))
.map(|input_type| input_type.data_type),
exposed_inputs: node
.inputs
.iter()
.zip(node_type.inputs.iter())
.skip(1)
.filter(|(input, _)| input.is_exposed())
.map(|(_, input_type)| NodeGraphInput {
data_type: input_type.data_type,
name: input_type.name.to_string(),
})
.collect(),
outputs: node_type
.outputs
.iter()
.map(|output_type| NodeGraphOutput {
data_type: output_type.data_type,
name: output_type.name.to_string(),
})
.collect(),
primary_input,
exposed_inputs,
outputs,
position: node.metadata.position.into(),
previewed: network.outputs_contain(*id),
disabled: network.disabled.contains(id),
thumbnail_svg,
})
}
responses.add(FrontendMessage::UpdateNodeGraph { nodes, links });
Expand Down Expand Up @@ -405,9 +422,9 @@ impl NodeGraphMessageHandler {
}
}

impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &[LayerId]>)> for NodeGraphMessageHandler {
impl MessageHandler<NodeGraphMessage, (&mut Document, &NodeGraphExecutor)> for NodeGraphMessageHandler {
#[remain::check]
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, (document, _selected): (&mut Document, &mut dyn Iterator<Item = &[LayerId]>)) {
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, (document, executor): (&mut Document, &NodeGraphExecutor)) {
#[remain::sorted]
match message {
NodeGraphMessage::CloseNodeGraph => {
Expand Down Expand Up @@ -536,7 +553,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
}
}
if let Some(network) = self.get_active_network(document) {
Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);
}
self.collect_nested_addresses(document, responses);
self.update_selected(document, responses);
Expand All @@ -561,7 +578,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
responses.add(NodeGraphMessage::InsertNode { node_id, document_node });
}

Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);
self.update_selected(document, responses);
}
}
Expand All @@ -571,7 +588,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
self.nested_path.pop();
}
if let Some(network) = self.get_active_network(document) {
Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);
}
self.collect_nested_addresses(document, responses);
self.update_selected(document, responses);
Expand Down Expand Up @@ -622,15 +639,15 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
node.metadata.position += IVec2::new(displacement_x, displacement_y)
}
}
Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);
}
NodeGraphMessage::OpenNodeGraph { layer_path } => {
self.layer_path = Some(layer_path);

if let Some(network) = self.get_active_network(document) {
self.selected_nodes.clear();

Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);

let node_types = document_node_types::collect_node_types();
responses.add(FrontendMessage::UpdateNodeTypes { node_types });
Expand Down Expand Up @@ -689,7 +706,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
}
NodeGraphMessage::SendGraph { should_rerender } => {
if let Some(network) = self.get_active_network(document) {
Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);
if should_rerender {
if let Some(layer_path) = self.layer_path.clone() {
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
Expand Down Expand Up @@ -816,7 +833,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
.disabled
.extend(self.selected_nodes.iter().filter(|&id| !network.inputs.contains(id) && !original_outputs.contains(id)));
}
Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);

// Only generate node graph if one of the selected nodes is connected to the output
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
Expand All @@ -842,7 +859,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
} else {
return;
}
Self::send_graph(network, responses);
Self::send_graph(network, executor, &self.layer_path, responses);
}
self.update_selection_action_buttons(document, responses);
if let Some(layer_path) = self.layer_path.clone() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,40 @@ fn static_nodes() -> Vec<DocumentNodeType> {
DocumentNodeType {
name: "Layer",
category: "General",
identifier: NodeImplementation::proto("graphene_core::ConstructLayerNode<_, _, _, _, _, _, _>"),
identifier: NodeImplementation::DocumentNode(NodeNetwork {
inputs: vec![0; 8],
outputs: vec![NodeOutput::new(1, 0)],
nodes: [
(
0,
DocumentNode {
inputs: vec![
NodeInput::Network(concrete!(graphene_core::vector::VectorData)),
NodeInput::Network(concrete!(String)),
NodeInput::Network(concrete!(BlendMode)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(graphene_core::GraphicGroup)),
],
implementation: DocumentNodeImplementation::proto("graphene_core::ConstructLayerNode<_, _, _, _, _, _, _>"),
..Default::default()
},
),
// The monitor node is used to display a thumbnail in the UI.
(
1,
DocumentNode {
inputs: vec![NodeInput::node(0, 0)],
implementation: DocumentNodeImplementation::proto("graphene_std::memo::MonitorNode<_>"),
..Default::default()
},
),
]
.into(),
..Default::default()
}),
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Name", TaggedValue::String(String::new()), false),
Expand Down Expand Up @@ -528,7 +561,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
identifier: NodeImplementation::DocumentNode(NodeNetwork {
inputs: vec![0],
outputs: vec![NodeOutput::new(1, 0)],
nodes: vec![
nodes: [
(
0,
DocumentNode {
Expand All @@ -548,8 +581,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
},
),
]
.into_iter()
.collect(),
.into(),
..Default::default()
}),
inputs: vec![DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true)],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -727,12 +727,12 @@ pub fn adjust_selective_color_properties(document_node: &DocumentNode, node_id:
} = &document_node.inputs[colors_index]
{
use SelectiveColorChoice::*;
let entries = [vec![Reds, Yellows, Greens, Cyans, Blues, Magentas], vec![Whites, Neutrals, Blacks]]
let entries = [[Reds, Yellows, Greens, Cyans, Blues, Magentas].as_slice(), [Whites, Neutrals, Blacks].as_slice()]
.into_iter()
.map(|section| {
section
.into_iter()
.map(|choice| DropdownEntryData::new(choice.to_string()).on_update(update_value(move |_| TaggedValue::SelectiveColorChoice(choice), node_id, colors_index)))
.map(|choice| DropdownEntryData::new(choice.to_string()).on_update(update_value(move |_| TaggedValue::SelectiveColorChoice(*choice), node_id, colors_index)))
.collect()
})
.collect();
Expand Down
1 change: 1 addition & 0 deletions editor/src/messages/portfolio/portfolio_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ pub enum PortfolioMessage {
SetImageBlobUrl {
document_id: u64,
layer_path: Vec<LayerId>,
node_id: Option<NodeId>,
blob_url: String,
resolution: (f64, f64),
},
Expand Down
6 changes: 6 additions & 0 deletions editor/src/messages/portfolio/portfolio_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,9 +503,15 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
PortfolioMessage::SetImageBlobUrl {
document_id,
layer_path,
node_id,
blob_url,
resolution,
} => {
if let (Some(layer_id), Some(node_id)) = (layer_path.last().copied(), node_id) {
self.executor.insert_thumbnail_blob_url(blob_url, layer_id, node_id, responses);
return;
}

let message = DocumentMessage::SetImageBlobUrl {
layer_path,
blob_url,
Expand Down
Loading