Fix 'Mask' node missing Properties widget; fix crash with 'Brightness/Contrast Classic' node (#3404)

* Fix 'Mask' node missing Properties widget; fix crash with 'Brightness/Contrast Classic' node

Also clean up dead code and improve tooltip for the "-" Properties panel widget fallback.

* format type

---------

Co-authored-by: Adam <adamgerhant@gmail.com>
This commit is contained in:
Keavon Chambers 2025-11-24 01:21:07 -08:00 committed by GitHub
parent 7afbeaa1f9
commit 6e66c79392
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 20 additions and 76 deletions

View File

@ -21,8 +21,8 @@ impl DialogLayoutHolder for AboutGraphiteDialog {
fn layout_column_2(&self) -> Layout {
let links = [
("Heart", "Donate", "https://graphite.rs/donate/"),
("Volunteer", "Volunteer", "https://graphite.rs/volunteer/"),
("GraphiteLogo", "Website", "https://graphite.rs"),
("Volunteer", "Volunteer", "https://graphite.rs/volunteer/"),
("Credits", "Credits", "https://github.com/GraphiteEditor/Graphite/graphs/contributors"),
];
let mut widgets = links

View File

@ -2021,47 +2021,6 @@ fn static_input_properties() -> InputProperties {
Ok(vec![cellular_jitter.into()])
}),
);
map.insert(
"brightness".to_string(),
Box::new(|node_id, index, context| {
let document_node = node_properties::get_document_node(node_id, context)?;
let is_use_classic = document_node
.inputs
.iter()
.find_map(|input| match input.as_value() {
Some(&TaggedValue::Bool(use_classic)) => Some(use_classic),
_ => None,
})
.unwrap_or(false);
let (b_min, b_max) = if is_use_classic { (-100., 100.) } else { (-100., 150.) };
let brightness = node_properties::number_widget(
ParameterWidgetsInfo::new(node_id, index, true, context),
NumberInput::default().mode_range().range_min(Some(b_min)).range_max(Some(b_max)).unit("%").display_decimal_places(2),
);
Ok(vec![brightness.into()])
}),
);
map.insert(
"contrast".to_string(),
Box::new(|node_id, index, context| {
let document_node = node_properties::get_document_node(node_id, context)?;
let is_use_classic = document_node
.inputs
.iter()
.find_map(|input| match input.as_value() {
Some(&TaggedValue::Bool(use_classic)) => Some(use_classic),
_ => None,
})
.unwrap_or(false);
let (c_min, c_max) = if is_use_classic { (-100., 100.) } else { (-50., 100.) };
let contrast = node_properties::number_widget(
ParameterWidgetsInfo::new(node_id, index, true, context),
NumberInput::default().mode_range().range_min(Some(c_min)).range_max(Some(c_max)).unit("%").display_decimal_places(2),
);
Ok(vec![contrast.into()])
}),
);
map.insert(
"assign_colors_gradient".to_string(),
Box::new(|node_id, index, context| {
@ -2091,21 +2050,6 @@ fn static_input_properties() -> InputProperties {
Ok(vec![repeat_every_row.into()])
}),
);
map.insert(
"mask_stencil".to_string(),
Box::new(|node_id, index, context| {
let mask = node_properties::color_widget(ParameterWidgetsInfo::new(node_id, index, true, context), ColorInput::default());
Ok(vec![mask])
}),
);
map.insert(
"spline_input".to_string(),
Box::new(|node_id, index, context| {
Ok(vec![LayoutGroup::Row {
widgets: node_properties::array_of_vec2_widget(ParameterWidgetsInfo::new(node_id, index, true, context), TextInput::default().centered(true)),
}])
}),
);
map.insert(
"transform_rotation".to_string(),
Box::new(|node_id, index, context| {

View File

@ -232,7 +232,12 @@ pub(crate) fn property_from_type(
.tooltip(format!(
"This data can only be supplied through the node graph because no widget exists for its type:\n\
{}",
concrete_type.name
// TODO: Avoid needing to remove spaces here by fixing how `alias` is generated
concrete_type
.alias
.as_deref()
.map(|s| s.to_string().replace(" ", ""))
.unwrap_or_else(|| graphene_std::format_type(concrete_type.name.as_ref()))
))
.widget_holder(),
]);
@ -1087,7 +1092,9 @@ pub(crate) fn brightness_contrast_properties(node_id: NodeId, context: &mut Node
return Vec::new();
}
};
let use_classic_value = match document_node.inputs[UseClassicInput::INDEX].as_value() {
let use_classic_value = document_node.inputs.get(UseClassicInput::INDEX);
let includes_use_classic = use_classic_value.is_some();
let use_classic_value = match use_classic_value.and_then(|input| input.as_value()) {
Some(TaggedValue::Bool(use_classic_choice)) => *use_classic_choice,
_ => false,
};
@ -1114,11 +1121,11 @@ pub(crate) fn brightness_contrast_properties(node_id: NodeId, context: &mut Node
.range_max(Some(100.)),
);
let layout = vec![
LayoutGroup::Row { widgets: brightness },
LayoutGroup::Row { widgets: contrast },
LayoutGroup::Row { widgets: use_classic },
];
let mut layout = vec![LayoutGroup::Row { widgets: brightness }, LayoutGroup::Row { widgets: contrast }];
if includes_use_classic {
// TODO: When we no longer use this function in the temporary "Brightness/Contrast Classic" node, remove this conditional pushing and just always include this
layout.push(LayoutGroup::Row { widgets: use_classic });
}
layout
}
@ -1596,18 +1603,11 @@ pub(crate) fn generate_node_properties(node_id: NodeId, context: &mut NodeProper
return Vec::new();
};
let mut input_types = implementations
.keys()
.filter_map(|item| item.inputs.get(input_index))
.filter(|ty| property_from_type(node_id, input_index, ty, number_options, unit_suffix, display_decimal_places, step, context).is_ok())
.collect::<Vec<_>>();
let mut input_types = implementations.keys().filter_map(|item| item.inputs.get(input_index)).collect::<Vec<_>>();
input_types.sort_by_key(|ty| ty.type_name());
let input_type = input_types.first().cloned();
let Some(input_type) = input_type else {
return Vec::new();
};
let Some(input_type) = input_type else { return Vec::new() };
input_type.clone()
}
_ => context

View File

@ -354,7 +354,7 @@ impl Type {
}
}
fn format_type(ty: &str) -> String {
pub fn format_type(ty: &str) -> String {
ty.split('<')
.map(|path| path.split(',').map(|path| path.split("::").last().unwrap_or(path)).collect::<Vec<_>>().join(","))
.collect::<Vec<_>>()

View File

@ -141,9 +141,9 @@ fn make_opaque<T: Adjust<Color>>(
input
}
/// See [`brightness_contrast`]
// TODO: Remove this once GPU shader nodes are able to support the non-classic algorithm
#[node_macro::node(
name("Brightness/Contrast classic"),
name("Brightness/Contrast Classic"),
category("Raster: Adjustment"),
properties("brightness_contrast_properties"),
shader_node(PerPixelAdjust)