Rename the Group type to Graphic everywhere (#3009)

This commit is contained in:
Keavon Chambers
2025-08-05 20:55:15 -07:00
committed by GitHub
parent 309a64340b
commit 0f638314dc
44 changed files with 267 additions and 277 deletions

View File

@@ -111,19 +111,19 @@ impl LayoutHolder for ExportDialogMessageHandler {
(ExportBounds::Selection, "Selection".to_string(), !self.has_selection),
];
let artboards = self.artboards.iter().map(|(&layer, name)| (ExportBounds::Artboard(layer), name.to_string(), false)).collect();
let groups = [standard_bounds, artboards];
let choices = [standard_bounds, artboards];
let current_bounds = if !self.has_selection && self.bounds == ExportBounds::Selection {
ExportBounds::AllArtwork
} else {
self.bounds
};
let index = groups.iter().flatten().position(|(bounds, _, _)| *bounds == current_bounds).unwrap();
let index = choices.iter().flatten().position(|(bounds, _, _)| *bounds == current_bounds).unwrap();
let mut entries = groups
let mut entries = choices
.into_iter()
.map(|group| {
group
.map(|choice| {
choice
.into_iter()
.map(|(val, name, disabled)| {
MenuListEntry::new(format!("{val:?}"))

View File

@@ -59,8 +59,8 @@ impl LayoutMessageHandler {
/// Get the widget path for the widget with the specified id
fn get_widget_path(widget_layout: &WidgetLayout, widget_id: WidgetId) -> Option<(&WidgetHolder, Vec<usize>)> {
let mut stack = widget_layout.layout.iter().enumerate().map(|(index, val)| (vec![index], val)).collect::<Vec<_>>();
while let Some((mut widget_path, group)) = stack.pop() {
match group {
while let Some((mut widget_path, layout_group)) = stack.pop() {
match layout_group {
// Check if any of the widgets in the current column or row have the correct id
LayoutGroup::Column { widgets } | LayoutGroup::Row { widgets } => {
for (index, widget) in widgets.iter().enumerate() {

View File

@@ -653,7 +653,7 @@ impl DiffUpdate {
};
match self {
Self::SubLayout(sub_layout) => sub_layout.iter_mut().flat_map(|group| group.iter_mut()).for_each(convert_tooltip),
Self::SubLayout(sub_layout) => sub_layout.iter_mut().flat_map(|layout_group| layout_group.iter_mut()).for_each(convert_tooltip),
Self::LayoutGroup(layout_group) => layout_group.iter_mut().for_each(convert_tooltip),
Self::Widget(widget_holder) => convert_tooltip(widget_holder),
}

View File

@@ -132,7 +132,7 @@ impl<'a> ModifyInputsContext<'a> {
pub fn create_artboard(&mut self, new_id: NodeId, artboard: Artboard) -> LayerNodeIdentifier {
let artboard_node_template = resolve_document_node_type("Artboard").expect("Node").node_template_input_override([
Some(NodeInput::value(TaggedValue::Artboard(Default::default()), true)),
Some(NodeInput::value(TaggedValue::Group(Default::default()), true)),
Some(NodeInput::value(TaggedValue::Graphic(Default::default()), true)),
Some(NodeInput::value(TaggedValue::DVec2(artboard.location.into()), false)),
Some(NodeInput::value(TaggedValue::DVec2(artboard.dimensions.into()), false)),
Some(NodeInput::value(TaggedValue::Color(artboard.background), false)),
@@ -144,7 +144,7 @@ impl<'a> ModifyInputsContext<'a> {
pub fn insert_boolean_data(&mut self, operation: graphene_std::path_bool::BooleanOperation, layer: LayerNodeIdentifier) {
let boolean = resolve_document_node_type("Boolean Operation").expect("Boolean node does not exist").node_template_input_override([
Some(NodeInput::value(TaggedValue::Group(Default::default()), true)),
Some(NodeInput::value(TaggedValue::Graphic(Default::default()), true)),
Some(NodeInput::value(TaggedValue::BooleanOperation(operation), false)),
]);
@@ -263,7 +263,7 @@ impl<'a> ModifyInputsContext<'a> {
}
/// Gets the node id of a node with a specific reference (name) that is upstream (leftward) from the layer node, but before reaching another upstream layer stack.
/// For example, if given a group layer, this would find a requested "Transform" or "Boolean Operation" node in its chain, between the group layer and its layer stack child contents.
/// For example, if given a parent layer, this would find a requested "Transform" or "Boolean Operation" node in its chain, between the parent layer and its layer stack child contents.
/// It would also travel up an entire layer that's not fed by a stack until reaching the generator node, such as a "Rectangle" or "Path" layer.
pub fn locate_node_in_layer_chain(reference_name: &str, left_of_layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
let upstream = network_interface.upstream_flow_back_from_nodes(vec![left_of_layer.to_node()], &[], network_interface::FlowType::HorizontalFlow);
@@ -300,8 +300,8 @@ impl<'a> ModifyInputsContext<'a> {
return None;
};
// If inserting a path node, insert a Flatten Path if the type is Group.
// TODO: Allow the path node to operate on Group data by utilizing the reference for each Vector in a group.
// If inserting a 'Path' node, insert a 'Flatten Path' node if the type is `Graphic`.
// TODO: Allow the 'Path' node to operate on table data by utilizing the reference (index or ID?) for each row.
if node_definition.identifier == "Path" {
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]).0.nested_type().clone();
if layer_input_type == concrete!(Table<Graphic>) {

View File

@@ -86,7 +86,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
let custom = vec![
// TODO: Auto-generate this from its proto node macro
DocumentNodeDefinition {
identifier: "Identity",
identifier: "Passthrough",
category: "General",
node_template: NodeTemplate {
document_node: DocumentNode {
@@ -95,13 +95,13 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
input_metadata: vec![("In", "TODO").into()],
input_metadata: vec![("Content", "TODO").into()],
output_names: vec!["Out".to_string()],
..Default::default()
},
},
description: Cow::Borrowed("Passes-through the input value without changing it. This is useful for rerouting wires for organization purposes."),
properties: Some("identity_properties"),
description: Cow::Borrowed("Returns the input value without changing it. This is useful for rerouting wires for organization purposes."),
properties: None,
},
// TODO: Auto-generate this from its proto node macro
DocumentNodeDefinition {
@@ -272,8 +272,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
}),
inputs: vec![
NodeInput::value(TaggedValue::Group(Default::default()), true),
NodeInput::value(TaggedValue::Group(Default::default()), true),
NodeInput::value(TaggedValue::Graphic(Default::default()), true),
NodeInput::value(TaggedValue::Graphic(Default::default()), true),
],
..Default::default()
},
@@ -336,7 +336,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
},
},
description: Cow::Borrowed("Merge attaches a layer to the stack's group."),
description: Cow::Borrowed("Merges new content as an entry into the graphic table that represents a layer compositing stack."),
properties: None,
},
DocumentNodeDefinition {
@@ -396,7 +396,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
}),
inputs: vec![
NodeInput::value(TaggedValue::Artboard(Default::default()), true),
NodeInput::value(TaggedValue::Group(Default::default()), true),
NodeInput::value(TaggedValue::Graphic(Default::default()), true),
NodeInput::value(TaggedValue::DVec2(DVec2::ZERO), false),
NodeInput::value(TaggedValue::DVec2(DVec2::new(1920., 1080.)), false),
NodeInput::value(TaggedValue::Color(Color::WHITE), false),
@@ -1553,7 +1553,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
}),
inputs: vec![
NodeInput::value(TaggedValue::Group(Default::default()), true),
NodeInput::value(TaggedValue::Graphic(Default::default()), true),
NodeInput::value(TaggedValue::BooleanOperation(path_bool::BooleanOperation::Union), false),
],
..Default::default()
@@ -1603,7 +1603,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
},
..Default::default()
}),
input_metadata: vec![("Group of Paths", "TODO").into(), ("Operation", "TODO").into()],
input_metadata: vec![("Content", "TODO").into(), ("Operation", "TODO").into()],
output_names: vec!["Vector".to_string()],
..Default::default()
},
@@ -1925,13 +1925,9 @@ fn static_node_properties() -> NodeProperties {
map.insert("rectangle_properties".to_string(), Box::new(node_properties::rectangle_properties));
map.insert("grid_properties".to_string(), Box::new(node_properties::grid_properties));
map.insert("sample_polyline_properties".to_string(), Box::new(node_properties::sample_polyline_properties));
map.insert(
"identity_properties".to_string(),
Box::new(|_node_id, _context| node_properties::string_properties("The identity node passes its data through.")),
);
map.insert(
"monitor_properties".to_string(),
Box::new(|_node_id, _context| node_properties::string_properties("The Monitor node is used by the editor to access the data flowing through it.")),
Box::new(|_node_id, _context| node_properties::string_properties("Used internally by the editor to obtain a layer thumbnail.")),
);
map
}

View File

@@ -1959,8 +1959,8 @@ pub mod choice {
{
let items = E::list()
.iter()
.map(|group| {
group
.map(|section| {
section
.iter()
.map(|(item, metadata)| {
let updater = updater_factory();
@@ -1980,7 +1980,7 @@ pub mod choice {
{
let items = E::list()
.iter()
.flat_map(|group| group.iter())
.flat_map(|section| section.iter())
.map(|(item, var_meta)| {
let updater = updater_factory();
let committer = committer_factory();

View File

@@ -11,7 +11,7 @@ pub enum FrontendGraphDataType {
Raster,
Vector,
Number,
Group,
Graphic,
Artboard,
}
@@ -28,7 +28,7 @@ impl FrontendGraphDataType {
| TaggedValue::VecF64(_)
| TaggedValue::VecDVec2(_)
| TaggedValue::DAffine2(_) => Self::Number,
TaggedValue::Group(_) => Self::Group,
TaggedValue::Graphic(_) => Self::Graphic,
TaggedValue::Artboard(_) => Self::Artboard,
_ => Self::General,
}

View File

@@ -23,7 +23,7 @@ pub fn empty_provider() -> OverlayProvider {
|_| Message::NoOp
}
// Types of overlays used by DocumentMessage to enable/disable select group of overlays in the frontend
/// Types of overlays used by DocumentMessage to enable/disable the selected set of viewport overlays.
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
pub enum OverlaysType {
ArtboardName,

View File

@@ -24,7 +24,7 @@ pub fn empty_provider() -> OverlayProvider {
|_| Message::NoOp
}
// Types of overlays used by DocumentMessage to enable/disable select group of overlays in the frontend
/// Types of overlays used by DocumentMessage to enable/disable the selected set of viewport overlays.
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
pub enum OverlaysType {
ArtboardName,

View File

@@ -303,10 +303,10 @@ impl LayerNodeIdentifier {
child.ancestors(metadata).any(|ancestor| ancestor == self)
}
/// Is the layer last child of parent group? Used for clipping
/// Is the layer the last child of its stack? Used for clipping
pub fn can_be_clipped(self, metadata: &DocumentMetadata) -> bool {
self.parent(metadata)
.map_or(false, |layer| layer.last_child(metadata).expect("Parent accessed via child should have children") != self)
.is_some_and(|layer| layer.last_child(metadata).expect("Parent accessed via child should have children") != self)
}
/// Iterator over all direct children (excluding self and recursive children)

View File

@@ -6614,25 +6614,27 @@ fn migrate_output_names<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Re
const REPLACEMENTS: &[(&str, &str)] = &[
// Single to table data
("VectorData", "Table<Vector>"),
("GraphicGroup", "Table<Group>"),
("GraphicGroup", "Table<Graphic>"),
("ImageFrame", "Table<Image>"),
// `ImageFrame` to `Image` rename
("Instances<ImageFrame>", "Table<Image>"),
// `Instances` to `Table` rename
("Instances<VectorData>", "Table<Vector>"),
("Instances<GraphicGroup>", "Table<Group>"),
("Instances<GraphicGroup>", "Table<Graphic>"),
("Instances<Image>", "Table<Image>"),
("Instances<GraphicElement>", "Table<Graphic>"),
("Table<GraphicElement>", "Table<Graphic>"),
("Future<Instances<Vector>>", "Future<Table<Vector>>"),
("Future<Instances<GraphicGroup>>", "Future<Table<Group>>"),
("Future<Instances<GraphicGroup>>", "Future<Table<Graphic>>"),
("Future<Instances<Image>>", "Future<Table<Image>>"),
("Future<Instances<GraphicElement>>", "Future<Table<Graphic>>"),
("Future<Table<GraphicElement>>", "Future<Table<Graphic>>"),
("Future<Table<VectorData>>", "Future<Table<Vector>>"),
("Table<VectorData>", "Table<Vector>"),
("Table<GraphicGroup>", "Table<Group>"),
("Future<Table<GraphicGroup>>", "Future<Table<Group>>"),
("Table<GraphicGroup>", "Table<Graphic>"),
("Future<Table<GraphicGroup>>", "Future<Table<Graphic>>"),
("Table<Group>", "Table<Graphic>"),
("Future<Table<Group>>", "Future<Table<Graphic>>"),
];
let mut names = Vec::<String>::deserialize(deserializer)?;

View File

@@ -359,8 +359,8 @@ impl LayoutHolder for MenuBarMessageHandler {
choices
.into_iter()
.map(|group| {
group
.map(|section| {
section
.into_iter()
.map(|(axis, aggregate, icon, name)| MenuBarEntry {
label: name.into(),

View File

@@ -154,7 +154,7 @@ impl TableRowLayout for Graphic {
}
fn identifier(&self) -> String {
match self {
Self::Group(group) => group.identifier(),
Self::Graphic(graphic) => graphic.identifier(),
Self::Vector(vector) => vector.identifier(),
Self::RasterCPU(_) => "Raster (on CPU)".to_string(),
Self::RasterGPU(_) => "Raster (on GPU)".to_string(),
@@ -166,7 +166,7 @@ impl TableRowLayout for Graphic {
}
fn compute_layout(&self, data: &mut LayoutData) -> Vec<LayoutGroup> {
match self {
Self::Group(table) => table.layout_with_breadcrumb(data),
Self::Graphic(table) => table.layout_with_breadcrumb(data),
Self::Vector(table) => table.layout_with_breadcrumb(data),
Self::RasterCPU(_) => label("Raster is not supported"),
Self::RasterGPU(_) => label("Raster is not supported"),
@@ -192,10 +192,10 @@ impl TableRowLayout for Vector {
let colinear = if colinear.is_empty() { "None" } else { &colinear };
let style = vec![
TextLabel::new(format!(
"{}\n\nColinear Handle IDs: {}\n\nUpstream Group Table: {}",
"{}\n\nColinear Handle IDs: {}\nPreserves Reference to Upstream Nested Layers for Editing by Tools: {}",
self.style,
colinear,
if self.upstream_group.is_some() { "Yes" } else { "No" }
if self.upstream_nested_layers.is_some() { "Yes" } else { "No" }
))
.multiline(true)
.widget_holder(),
@@ -269,7 +269,7 @@ impl TableRowLayout for Artboard {
self.label.clone()
}
fn compute_layout(&self, data: &mut LayoutData) -> Vec<LayoutGroup> {
self.group.compute_layout(data)
self.content.compute_layout(data)
}
}

View File

@@ -455,8 +455,8 @@ fn subpath_anchor_snap_points(layer: LayerNodeIdentifier, subpath: &Subpath<Poin
}
// Anchors
for (index, group) in subpath.manipulator_groups().iter().enumerate() {
if snap_data.ignore_manipulator(layer, group.id) {
for (index, manipulators) in subpath.manipulator_groups().iter().enumerate() {
if snap_data.ignore_manipulator(layer, manipulators.id) {
continue;
}
@@ -464,12 +464,12 @@ fn subpath_anchor_snap_points(layer: LayerNodeIdentifier, subpath: &Subpath<Poin
return;
}
let colinear = are_manipulator_handles_colinear(group, to_document, subpath, index);
let colinear = are_manipulator_handles_colinear(manipulators, to_document, subpath, index);
// Colinear handles
if colinear && document.snapping_state.target_enabled(SnapTarget::Path(PathSnapTarget::AnchorPointWithColinearHandles)) {
points.push(SnapCandidatePoint::new(
to_document.transform_point2(group.anchor),
to_document.transform_point2(manipulators.anchor),
SnapSource::Path(PathSnapSource::AnchorPointWithColinearHandles),
SnapTarget::Path(PathSnapTarget::AnchorPointWithColinearHandles),
Some(layer),
@@ -478,7 +478,7 @@ fn subpath_anchor_snap_points(layer: LayerNodeIdentifier, subpath: &Subpath<Poin
// Free handles
else if !colinear && document.snapping_state.target_enabled(SnapTarget::Path(PathSnapTarget::AnchorPointWithFreeHandles)) {
points.push(SnapCandidatePoint::new(
to_document.transform_point2(group.anchor),
to_document.transform_point2(manipulators.anchor),
SnapSource::Path(PathSnapSource::AnchorPointWithFreeHandles),
SnapTarget::Path(PathSnapTarget::AnchorPointWithFreeHandles),
Some(layer),
@@ -487,10 +487,10 @@ fn subpath_anchor_snap_points(layer: LayerNodeIdentifier, subpath: &Subpath<Poin
}
}
pub fn are_manipulator_handles_colinear(group: &bezier_rs::ManipulatorGroup<PointId>, to_document: DAffine2, subpath: &Subpath<PointId>, index: usize) -> bool {
let anchor = group.anchor;
let handle_in = group.in_handle.map(|handle| anchor - handle).filter(handle_not_under(to_document));
let handle_out = group.out_handle.map(|handle| handle - anchor).filter(handle_not_under(to_document));
pub fn are_manipulator_handles_colinear(manipulators: &bezier_rs::ManipulatorGroup<PointId>, to_document: DAffine2, subpath: &Subpath<PointId>, index: usize) -> bool {
let anchor = manipulators.anchor;
let handle_in = manipulators.in_handle.map(|handle| anchor - handle).filter(handle_not_under(to_document));
let handle_out = manipulators.out_handle.map(|handle| handle - anchor).filter(handle_not_under(to_document));
let anchor_is_endpoint = !subpath.closed() && (index == 0 || index == subpath.len() - 1);
// Unless this is an endpoint, check if both handles are colinear (within an angular epsilon)

View File

@@ -339,7 +339,7 @@ impl Fsm for ArtboardToolFsmState {
responses.add(GraphOperationMessage::NewArtboard {
id,
artboard: Artboard {
group: Table::new(),
content: Table::new(),
label: String::from("Artboard"),
location: start.min(end).round().as_ivec2(),
dimensions: (start.round() - end.round()).abs().as_ivec2(),

View File

@@ -163,8 +163,8 @@ impl LayoutHolder for BrushTool {
let blend_mode_entries: Vec<Vec<_>> = BlendMode::list()
.iter()
.map(|group| {
group
.map(|section| {
section
.iter()
.map(|blend_mode| {
MenuListEntry::new(format!("{blend_mode:?}"))

View File

@@ -674,6 +674,7 @@ mod test_gradient {
let folder = layers.next().unwrap();
let rectangle = layers.next().unwrap();
assert_eq!(rectangle.parent(metadata), Some(folder));
// Transform the group
editor
.handle_message(GraphOperationMessage::TransformSet {

View File

@@ -378,7 +378,7 @@ impl NodeGraphExecutor {
TaggedValue::DVec2(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::OptionalColor(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Vector(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Group(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Graphic(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Raster(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Palette(render_object) => Self::debug_render(render_object, transform, responses),
_ => {