mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 05:18:19 +00:00
Remove artboard from graphic element (#1824)
* Remove artboard from graphic element * Fix transform bug
This commit is contained in:
parent
027d3f4e60
commit
0c2e3361ab
4 changed files with 51 additions and 72 deletions
|
@ -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::<IORecord<Footprint, graphene_core::GraphicElement>>()
|
||||
.map(|io_data| IntrospectedData::GraphicElement(&io_data.output))
|
||||
.or_else(|| {
|
||||
introspected_data
|
||||
.downcast_ref::<IORecord<Footprint, graphene_core::Artboard>>()
|
||||
.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 <svg>...</svg> 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::<IORecord<Footprint, graphene_core::GraphicElement>>() {
|
||||
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::<IORecord<Footprint, graphene_core::Artboard>>() {
|
||||
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::<IORecord<Footprint, VectorData>>() {
|
||||
// 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<NodeId, Vec<SvgSegment>>,
|
||||
click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>,
|
||||
parent_network_node_id: NodeId,
|
||||
graphic_element: &impl GraphicElementRendered,
|
||||
responses: &mut VecDeque<FrontendMessage>,
|
||||
) {
|
||||
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 <svg>...</svg> 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<Arc<dyn std::any::Any>> {
|
||||
|
|
|
@ -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<Stack, GraphicElement> {
|
||||
|
@ -240,11 +231,6 @@ impl From<GraphicGroup> for GraphicElement {
|
|||
GraphicElement::GraphicGroup(graphic_group)
|
||||
}
|
||||
}
|
||||
impl From<Artboard> for GraphicElement {
|
||||
fn from(artboard: Artboard) -> Self {
|
||||
GraphicElement::Artboard(artboard)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for GraphicGroup {
|
||||
type Target = Vec<GraphicElement>;
|
||||
|
@ -265,7 +251,6 @@ trait ToGraphicElement: Into<GraphicElement> {}
|
|||
|
||||
impl ToGraphicElement for VectorData {}
|
||||
impl ToGraphicElement for ImageFrame<Color> {}
|
||||
impl ToGraphicElement for Artboard {}
|
||||
|
||||
impl<T> From<T> for GraphicGroup
|
||||
where
|
||||
|
|
|
@ -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<ClickTarget>) {
|
||||
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 {
|
||||
|
|
|
@ -289,7 +289,6 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
async_node!(graphene_core::ops::IntoNode<_, GraphicGroup>, input: ImageFrame<Color>, 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<Color>, params: [ImageFrame<Color>]),
|
||||
|
@ -753,11 +752,9 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
register_node!(graphene_core::ToGraphicElementNode, input: graphene_core::vector::VectorData, params: []),
|
||||
register_node!(graphene_core::ToGraphicElementNode, input: ImageFrame<Color>, 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<Color>, 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]),
|
||||
];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue