mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-25 06:48:11 +08:00
New node: Math (#2121)
* 2115 IP * Initial implementation of Expression node * Register Expression Node * Add Expression DocumentNode Definition * DocumentNodeImplementation::Expresssion in guess_type_from_node * Move expression.rs to graphene-core * WIP: Investigating 'exposed' & 'value_source' params for Expression property * Node graph render debug IP * Single input can change node properties; complex debug IP * Fix epsilon in test * Handle invalid expressions in expression_node by returning 0.0 * Run cargo fmt * Set the default expression to "1 + 1" * Hardcode the A and B inputs at Keavon's request * Rename and clean up UX * Move into ops.rs --------- Co-authored-by: hypercube <0hypercube@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
hypercube
Keavon Chambers
parent
79b4f4df7b
commit
3423c8ec13
@@ -2530,6 +2530,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
"graphene_core::raster::adjustments::SelectiveColorNode",
|
||||
&node_properties::selective_color_properties as PropertiesLayout,
|
||||
),
|
||||
("graphene_core::ops::MathNode", &node_properties::math_properties as PropertiesLayout),
|
||||
("graphene_core::raster::ExposureNode", &node_properties::exposure_properties as PropertiesLayout),
|
||||
("graphene_core::vector::generator_nodes::RectangleNode", &node_properties::rectangle_properties as PropertiesLayout),
|
||||
("graphene_core::vector::AssignColorsNode", &node_properties::assign_colors_properties as PropertiesLayout),
|
||||
|
||||
@@ -2616,3 +2616,52 @@ pub(crate) fn artboard_properties(document_node: &DocumentNode, node_id: NodeId,
|
||||
|
||||
vec![location, dimensions, background, clip_row]
|
||||
}
|
||||
|
||||
pub fn math_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let expression_index = 1;
|
||||
let operation_b_index = 2;
|
||||
|
||||
let expression = (|| {
|
||||
let mut widgets = start_widgets(document_node, node_id, expression_index, "Expression", FrontendGraphDataType::General, true);
|
||||
|
||||
let Some(input) = document_node.inputs.get(expression_index) else {
|
||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||
return vec![];
|
||||
};
|
||||
if let Some(TaggedValue::String(x)) = &input.as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
TextInput::new(x.clone())
|
||||
.centered(true)
|
||||
.on_update(update_value(
|
||||
|x: &TextInput| {
|
||||
TaggedValue::String({
|
||||
let mut expression = x.value.trim().to_string();
|
||||
|
||||
if ["+", "-", "*", "/", "^", "%"].iter().any(|&infix| infix == expression) {
|
||||
expression = format!("A {} B", expression);
|
||||
} else if expression == "^" {
|
||||
expression = String::from("A^B");
|
||||
}
|
||||
|
||||
expression
|
||||
})
|
||||
},
|
||||
node_id,
|
||||
expression_index,
|
||||
))
|
||||
.on_commit(commit_value)
|
||||
.widget_holder(),
|
||||
])
|
||||
}
|
||||
widgets
|
||||
})();
|
||||
let operand_b = number_widget(document_node, node_id, operation_b_index, "Operand B", NumberInput::default(), true);
|
||||
let operand_a_hint = vec![TextLabel::new("(Operand A is the primary input)").widget_holder()];
|
||||
|
||||
vec![
|
||||
LayoutGroup::Row { widgets: expression }.with_tooltip(r#"A math expression that may incorporate "A" and/or "B", such as "sqrt(A + B) - B^2""#),
|
||||
LayoutGroup::Row { widgets: operand_b }.with_tooltip(r#"The value of "B" when calculating the expression"#),
|
||||
LayoutGroup::Row { widgets: operand_a_hint }.with_tooltip(r#""A" is fed by the value from the previous node in the primary data flow, or it is 0 if disconnected"#),
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user