Make the node graph use Table<GradientStops> instead of GradientStops (#3837)

* Switch from GradientStops to Table<GradientStops> in all nodes

* Remove TaggedValue::ColorNotInTable

* Fix bug

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Add migrations

* Fix default gradient on empty table

* Update demo artwork

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Keavon Chambers
2026-02-26 14:07:31 -08:00
committed by GitHub
parent 81c73d11ff
commit f1cbc4b396
26 changed files with 132 additions and 111 deletions

View File

@@ -214,19 +214,19 @@ pub(crate) fn property_from_type(
Some(x) if x == TypeId::of::<String>() => text_widget(default_info).into(),
Some(x) if x == TypeId::of::<DVec2>() => vec2_widget(default_info, "X", "Y", "", None, false),
Some(x) if x == TypeId::of::<DAffine2>() => transform_widget(default_info, &mut extra_widgets),
Some(x) if x == TypeId::of::<Color>() => color_widget(default_info, ColorInput::default()),
Some(x) if x == TypeId::of::<Option<Color>>() => color_widget(default_info, ColorInput::default()),
// ==========================
// PRIMITIVE COLLECTION TYPES
// ==========================
Some(x) if x == TypeId::of::<Vec<f64>>() => array_of_number_widget(default_info, TextInput::default()).into(),
Some(x) if x == TypeId::of::<Vec<DVec2>>() => array_of_vec2_widget(default_info, TextInput::default()).into(),
// ===========
// TABLE TYPES
// ===========
Some(x) if x == TypeId::of::<Table<Color>>() => color_widget(default_info, ColorInput::default().allow_none(true)),
Some(x) if x == TypeId::of::<Table<GradientStops>>() => color_widget(default_info, ColorInput::default().allow_none(false)),
// ============
// STRUCT TYPES
// ============
Some(x) if x == TypeId::of::<Table<Color>>() => color_widget(default_info, ColorInput::default().allow_none(true)),
Some(x) if x == TypeId::of::<Table<GradientStops>>() => color_widget(default_info, ColorInput::default().allow_none(false)),
Some(x) if x == TypeId::of::<GradientStops>() => color_widget(default_info, ColorInput::default().allow_none(false)),
Some(x) if x == TypeId::of::<Font>() => font_widget(default_info),
Some(x) if x == TypeId::of::<Curve>() => curve_widget(default_info),
Some(x) if x == TypeId::of::<Footprint>() => footprint_widget(default_info, &mut extra_widgets),
@@ -1145,14 +1145,6 @@ pub fn color_widget(parameter_widgets_info: ParameterWidgetsInfo, color_button:
// Add the color input
match &**tagged_value {
TaggedValue::ColorNotInTable(color) => widgets.push(
color_button
.value(FillChoice::Solid(*color))
.allow_none(false)
.on_update(update_value(|input: &ColorInput| TaggedValue::ColorNotInTable(input.value.as_solid().unwrap()), node_id, index))
.on_commit(commit_value)
.widget_instance(),
),
TaggedValue::Color(color_table) => widgets.push(
color_button
.value(match color_table.iter().next() {
@@ -1171,7 +1163,7 @@ pub fn color_widget(parameter_widgets_info: ParameterWidgetsInfo, color_button:
color_button
.value(match gradient_table.iter().next() {
Some(row) => FillChoice::Gradient(row.element.clone()),
None => FillChoice::None,
None => FillChoice::Gradient(GradientStops::default()),
})
.on_update(update_value(
|input: &ColorInput| TaggedValue::GradientTable(input.value.as_gradient().iter().map(|&gradient| TableRow::new_from_element(gradient.clone())).collect()),
@@ -1181,18 +1173,7 @@ pub fn color_widget(parameter_widgets_info: ParameterWidgetsInfo, color_button:
.on_commit(commit_value)
.widget_instance(),
),
TaggedValue::GradientStops(gradient_stops) => widgets.push(
color_button
.value(FillChoice::Gradient(gradient_stops.clone()))
.on_update(update_value(
|input: &ColorInput| TaggedValue::GradientStops(input.value.as_gradient().cloned().unwrap_or_default()),
node_id,
index,
))
.on_commit(commit_value)
.widget_instance(),
),
x => warn!("Colour {x:?}"),
x => warn!("Color {x:?}"),
}
LayoutGroup::Row { widgets }

View File

@@ -35,7 +35,7 @@ impl FrontendGraphDataType {
TaggedValue::Raster(_) => Self::Raster,
TaggedValue::Vector(_) => Self::Vector,
TaggedValue::Color(_) => Self::Color,
TaggedValue::Gradient(_) | TaggedValue::GradientStops(_) | TaggedValue::GradientTable(_) => Self::Gradient,
TaggedValue::Gradient(_) | TaggedValue::GradientTable(_) => Self::Gradient,
TaggedValue::String(_) | TaggedValue::VecString(_) => Self::Typography,
_ => Self::General,
}

View File

@@ -67,7 +67,7 @@ impl TypeSource {
TaggedValue::Raster(_) => FrontendGraphDataType::Raster,
TaggedValue::Vector(_) => FrontendGraphDataType::Vector,
TaggedValue::Color(_) => FrontendGraphDataType::Color,
TaggedValue::Gradient(_) | TaggedValue::GradientStops(_) | TaggedValue::GradientTable(_) => FrontendGraphDataType::Gradient,
TaggedValue::Gradient(_) | TaggedValue::GradientTable(_) => FrontendGraphDataType::Gradient,
TaggedValue::String(_) => FrontendGraphDataType::Typography,
_ => FrontendGraphDataType::General,
},

View File

@@ -282,13 +282,15 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
node: graphene_std::math_nodes::footprint_value::IDENTIFIER,
aliases: &["graphene_math_nodes::FootprintValueNode", "graphene_core::ops::FootprintValueNode"],
},
NodeReplacement {
node: graphene_std::math_nodes::gradient_table_value::IDENTIFIER,
aliases: &["graphene_math_nodes::GradientTableValueNode", "graphene_core::ops::GradientTableValueNode"],
},
NodeReplacement {
node: graphene_std::math_nodes::gradient_value::IDENTIFIER,
aliases: &["graphene_math_nodes::GradientValueNode", "graphene_core::ops::GradientValueNode"],
aliases: &[
"graphene_math_nodes::GradientValueNode",
"graphene_core::ops::GradientValueNode",
"graphene_math_nodes::GradientTableValueNode",
"graphene_core::ops::GradientTableValueNode",
"math_nodes::GradientTableValueNode",
],
},
NodeReplacement {
node: graphene_std::math_nodes::greater_than::IDENTIFIER,