Replace Table<Table<Graphic>> with Table<Artboard> where Artboard is a type boundary newtype (#4093)

Replace Table<Table<Graphic>> with Table<Artboard> with Artboard as a type boundary newtype
This commit is contained in:
Keavon Chambers
2026-05-01 21:57:50 -07:00
committed by GitHub
parent 9943af5248
commit a0d5f418d9
16 changed files with 134 additions and 86 deletions

View File

@@ -6,9 +6,6 @@ use crate::messages::prelude::*;
use crate::messages::tool::tool_messages::tool_prelude::*;
use glam::{Affine2, DAffine2, Vec2};
use graph_craft::document::NodeId;
use graphene_std::Color;
use graphene_std::Context;
use graphene_std::Graphic;
use graphene_std::blending::BlendMode;
use graphene_std::gradient::GradientStops;
use graphene_std::memo::IORecord;
@@ -16,6 +13,7 @@ use graphene_std::raster_types::{CPU, GPU, Raster};
use graphene_std::table::Table;
use graphene_std::vector::Vector;
use graphene_std::vector::style::{Fill, FillChoice};
use graphene_std::{Artboard, Color, Context, Graphic};
use std::any::Any;
use std::sync::Arc;
@@ -183,7 +181,7 @@ fn generate_layout(introspected_data: &Arc<dyn std::any::Any + Send + Sync + 'st
return Some(table_node_id_path_layout_with_breadcrumb(&io.output, data));
}
generate_layout_downcast!(introspected_data, data, [
Table<Table<Graphic>>,
Table<Artboard>,
Table<Graphic>,
Table<Vector>,
Table<Raster<CPU>>,
@@ -301,6 +299,22 @@ impl<T: TableRowLayout> TableRowLayout for Table<T> {
}
}
impl TableRowLayout for Artboard {
fn type_name() -> &'static str {
"Artboard"
}
fn identifier(&self) -> String {
self.as_graphic_table().identifier()
}
// Don't put a breadcrumb for Artboard
fn layout_with_breadcrumb(&self, data: &mut LayoutData) -> Vec<LayoutGroup> {
self.value_page(data)
}
fn value_page(&self, data: &mut LayoutData) -> Vec<LayoutGroup> {
self.as_graphic_table().layout_with_breadcrumb(data)
}
}
impl TableRowLayout for Graphic {
fn type_name() -> &'static str {
"Graphic"
@@ -871,7 +885,7 @@ impl TableRowLayout for NodeId {
macro_rules! known_table_row_types {
($apply:ident) => {
$apply!(
Table<Table<Graphic>>,
Table<Artboard>,
Table<Graphic>,
Table<Vector>,
Table<Raster<CPU>>,
@@ -900,6 +914,7 @@ macro_rules! known_table_row_types {
Raster<CPU>,
Raster<GPU>,
Graphic,
Artboard,
);
};
}

View File

@@ -394,7 +394,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
},
DocumentNode {
inputs: vec![
NodeInput::import(graphene_std::Type::Fn(Box::new(concrete!(Context)), Box::new(concrete!(Table<Table<Graphic>>))), 0),
NodeInput::import(graphene_std::Type::Fn(Box::new(concrete!(Context)), Box::new(concrete!(Table<Artboard>))), 0),
NodeInput::node(NodeId(3), 0),
],
implementation: DocumentNodeImplementation::ProtoNode(graphic::extend::IDENTIFIER),

View File

@@ -611,18 +611,15 @@ impl Fsm for ArtboardToolFsmState {
#[cfg(test)]
mod test_artboard {
pub use crate::test_utils::test_prelude::*;
use graphene_std::Graphic;
use graphene_std::Artboard;
use graphene_std::table::Table;
async fn get_artboards(editor: &mut EditorTestUtils) -> Table<Table<Graphic>> {
async fn get_artboards(editor: &mut EditorTestUtils) -> Table<Artboard> {
let instrumented = match editor.eval_graph().await {
Ok(instrumented) => instrumented,
Err(e) => panic!("Failed to evaluate graph: {e}"),
};
instrumented
.grab_all_input::<graphene_std::graphic::extend::NewInput<Table<graphene_std::Graphic>>>(&editor.runtime)
.flatten()
.collect()
instrumented.grab_all_input::<graphene_std::graphic::extend::NewInput<Artboard>>(&editor.runtime).flatten().collect()
}
#[derive(Debug, PartialEq)]

View File

@@ -20,7 +20,7 @@ use graphene_std::text::FontCache;
use graphene_std::transform::RenderQuality;
use graphene_std::vector::Vector;
use graphene_std::vector::style::RenderMode;
use graphene_std::{Context, Graphic};
use graphene_std::{Artboard, Context, Graphic};
use interpreted_executor::dynamic_executor::{DynamicExecutor, IntrospectError, ResolvedDocumentNodeTypesDelta};
use interpreted_executor::util::wrap_network_in_scope;
use spin::Mutex;
@@ -441,7 +441,7 @@ impl NodeRuntime {
}
// Artboard thumbnail bounds come from the clipping rectangles, not the content union, since the renderer
// clips content to those rectangles so anything outside isn't visible
else if let Some(io) = introspected_data.downcast_ref::<IORecord<Context, Table<Table<Graphic>>>>() {
else if let Some(io) = introspected_data.downcast_ref::<IORecord<Context, Table<Artboard>>>() {
if update_thumbnails {
let bounds = artboard_clip_bounds(&io.output);
Self::render_thumbnail(&mut self.thumbnail_renders, parent_network_node_id, &io.output, bounds, responses)
@@ -522,7 +522,7 @@ impl NodeRuntime {
/// Returns the union of the artboards' clipping rectangles, used as the thumbnail bounds for an artboard layer so the
/// framing matches what's actually visible after clipping rather than the unclipped content extents.
fn artboard_clip_bounds(artboards: &Table<Table<Graphic>>) -> RenderBoundingBox {
fn artboard_clip_bounds(artboards: &Table<Artboard>) -> RenderBoundingBox {
let mut combined: Option<[DVec2; 2]> = None;
for index in 0..artboards.len() {
let location: DVec2 = artboards.attribute_cloned_or_default(graphene_std::ATTR_LOCATION, index);