Skip to content

Commit 50e0c0e

Browse files
Keavonoluseyi
authored andcommitted
Migrate remaining node graph data types from Vec to Table (GraphiteEditor#4067)
* Move Vec<String> to Table<String> * Remove old VecDVec2 * Move Vec<u8> to Table<u8> * Move Vec<f64> to Table<f64> * Move [f64; 4] to Table<f64> * Move Vec<NodeId> to Table<NodeId> * Tidy up the TaggedValue variants * Move Vec<BrushStroke> to Table<BrushStroke> * Add missing type implementations * Fix tests ---------
1 parent d28d48f commit 50e0c0e

25 files changed

Lines changed: 277 additions & 341 deletions

File tree

editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,15 @@ fn generate_layout(introspected_data: &Arc<dyn std::any::Any + Send + Sync + 'st
169169
Table<Raster<GPU>>,
170170
Table<Color>,
171171
Table<GradientStops>,
172+
Table<String>,
173+
Table<NodeId>,
174+
Table<f64>,
175+
Table<u8>,
172176
GradientStops,
173177
f64,
174178
u32,
175179
u64,
176180
bool,
177-
Vec<String>,
178181
String,
179182
Option<f64>,
180183
DVec2,
@@ -214,46 +217,6 @@ trait TableRowLayout {
214217
}
215218
}
216219

217-
impl<T: TableRowLayout> TableRowLayout for Vec<T> {
218-
fn type_name() -> &'static str {
219-
"Vec"
220-
}
221-
fn identifier(&self) -> String {
222-
format!("Vec<{}> ({} element{})", T::type_name(), self.len(), if self.len() == 1 { "" } else { "s" })
223-
}
224-
fn element_page(&self, data: &mut LayoutData) -> Vec<LayoutGroup> {
225-
if let Some(step) = data.desired_path.get(data.current_depth).cloned() {
226-
match step {
227-
PathStep::Element(index) => {
228-
if let Some(row) = self.get(index) {
229-
data.current_depth += 1;
230-
let result = row.layout_with_breadcrumb(data);
231-
data.current_depth -= 1;
232-
return result;
233-
} else {
234-
warn!("Desired path truncated");
235-
data.desired_path.truncate(data.current_depth);
236-
}
237-
}
238-
PathStep::Attribute { .. } => {
239-
warn!("Attribute path step inside a Vec is unsupported");
240-
data.desired_path.truncate(data.current_depth);
241-
}
242-
}
243-
}
244-
245-
let mut rows = self
246-
.iter()
247-
.enumerate()
248-
.map(|(index, row)| vec![TextLabel::new(format!("{index}")).narrow(true).widget_instance(), row.cell_widget(PathStep::Element(index))])
249-
.collect::<Vec<_>>();
250-
251-
rows.insert(0, column_headings(&["", "element"]));
252-
253-
vec![LayoutGroup::table(rows, false)]
254-
}
255-
}
256-
257220
impl<T: TableRowLayout> TableRowLayout for Table<T> {
258221
fn type_name() -> &'static str {
259222
"Table"
@@ -616,6 +579,21 @@ impl TableRowLayout for f64 {
616579
}
617580
}
618581

582+
impl TableRowLayout for u8 {
583+
fn type_name() -> &'static str {
584+
"Byte"
585+
}
586+
fn identifier(&self) -> String {
587+
format!("{self:02X}")
588+
}
589+
fn cell_widget(&self, _target: PathStep) -> WidgetInstance {
590+
TextLabel::new(self.identifier()).narrow(true).widget_instance()
591+
}
592+
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
593+
vec![LayoutGroup::row(vec![self.cell_widget(PathStep::Element(0))])]
594+
}
595+
}
596+
619597
impl TableRowLayout for u32 {
620598
fn type_name() -> &'static str {
621599
"Number (u32)"
@@ -774,6 +752,26 @@ impl TableRowLayout for AlphaBlending {
774752
}
775753
}
776754

755+
impl TableRowLayout for NodeId {
756+
fn type_name() -> &'static str {
757+
"NodeId"
758+
}
759+
fn identifier(&self) -> String {
760+
format!("Node {self}")
761+
}
762+
fn cell_widget(&self, _target: PathStep) -> WidgetInstance {
763+
let node_id = *self;
764+
TextButton::new("Go to Node")
765+
.tooltip_description("Click to select the node with this ID in the graph.")
766+
.on_update(move |_| NodeGraphMessage::SelectedNodesSet { nodes: vec![node_id] }.into())
767+
.narrow(true)
768+
.widget_instance()
769+
}
770+
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
771+
vec![LayoutGroup::row(vec![self.cell_widget(PathStep::Element(0))])]
772+
}
773+
}
774+
777775
impl TableRowLayout for Option<NodeId> {
778776
fn type_name() -> &'static str {
779777
"NodeId"
@@ -812,8 +810,13 @@ macro_rules! known_table_row_types {
812810
Table<Raster<GPU>>,
813811
Table<Color>,
814812
Table<GradientStops>,
813+
Table<String>,
814+
Table<NodeId>,
815+
Table<f64>,
816+
Table<u8>,
815817
GradientStops,
816818
Color,
819+
NodeId,
817820
Option<NodeId>,
818821
AlphaBlending,
819822
DAffine2,
@@ -822,11 +825,11 @@ macro_rules! known_table_row_types {
822825
Vec2,
823826
Option<f64>,
824827
f64,
828+
u8,
825829
u32,
826830
u64,
827831
bool,
828832
String,
829-
Vec<String>,
830833
Vector,
831834
Raster<CPU>,
832835
Raster<GPU>,

editor/src/messages/portfolio/document/graph_operation/utility_types.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,9 @@ impl<'a> ModifyInputsContext<'a> {
491491
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(stroke.join_miter_limit), false), false);
492492
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::PaintOrderInput::INDEX);
493493
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::PaintOrder(stroke.paint_order), false), false);
494-
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashLengthsInput::<Vec<f64>>::INDEX);
495-
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::VecF64(stroke.dash_lengths), false), true);
494+
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashLengthsInput::<graphene_std::table::Table<f64>>::INDEX);
495+
let dash_lengths_table = stroke.dash_lengths.into_iter().map(graphene_std::table::TableRow::new_from_element).collect();
496+
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64Table(dash_lengths_table), false), true);
496497
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashOffsetInput::INDEX);
497498
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(stroke.dash_offset), false), true);
498499
}
@@ -579,7 +580,8 @@ impl<'a> ModifyInputsContext<'a> {
579580
let Some(brush_node_id) = self.existing_network_node_id("Brush", true) else {
580581
return;
581582
};
582-
self.set_input_with_refresh(InputConnector::node(brush_node_id, 1), NodeInput::value(TaggedValue::BrushStrokes(strokes), false), false);
583+
let strokes_table = strokes.into_iter().map(graphene_std::table::TableRow::new_from_element).collect();
584+
self.set_input_with_refresh(InputConnector::node(brush_node_id, 1), NodeInput::value(TaggedValue::BrushStrokeTable(strokes_table), false), false);
583585
}
584586

585587
pub fn resize_artboard(&mut self, location: IVec2, dimensions: IVec2) {

editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1391,7 +1391,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
13911391
}),
13921392
inputs: vec![
13931393
NodeInput::value(TaggedValue::Raster(Default::default()), true),
1394-
NodeInput::value(TaggedValue::BrushStrokes(Vec::new()), false),
1394+
NodeInput::value(TaggedValue::BrushStrokeTable(Default::default()), false),
13951395
NodeInput::value(TaggedValue::BrushCache(BrushCache::default()), false),
13961396
],
13971397
..Default::default()

editor/src/messages/portfolio/document/node_graph/node_properties.rs

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,10 @@ pub(crate) fn property_from_type(
210210
Some(x) if x == TypeId::of::<String>() => text_widget(default_info).into(),
211211
Some(x) if x == TypeId::of::<DVec2>() => vec2_widget(default_info, "X", "Y", "", None, false),
212212
Some(x) if x == TypeId::of::<DAffine2>() => transform_widget(default_info, &mut extra_widgets),
213-
// ==========================
214-
// PRIMITIVE COLLECTION TYPES
215-
// ==========================
216-
Some(x) if x == TypeId::of::<Vec<f64>>() => array_of_number_widget(default_info, TextInput::default()).into(),
217-
Some(x) if x == TypeId::of::<Vec<DVec2>>() => array_of_vec2_widget(default_info, TextInput::default()).into(),
218213
// ===========
219214
// TABLE TYPES
220215
// ===========
216+
Some(x) if x == TypeId::of::<Table<f64>>() => array_of_number_widget(default_info, TextInput::default()).into(),
221217
Some(x) if x == TypeId::of::<Table<Color>>() => color_widget(default_info, ColorInput::default().allow_none(true)),
222218
Some(x) if x == TypeId::of::<Table<GradientStops>>() => color_widget(default_info, ColorInput::default().allow_none(false)),
223219
// ============
@@ -776,51 +772,19 @@ pub fn array_of_number_widget(parameter_widgets_info: ParameterWidgetsInfo, text
776772
.map(str::parse::<f64>)
777773
.collect::<Result<Vec<_>, _>>()
778774
.ok()
779-
.map(TaggedValue::VecF64)
775+
.map(|values| TaggedValue::F64Table(values.into_iter().map(graphene_std::table::TableRow::new_from_element).collect()))
780776
};
781777

782778
let Some(document_node) = document_node else { return Vec::new() };
783779
let Some(input) = document_node.inputs.get(index) else {
784780
log::warn!("A widget failed to be built because its node's input index is invalid.");
785781
return vec![];
786782
};
787-
if let Some(TaggedValue::VecF64(x)) = &input.as_non_exposed_value() {
783+
if let Some(TaggedValue::F64Table(table)) = &input.as_non_exposed_value() {
788784
widgets.extend_from_slice(&[
789785
Separator::new(SeparatorStyle::Unrelated).widget_instance(),
790786
text_input
791-
.value(x.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
792-
.on_update(optionally_update_value(move |x: &TextInput| from_string(&x.value), node_id, index))
793-
.widget_instance(),
794-
])
795-
}
796-
widgets
797-
}
798-
799-
pub fn array_of_vec2_widget(parameter_widgets_info: ParameterWidgetsInfo, text_props: TextInput) -> Vec<WidgetInstance> {
800-
let ParameterWidgetsInfo { document_node, node_id, index, .. } = parameter_widgets_info;
801-
802-
let mut widgets = start_widgets(parameter_widgets_info);
803-
804-
let from_string = |string: &str| {
805-
string
806-
.split(|c: char| !c.is_alphanumeric() && !matches!(c, '.' | '+' | '-'))
807-
.filter(|x| !x.is_empty())
808-
.map(|x| x.parse::<f64>().ok())
809-
.collect::<Option<Vec<_>>>()
810-
.map(|numbers| numbers.chunks_exact(2).map(|values| DVec2::new(values[0], values[1])).collect())
811-
.map(TaggedValue::VecDVec2)
812-
};
813-
814-
let Some(document_node) = document_node else { return Vec::new() };
815-
let Some(input) = document_node.inputs.get(index) else {
816-
log::warn!("A widget failed to be built because its node's input index is invalid.");
817-
return vec![];
818-
};
819-
if let Some(TaggedValue::VecDVec2(x)) = &input.as_non_exposed_value() {
820-
widgets.extend_from_slice(&[
821-
Separator::new(SeparatorStyle::Unrelated).widget_instance(),
822-
text_props
823-
.value(x.iter().map(|v| format!("({}, {})", v.x, v.y)).collect::<Vec<_>>().join(", "))
787+
.value(table.iter_element_values().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
824788
.on_update(optionally_update_value(move |x: &TextInput| from_string(&x.value), node_id, index))
825789
.widget_instance(),
826790
])
@@ -1839,13 +1803,13 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
18391803
};
18401804
let uniform_val = match input.as_non_exposed_value() {
18411805
Some(TaggedValue::F64(x)) => *x,
1842-
Some(TaggedValue::F64Array4(x)) => x[0],
1806+
Some(TaggedValue::F64Table(table)) => table.iter_element_values().copied().next().unwrap_or(0.),
18431807
_ => 0.,
18441808
};
18451809
let individual_val = match input.as_non_exposed_value() {
1846-
Some(&TaggedValue::F64Array4(x)) => x,
1847-
Some(&TaggedValue::F64(x)) => [x; 4],
1848-
_ => [0.; 4],
1810+
Some(&TaggedValue::F64(x)) => vec![x; 4],
1811+
Some(TaggedValue::F64Table(table)) => table.iter_element_values().copied().collect(),
1812+
_ => vec![0.; 4],
18491813
};
18501814

18511815
// Uniform/individual radio input widget
@@ -1868,6 +1832,7 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
18681832
]),
18691833
})
18701834
.on_commit(commit_value);
1835+
let individual_val_for_switch = individual_val.clone();
18711836
let individual = RadioEntryData::new("Individual")
18721837
.label("Individual")
18731838
.on_update(move |_| Message::Batched {
@@ -1881,7 +1846,7 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
18811846
NodeGraphMessage::SetInputValue {
18821847
node_id,
18831848
input_index: CornerRadiusInput::<f64>::INDEX,
1884-
value: TaggedValue::F64Array4(individual_val),
1849+
value: TaggedValue::F64Table(individual_val_for_switch.iter().copied().map(graphene_std::table::TableRow::new_from_element).collect()),
18851850
}
18861851
.into(),
18871852
]),
@@ -1899,11 +1864,7 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
18991864
.map(str::parse::<f64>)
19001865
.collect::<Result<Vec<f64>, _>>()
19011866
.ok()
1902-
.map(|v| {
1903-
let arr: Box<[f64; 4]> = v.into_boxed_slice().try_into().unwrap_or_default();
1904-
*arr
1905-
})
1906-
.map(TaggedValue::F64Array4)
1867+
.map(|values| TaggedValue::F64Table(values.into_iter().take(4).map(graphene_std::table::TableRow::new_from_element).collect()))
19071868
};
19081869
TextInput::default()
19091870
.value(individual_val.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
@@ -2296,11 +2257,10 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) -
22962257
_ => &StrokeJoin::Miter,
22972258
};
22982259

2299-
let dash_lengths_val = match &document_node.inputs[DashLengthsInput::<Vec<f64>>::INDEX].as_value() {
2300-
Some(TaggedValue::VecF64(x)) => x,
2301-
_ => &vec![],
2260+
let has_dash_lengths = match &document_node.inputs[DashLengthsInput::<Table<f64>>::INDEX].as_value() {
2261+
Some(TaggedValue::F64Table(table)) => table.is_empty(),
2262+
_ => true,
23022263
};
2303-
let has_dash_lengths = dash_lengths_val.is_empty();
23042264
let miter_limit_disabled = join_value != &StrokeJoin::Miter;
23052265

23062266
let color = color_widget(
@@ -2325,7 +2285,7 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) -
23252285
.property_row();
23262286
let disabled_number_input = NumberInput::default().unit(" px").disabled(has_dash_lengths);
23272287
let dash_lengths = array_of_number_widget(
2328-
ParameterWidgetsInfo::new(node_id, DashLengthsInput::<Vec<f64>>::INDEX, true, context),
2288+
ParameterWidgetsInfo::new(node_id, DashLengthsInput::<Table<f64>>::INDEX, true, context),
23292289
TextInput::default().centered(true),
23302290
);
23312291
let number_input = disabled_number_input;

editor/src/messages/portfolio/document/node_graph/utility_types.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,14 @@ pub enum FrontendGraphDataType {
2121
impl FrontendGraphDataType {
2222
pub fn from_type(input: &Type) -> Self {
2323
match TaggedValue::from_type_or_none(input) {
24-
TaggedValue::U32(_)
25-
| TaggedValue::U64(_)
26-
| TaggedValue::F32(_)
27-
| TaggedValue::F64(_)
28-
| TaggedValue::DVec2(_)
29-
| TaggedValue::F64Array4(_)
30-
| TaggedValue::VecF64(_)
31-
| TaggedValue::VecDVec2(_)
32-
| TaggedValue::DAffine2(_) => Self::Number,
24+
TaggedValue::U32(_) | TaggedValue::U64(_) | TaggedValue::F32(_) | TaggedValue::F64(_) | TaggedValue::DVec2(_) | TaggedValue::F64Table(_) | TaggedValue::DAffine2(_) => Self::Number,
3325
TaggedValue::Artboard(_) => Self::Artboard,
3426
TaggedValue::Graphic(_) => Self::Graphic,
3527
TaggedValue::Raster(_) => Self::Raster,
3628
TaggedValue::Vector(_) => Self::Vector,
3729
TaggedValue::Color(_) => Self::Color,
3830
TaggedValue::Gradient(_) | TaggedValue::GradientTable(_) => Self::Gradient,
39-
TaggedValue::String(_) | TaggedValue::VecString(_) => Self::Typography,
31+
TaggedValue::String(_) | TaggedValue::StringTable(_) => Self::Typography,
4032
_ => Self::General,
4133
}
4234
}

editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,9 @@ impl TypeSource {
5353
};
5454
match self.compiled_nested_type() {
5555
Some(nested_type) => match TaggedValue::from_type_or_none(nested_type) {
56-
TaggedValue::U32(_)
57-
| TaggedValue::U64(_)
58-
| TaggedValue::F32(_)
59-
| TaggedValue::F64(_)
60-
| TaggedValue::DVec2(_)
61-
| TaggedValue::F64Array4(_)
62-
| TaggedValue::VecF64(_)
63-
| TaggedValue::VecDVec2(_)
64-
| TaggedValue::DAffine2(_) => FrontendGraphDataType::Number,
56+
TaggedValue::U32(_) | TaggedValue::U64(_) | TaggedValue::F32(_) | TaggedValue::F64(_) | TaggedValue::DVec2(_) | TaggedValue::F64Table(_) | TaggedValue::DAffine2(_) => {
57+
FrontendGraphDataType::Number
58+
}
6559
TaggedValue::Artboard(_) => FrontendGraphDataType::Artboard,
6660
TaggedValue::Graphic(_) => FrontendGraphDataType::Graphic,
6761
TaggedValue::Raster(_) => FrontendGraphDataType::Raster,

0 commit comments

Comments
 (0)