From 0c2e3361ab21b1a339a8fb7eb73d2c1fde7e8ef1 Mon Sep 17 00:00:00 2001 From: James Lindsay <78500760+0HyperCube@users.noreply.github.com> Date: Sun, 14 Jul 2024 05:10:29 +0100 Subject: [PATCH] Remove artboard from graphic element (#1824) * Remove artboard from graphic element * Fix transform bug --- editor/src/node_graph_executor.rs | 95 +++++++++---------- node-graph/gcore/src/graphic_element.rs | 15 --- .../gcore/src/graphic_element/renderer.rs | 10 +- .../interpreted-executor/src/node_registry.rs | 3 - 4 files changed, 51 insertions(+), 72 deletions(-) diff --git a/editor/src/node_graph_executor.rs b/editor/src/node_graph_executor.rs index a9251fe3..655ad95d 100644 --- a/editor/src/node_graph_executor.rs +++ b/editor/src/node_graph_executor.rs @@ -301,57 +301,10 @@ impl NodeRuntime { continue; }; - enum IntrospectedData<'a> { - GraphicElement(&'a graphene_core::GraphicElement), - Artboard(&'a graphene_core::Artboard), - } - - let introspected_data_output = introspected_data - .downcast_ref::>() - .map(|io_data| IntrospectedData::GraphicElement(&io_data.output)) - .or_else(|| { - introspected_data - .downcast_ref::>() - .map(|io_data| IntrospectedData::Artboard(&io_data.output)) - }); - - let graphic_element = match introspected_data_output { - Some(IntrospectedData::GraphicElement(graphic_element)) => Some(graphic_element.clone()), - Some(IntrospectedData::Artboard(artboard)) => Some(artboard.clone().into()), - _ => None, - }; - // If this is `GraphicElement` data: - // Regenerate click targets and thumbnails for the layers in the graph, modifying the state and updating the UI. - if let Some(graphic_element) = graphic_element { - let click_targets = self.click_targets.entry(parent_network_node_id).or_default(); - click_targets.clear(); - graphic_element.add_click_targets(click_targets); - - // RENDER THUMBNAIL - - let bounds = graphic_element.bounding_box(DAffine2::IDENTITY); - - // Render the thumbnail from a `GraphicElement` into an SVG string - let render_params = RenderParams::new(ViewMode::Normal, ImageRenderMode::Base64, bounds, true, false, false); - let mut render = SvgRender::new(); - graphic_element.render_svg(&mut render, &render_params); - - // And give the SVG a viewbox and outer ... wrapper tag - let [min, max] = bounds.unwrap_or_default(); - render.format_svg(min, max); - - // UPDATE FRONTEND THUMBNAIL - - let new_thumbnail_svg = render.svg; - let old_thumbnail_svg = self.thumbnail_renders.entry(parent_network_node_id).or_default(); - - if old_thumbnail_svg != &new_thumbnail_svg { - responses.push_back(FrontendMessage::UpdateNodeThumbnail { - id: parent_network_node_id, - value: new_thumbnail_svg.to_svg_string(), - }); - *old_thumbnail_svg = new_thumbnail_svg; - } + if let Some(io) = introspected_data.downcast_ref::>() { + Self::process_graphic_element(&mut self.thumbnail_renders, &mut self.click_targets, parent_network_node_id, &io.output, responses) + } else if let Some(io) = introspected_data.downcast_ref::>() { + Self::process_graphic_element(&mut self.thumbnail_renders, &mut self.click_targets, parent_network_node_id, &io.output, responses) } else if let Some(record) = introspected_data.downcast_ref::>() { // Insert the vector modify if we are dealing with vector data self.vector_modify.insert(parent_network_node_id, record.output.clone()); @@ -374,6 +327,46 @@ impl NodeRuntime { } } } + + // If this is `GraphicElement` data: + // Regenerate click targets and thumbnails for the layers in the graph, modifying the state and updating the UI. + fn process_graphic_element( + thumbnail_renders: &mut HashMap>, + click_targets: &mut HashMap>, + parent_network_node_id: NodeId, + graphic_element: &impl GraphicElementRendered, + responses: &mut VecDeque, + ) { + let click_targets = click_targets.entry(parent_network_node_id).or_default(); + click_targets.clear(); + graphic_element.add_click_targets(click_targets); + + // RENDER THUMBNAIL + + let bounds = graphic_element.bounding_box(DAffine2::IDENTITY); + + // Render the thumbnail from a `GraphicElement` into an SVG string + let render_params = RenderParams::new(ViewMode::Normal, ImageRenderMode::Base64, bounds, true, false, false); + let mut render = SvgRender::new(); + graphic_element.render_svg(&mut render, &render_params); + + // And give the SVG a viewbox and outer ... wrapper tag + let [min, max] = bounds.unwrap_or_default(); + render.format_svg(min, max); + + // UPDATE FRONTEND THUMBNAIL + + let new_thumbnail_svg = render.svg; + let old_thumbnail_svg = thumbnail_renders.entry(parent_network_node_id).or_default(); + + if old_thumbnail_svg != &new_thumbnail_svg { + responses.push_back(FrontendMessage::UpdateNodeThumbnail { + id: parent_network_node_id, + value: new_thumbnail_svg.to_svg_string(), + }); + *old_thumbnail_svg = new_thumbnail_svg; + } + } } pub fn introspect_node(path: &[NodeId]) -> Option> { diff --git a/node-graph/gcore/src/graphic_element.rs b/node-graph/gcore/src/graphic_element.rs index 62aa203a..0b04dafa 100644 --- a/node-graph/gcore/src/graphic_element.rs +++ b/node-graph/gcore/src/graphic_element.rs @@ -121,15 +121,6 @@ impl ArtboardGroup { fn add_artboard(&mut self, artboard: Artboard) { self.artboards.push(artboard); } - - pub fn get_graphic_group(&self) -> GraphicGroup { - let mut graphic_group = GraphicGroup::EMPTY; - for artboard in self.artboards.clone() { - let graphic_element: GraphicElement = artboard.into(); - graphic_group.push(graphic_element); - } - graphic_group - } } pub struct ConstructLayerNode { @@ -240,11 +231,6 @@ impl From for GraphicElement { GraphicElement::GraphicGroup(graphic_group) } } -impl From for GraphicElement { - fn from(artboard: Artboard) -> Self { - GraphicElement::Artboard(artboard) - } -} impl Deref for GraphicGroup { type Target = Vec; @@ -265,7 +251,6 @@ trait ToGraphicElement: Into {} impl ToGraphicElement for VectorData {} impl ToGraphicElement for ImageFrame {} -impl ToGraphicElement for Artboard {} impl From for GraphicGroup where diff --git a/node-graph/gcore/src/graphic_element/renderer.rs b/node-graph/gcore/src/graphic_element/renderer.rs index 43c83418..7540bb23 100644 --- a/node-graph/gcore/src/graphic_element/renderer.rs +++ b/node-graph/gcore/src/graphic_element/renderer.rs @@ -469,15 +469,19 @@ impl GraphicElementRendered for Artboard { impl GraphicElementRendered for crate::ArtboardGroup { fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) { - self.get_graphic_group().render_svg(render, render_params); + for artboard in &self.artboards { + artboard.render_svg(render, render_params); + } } fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]> { - self.get_graphic_group().bounding_box(transform) + self.artboards.iter().filter_map(|element| element.bounding_box(transform)).reduce(Quad::combine_bounds) } fn add_click_targets(&self, click_targets: &mut Vec) { - self.get_graphic_group().add_click_targets(click_targets); + for artboard in &self.artboards { + artboard.add_click_targets(click_targets); + } } fn contains_artboard(&self) -> bool { diff --git a/node-graph/interpreted-executor/src/node_registry.rs b/node-graph/interpreted-executor/src/node_registry.rs index c5e3206b..a5901e05 100644 --- a/node-graph/interpreted-executor/src/node_registry.rs +++ b/node-graph/interpreted-executor/src/node_registry.rs @@ -289,7 +289,6 @@ fn node_registry() -> HashMap, input: ImageFrame, output: GraphicGroup, params: []), async_node!(graphene_core::ops::IntoNode<_, GraphicGroup>, input: VectorData, output: GraphicGroup, params: []), async_node!(graphene_core::ops::IntoNode<_, GraphicGroup>, input: GraphicGroup, output: GraphicGroup, params: []), - async_node!(graphene_core::ops::IntoNode<_, GraphicGroup>, input: Artboard, output: GraphicGroup, params: []), #[cfg(feature = "gpu")] async_node!(graphene_core::ops::IntoNode<_, &WgpuExecutor>, input: &WasmEditorApi, output: &WgpuExecutor, params: []), register_node!(graphene_std::raster::MaskImageNode<_, _, _>, input: ImageFrame, params: [ImageFrame]), @@ -753,11 +752,9 @@ fn node_registry() -> HashMap, params: []), register_node!(graphene_core::ToGraphicElementNode, input: GraphicGroup, params: []), - register_node!(graphene_core::ToGraphicElementNode, input: Artboard, params: []), register_node!(graphene_core::ToGraphicGroupNode, input: graphene_core::vector::VectorData, params: []), register_node!(graphene_core::ToGraphicGroupNode, input: ImageFrame, params: []), register_node!(graphene_core::ToGraphicGroupNode, input: GraphicGroup, params: []), - register_node!(graphene_core::ToGraphicGroupNode, input: Artboard, params: []), async_node!(graphene_core::ConstructArtboardNode<_, _, _, _, _, _>, input: Footprint, output: Artboard, fn_params: [Footprint => GraphicGroup, () => String, () => glam::IVec2, () => glam::IVec2, () => Color, () => bool]), async_node!(graphene_core::AddArtboardNode<_, _>, input: Footprint, output: ArtboardGroup, fn_params: [Footprint => ArtboardGroup, Footprint => Artboard]), ];