mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 02:08:12 +08:00
Memoize hashing (#1876)
* Implement memoization wrapper for hashing * Fix pattern matching errors * Revert proper point modification hash calculiton * Remove unused hashing code * Code review and bug fixes * Improve pattern matching * Fix tests --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
44ffb635e9
commit
a6af5d4831
@@ -1631,11 +1631,7 @@ impl DocumentMessageHandler {
|
||||
let mut fonts = HashSet::new();
|
||||
for (_node_id, node) in self.network.recursive_nodes() {
|
||||
for input in &node.inputs {
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::Font(font),
|
||||
..
|
||||
} = input
|
||||
{
|
||||
if let Some(TaggedValue::Font(font)) = input.as_value() {
|
||||
fonts.insert(font.clone());
|
||||
}
|
||||
}
|
||||
@@ -2134,7 +2130,7 @@ fn root_network() -> NodeNetwork {
|
||||
{
|
||||
NodeNetwork {
|
||||
exports: vec![NodeInput::Value {
|
||||
tagged_value: TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY),
|
||||
tagged_value: TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY).into(),
|
||||
exposed: true,
|
||||
}],
|
||||
..Default::default()
|
||||
|
||||
@@ -70,56 +70,24 @@ impl LayerBounds {
|
||||
|
||||
/// Get the current affine transform from the transform node's inputs
|
||||
pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 {
|
||||
let translation = if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::DVec2(translation),
|
||||
..
|
||||
} = inputs[1]
|
||||
{
|
||||
let translation = if let Some(&TaggedValue::DVec2(translation)) = inputs[1].as_value() {
|
||||
translation
|
||||
} else {
|
||||
DVec2::ZERO
|
||||
};
|
||||
|
||||
let angle = if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64(angle),
|
||||
..
|
||||
} = inputs[2]
|
||||
{
|
||||
angle
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
let angle = if let Some(&TaggedValue::F64(angle)) = inputs[2].as_value() { angle } else { 0. };
|
||||
|
||||
let scale = if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::DVec2(scale),
|
||||
..
|
||||
} = inputs[3]
|
||||
{
|
||||
scale
|
||||
} else {
|
||||
DVec2::ONE
|
||||
};
|
||||
let scale = if let Some(&TaggedValue::DVec2(scale)) = inputs[3].as_value() { scale } else { DVec2::ONE };
|
||||
|
||||
let shear = if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::DVec2(shear),
|
||||
..
|
||||
} = inputs[4]
|
||||
{
|
||||
shear
|
||||
} else {
|
||||
DVec2::ZERO
|
||||
};
|
||||
let shear = if let Some(&TaggedValue::DVec2(shear)) = inputs[4].as_value() { shear } else { DVec2::ZERO };
|
||||
|
||||
DAffine2::from_scale_angle_translation(scale, angle, translation) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.])
|
||||
}
|
||||
|
||||
/// Extract the current normalized pivot from the layer
|
||||
pub fn get_current_normalized_pivot(inputs: &[NodeInput]) -> DVec2 {
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::DVec2(pivot),
|
||||
..
|
||||
} = inputs[5]
|
||||
{
|
||||
if let Some(&TaggedValue::DVec2(pivot)) = inputs[5].as_value() {
|
||||
pivot
|
||||
} else {
|
||||
DVec2::splat(0.5)
|
||||
|
||||
@@ -657,14 +657,12 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
|
||||
pub fn vector_modify(&mut self, modification_type: VectorModificationType) {
|
||||
self.modify_inputs("Path", false, |inputs, _node_id, _metadata| {
|
||||
let [_, NodeInput::Value {
|
||||
tagged_value: TaggedValue::VectorModification(modification),
|
||||
..
|
||||
}] = inputs.as_mut_slice()
|
||||
else {
|
||||
let Some(NodeInput::Value { tagged_value, .. }) = inputs.iter_mut().skip(1).next() else {
|
||||
panic!("Path node does not have modification input");
|
||||
};
|
||||
let TaggedValue::VectorModification(modification) = &mut *tagged_value.inner_mut() else {
|
||||
panic!("Path node does not have modification input");
|
||||
};
|
||||
|
||||
modification.modify(&modification_type);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ impl DocumentInputType {
|
||||
Self { name, data_type, default }
|
||||
}
|
||||
|
||||
pub const fn none() -> Self {
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
name: "None",
|
||||
data_type: FrontendGraphDataType::General,
|
||||
|
||||
@@ -1189,7 +1189,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
return;
|
||||
};
|
||||
if let Some(node) = network.nodes.get(&node_id) {
|
||||
let input = NodeInput::Value { tagged_value: value, exposed: false };
|
||||
let input = NodeInput::value(value, false);
|
||||
responses.add(NodeGraphMessage::SetNodeInput { node_id, input_index, input });
|
||||
responses.add(PropertiesPanelMessage::Refresh);
|
||||
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id) {
|
||||
@@ -1214,7 +1214,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
if input_index >= node.inputs.len() {
|
||||
node.inputs.extend(((node.inputs.len() - 1)..input_index).map(|_| NodeInput::network(generic!(T), 0)));
|
||||
}
|
||||
node.inputs[input_index] = NodeInput::Value { tagged_value: value, exposed: false };
|
||||
node.inputs[input_index] = NodeInput::value(value, false);
|
||||
if network.connected_to_output(node_id) {
|
||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||
}
|
||||
|
||||
@@ -91,11 +91,7 @@ fn start_widgets(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
fn text_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> Vec<WidgetHolder> {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::String(x),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(TaggedValue::String(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
TextInput::new(x.clone())
|
||||
@@ -110,11 +106,7 @@ fn text_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
|
||||
fn text_area_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> Vec<WidgetHolder> {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::String(x),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(TaggedValue::String(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
TextAreaInput::new(x.clone())
|
||||
@@ -129,14 +121,10 @@ fn text_area_widget(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||
fn bool_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> Vec<WidgetHolder> {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::Bool(x),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::Bool(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
CheckboxInput::new(*x)
|
||||
CheckboxInput::new(x)
|
||||
.on_update(update_value(|x: &CheckboxInput| TaggedValue::Bool(x.checked), node_id, index))
|
||||
.on_commit(commit_value)
|
||||
.widget_holder(),
|
||||
@@ -157,12 +145,7 @@ fn footprint_widget(document_node: &DocumentNode, node_id: NodeId, index: usize)
|
||||
add_blank_assist(&mut resolution_widgets);
|
||||
resolution_widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::Footprint(footprint),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
let footprint = *footprint;
|
||||
if let Some(&TaggedValue::Footprint(footprint)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let top_left = footprint.transform.transform_point2(DVec2::ZERO);
|
||||
let bounds = footprint.scale();
|
||||
let oversample = footprint.resolution.as_dvec2() / bounds;
|
||||
@@ -292,11 +275,7 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
|
||||
|
||||
assist(&mut widgets);
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::DVec2(dvec2),
|
||||
exposed: false,
|
||||
} = document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::DVec2(dvec2)) = document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
NumberInput::new(Some(dvec2.x))
|
||||
@@ -317,11 +296,7 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
|
||||
.on_commit(commit_value)
|
||||
.widget_holder(),
|
||||
]);
|
||||
} else if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::IVec2(ivec2),
|
||||
exposed: false,
|
||||
} = document_node.inputs[index]
|
||||
{
|
||||
} else if let Some(&TaggedValue::IVec2(ivec2)) = document_node.inputs[index].as_non_exposed_value() {
|
||||
let update_x = move |input: &NumberInput| TaggedValue::IVec2(IVec2::new(input.value.unwrap() as i32, ivec2.y));
|
||||
let update_y = move |input: &NumberInput| TaggedValue::IVec2(IVec2::new(ivec2.x, input.value.unwrap() as i32));
|
||||
widgets.extend_from_slice(&[
|
||||
@@ -346,11 +321,7 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
|
||||
.on_commit(commit_value)
|
||||
.widget_holder(),
|
||||
]);
|
||||
} else if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::UVec2(uvec2),
|
||||
exposed: false,
|
||||
} = document_node.inputs[index]
|
||||
{
|
||||
} else if let Some(&TaggedValue::UVec2(uvec2)) = document_node.inputs[index].as_non_exposed_value() {
|
||||
let update_x = move |input: &NumberInput| TaggedValue::UVec2(UVec2::new(input.value.unwrap() as u32, uvec2.y));
|
||||
let update_y = move |input: &NumberInput| TaggedValue::UVec2(UVec2::new(uvec2.x, input.value.unwrap() as u32));
|
||||
widgets.extend_from_slice(&[
|
||||
@@ -393,11 +364,7 @@ fn vec_f64_input(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
.map(TaggedValue::VecF64)
|
||||
};
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::VecF64(x),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(TaggedValue::VecF64(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
text_props
|
||||
@@ -422,11 +389,7 @@ fn vec_dvec2_input(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||
.map(TaggedValue::VecDVec2)
|
||||
};
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::VecDVec2(x),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(TaggedValue::VecDVec2(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
text_props
|
||||
@@ -444,11 +407,7 @@ fn font_inputs(document_node: &DocumentNode, node_id: NodeId, index: usize, name
|
||||
|
||||
let from_font_input = |font: &FontInput| TaggedValue::Font(Font::new(font.font_family.clone(), font.font_style.clone()));
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::Font(font),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(TaggedValue::Font(font)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
first_widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
FontInput::new(font.font_family.clone(), font.font_style.clone())
|
||||
@@ -484,11 +443,7 @@ fn vector_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
fn number_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, number_props: NumberInput, blank_assist: bool) -> Vec<WidgetHolder> {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Number, blank_assist);
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64(x),
|
||||
exposed: false,
|
||||
} = document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::F64(x)) = document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
number_props
|
||||
@@ -497,11 +452,7 @@ fn number_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
.on_commit(commit_value)
|
||||
.widget_holder(),
|
||||
])
|
||||
} else if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::U32(x),
|
||||
exposed: false,
|
||||
} = document_node.inputs[index]
|
||||
{
|
||||
} else if let Some(&TaggedValue::U32(x)) = document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
number_props
|
||||
@@ -517,11 +468,7 @@ fn number_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
// TODO: Generalize this instead of using a separate function per dropdown menu enum
|
||||
fn color_channel(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::RedGreenBlue(mode),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::RedGreenBlue(mode)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let calculation_modes = [RedGreenBlue::Red, RedGreenBlue::Green, RedGreenBlue::Blue];
|
||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||
for method in calculation_modes {
|
||||
@@ -544,11 +491,7 @@ fn color_channel(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
|
||||
fn rgba_channel(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::RedGreenBlueAlpha(mode),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::RedGreenBlueAlpha(mode)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let calculation_modes = [RedGreenBlueAlpha::Red, RedGreenBlueAlpha::Green, RedGreenBlueAlpha::Blue, RedGreenBlueAlpha::Alpha];
|
||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||
for method in calculation_modes {
|
||||
@@ -572,11 +515,7 @@ fn rgba_channel(document_node: &DocumentNode, node_id: NodeId, index: usize, nam
|
||||
// TODO: Generalize this instead of using a separate function per dropdown menu enum
|
||||
fn noise_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::NoiseType(noise_type),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::NoiseType(noise_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = NoiseType::list()
|
||||
.iter()
|
||||
.map(|noise_type| {
|
||||
@@ -598,11 +537,7 @@ fn noise_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name:
|
||||
// TODO: Generalize this instead of using a separate function per dropdown menu enum
|
||||
fn fractal_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::FractalType(fractal_type),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::FractalType(fractal_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = FractalType::list()
|
||||
.iter()
|
||||
.map(|fractal_type| {
|
||||
@@ -624,11 +559,7 @@ fn fractal_type(document_node: &DocumentNode, node_id: NodeId, index: usize, nam
|
||||
// TODO: Generalize this instead of using a separate function per dropdown menu enum
|
||||
fn cellular_distance_function(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::CellularDistanceFunction(cellular_distance_function),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::CellularDistanceFunction(cellular_distance_function)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = CellularDistanceFunction::list()
|
||||
.iter()
|
||||
.map(|cellular_distance_function| {
|
||||
@@ -653,11 +584,7 @@ fn cellular_distance_function(document_node: &DocumentNode, node_id: NodeId, ind
|
||||
// TODO: Generalize this instead of using a separate function per dropdown menu enum
|
||||
fn cellular_return_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::CellularReturnType(cellular_return_type),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::CellularReturnType(cellular_return_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = CellularReturnType::list()
|
||||
.iter()
|
||||
.map(|cellular_return_type| {
|
||||
@@ -679,11 +606,7 @@ fn cellular_return_type(document_node: &DocumentNode, node_id: NodeId, index: us
|
||||
// TODO: Generalize this instead of using a separate function per dropdown menu enum
|
||||
fn domain_warp_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::DomainWarpType(domain_warp_type),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::DomainWarpType(domain_warp_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = DomainWarpType::list()
|
||||
.iter()
|
||||
.map(|domain_warp_type| {
|
||||
@@ -705,11 +628,7 @@ fn domain_warp_type(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||
// TODO: Generalize this instead of using a separate function per dropdown menu enum
|
||||
fn blend_mode(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::BlendMode(blend_mode),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::BlendMode(blend_mode)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = BlendMode::list_svg_subset()
|
||||
.iter()
|
||||
.map(|category| {
|
||||
@@ -738,11 +657,7 @@ fn blend_mode(document_node: &DocumentNode, node_id: NodeId, index: usize, name:
|
||||
// TODO: Generalize this for all dropdowns (also see blend_mode and channel_extration)
|
||||
fn luminance_calculation(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::LuminanceCalculation(calculation),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::LuminanceCalculation(calculation)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let calculation_modes = LuminanceCalculation::list();
|
||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||
for method in calculation_modes {
|
||||
@@ -766,11 +681,7 @@ fn luminance_calculation(document_node: &DocumentNode, node_id: NodeId, index: u
|
||||
fn boolean_operation_radio_buttons(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::BooleanOperation(calculation),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::BooleanOperation(calculation)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let operations = BooleanOperation::list();
|
||||
let icons = BooleanOperation::icons();
|
||||
let mut entries = Vec::with_capacity(operations.len());
|
||||
@@ -795,11 +706,7 @@ fn boolean_operation_radio_buttons(document_node: &DocumentNode, node_id: NodeId
|
||||
|
||||
fn line_cap_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::LineCap(line_cap),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::LineCap(line_cap)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = [("Butt", LineCap::Butt), ("Round", LineCap::Round), ("Square", LineCap::Square)]
|
||||
.into_iter()
|
||||
.map(|(name, val)| {
|
||||
@@ -820,11 +727,7 @@ fn line_cap_widget(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||
|
||||
fn line_join_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::LineJoin(line_join),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::LineJoin(line_join)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = [("Miter", LineJoin::Miter), ("Bevel", LineJoin::Bevel), ("Round", LineJoin::Round)]
|
||||
.into_iter()
|
||||
.map(|(name, val)| {
|
||||
@@ -853,7 +756,7 @@ fn color_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, nam
|
||||
|
||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
|
||||
match tagged_value {
|
||||
match &**tagged_value {
|
||||
TaggedValue::Color(color) => widgets.push(
|
||||
color_props
|
||||
.value(FillChoice::Solid(*color))
|
||||
@@ -891,11 +794,7 @@ fn color_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, nam
|
||||
fn curves_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::Curve(curve),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(TaggedValue::Curve(curve)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
CurveInput::new(curve.clone())
|
||||
@@ -909,11 +808,7 @@ fn curves_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
|
||||
fn centroid_widget(document_node: &DocumentNode, node_id: NodeId, index: usize) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, "Centroid Type", FrontendGraphDataType::General, true);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::CentroidType(centroid_type),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::CentroidType(centroid_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||
let entries = vec![
|
||||
RadioEntryData::new("area")
|
||||
.label("Area")
|
||||
@@ -1054,25 +949,16 @@ pub fn extract_channel_properties(document_node: &DocumentNode, node_id: NodeId,
|
||||
// As soon as there are more types of noise, this should be uncommented.
|
||||
pub fn noise_pattern_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
// Get the current values of the inputs of interest so they can set whether certain inputs are disabled based on various conditions.
|
||||
let current_noise_type = match &document_node.inputs[4] {
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::NoiseType(noise_type),
|
||||
..
|
||||
} => Some(*noise_type),
|
||||
let current_noise_type = match &document_node.inputs[4].as_value() {
|
||||
Some(&TaggedValue::NoiseType(noise_type)) => Some(noise_type),
|
||||
_ => None,
|
||||
};
|
||||
let current_domain_warp_type = match &document_node.inputs[5] {
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::DomainWarpType(domain_warp_type),
|
||||
..
|
||||
} => Some(*domain_warp_type),
|
||||
let current_domain_warp_type = match &document_node.inputs[5].as_value() {
|
||||
Some(&TaggedValue::DomainWarpType(domain_warp_type)) => Some(domain_warp_type),
|
||||
_ => None,
|
||||
};
|
||||
let current_fractal_type = match &document_node.inputs[7] {
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::FractalType(fractal_type),
|
||||
..
|
||||
} => Some(*fractal_type),
|
||||
let current_fractal_type = match &document_node.inputs[7].as_value() {
|
||||
Some(&TaggedValue::FractalType(fractal_type)) => Some(fractal_type),
|
||||
_ => None,
|
||||
};
|
||||
let fractal_active = current_fractal_type != Some(FractalType::None);
|
||||
@@ -1262,11 +1148,7 @@ pub fn adjust_channel_mixer_properties(document_node: &DocumentNode, node_id: No
|
||||
// Monochrome
|
||||
let monochrome_index = 1;
|
||||
let monochrome = bool_widget(document_node, node_id, monochrome_index, "Monochrome", true);
|
||||
let is_monochrome = if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::Bool(monochrome_choice),
|
||||
..
|
||||
} = &document_node.inputs[monochrome_index]
|
||||
{
|
||||
let is_monochrome = if let Some(&TaggedValue::Bool(monochrome_choice)) = &document_node.inputs[monochrome_index].as_value() {
|
||||
monochrome_choice
|
||||
} else {
|
||||
false
|
||||
@@ -1276,11 +1158,7 @@ pub fn adjust_channel_mixer_properties(document_node: &DocumentNode, node_id: No
|
||||
let output_channel_index = 18;
|
||||
let mut output_channel = vec![TextLabel::new("Output Channel").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()];
|
||||
add_blank_assist(&mut output_channel);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::RedGreenBlue(choice),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[output_channel_index]
|
||||
{
|
||||
if let Some(&TaggedValue::RedGreenBlue(choice)) = &document_node.inputs[output_channel_index].as_non_exposed_value() {
|
||||
let entries = vec![
|
||||
RadioEntryData::new(format!("{:?}", RedGreenBlue::Red))
|
||||
.label(RedGreenBlue::Red.to_string())
|
||||
@@ -1297,11 +1175,7 @@ pub fn adjust_channel_mixer_properties(document_node: &DocumentNode, node_id: No
|
||||
];
|
||||
output_channel.extend([RadioInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
||||
};
|
||||
let is_output_channel = if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::RedGreenBlue(choice),
|
||||
..
|
||||
} = &document_node.inputs[output_channel_index]
|
||||
{
|
||||
let is_output_channel = if let Some(&TaggedValue::RedGreenBlue(choice)) = &document_node.inputs[output_channel_index].as_value() {
|
||||
choice
|
||||
} else {
|
||||
warn!("Channel Mixer node properties panel could not be displayed.");
|
||||
@@ -1369,11 +1243,7 @@ pub fn adjust_selective_color_properties(document_node: &DocumentNode, node_id:
|
||||
let colors_index = 38;
|
||||
let mut colors = vec![TextLabel::new("Colors").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()];
|
||||
add_blank_assist(&mut colors);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::SelectiveColorChoice(choice),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[colors_index]
|
||||
{
|
||||
if let Some(&TaggedValue::SelectiveColorChoice(choice)) = &document_node.inputs[colors_index].as_non_exposed_value() {
|
||||
use SelectiveColorChoice::*;
|
||||
let entries = [[Reds, Yellows, Greens, Cyans, Blues, Magentas].as_slice(), [Whites, Neutrals, Blacks].as_slice()]
|
||||
.into_iter()
|
||||
@@ -1391,11 +1261,7 @@ pub fn adjust_selective_color_properties(document_node: &DocumentNode, node_id:
|
||||
.collect();
|
||||
colors.extend([DropdownInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
||||
};
|
||||
let colors_choice_index = if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::SelectiveColorChoice(choice),
|
||||
..
|
||||
} = &document_node.inputs[colors_index]
|
||||
{
|
||||
let colors_choice_index = if let Some(&TaggedValue::SelectiveColorChoice(choice)) = &document_node.inputs[colors_index].as_value() {
|
||||
choice
|
||||
} else {
|
||||
warn!("Selective Color node properties panel could not be displayed.");
|
||||
@@ -1423,11 +1289,7 @@ pub fn adjust_selective_color_properties(document_node: &DocumentNode, node_id:
|
||||
let mode_index = 1;
|
||||
let mut mode = start_widgets(document_node, node_id, mode_index, "Mode", FrontendGraphDataType::General, true);
|
||||
mode.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::RelativeAbsolute(relative_or_absolute),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[mode_index]
|
||||
{
|
||||
if let Some(&TaggedValue::RelativeAbsolute(relative_or_absolute)) = &document_node.inputs[mode_index].as_non_exposed_value() {
|
||||
let entries = vec![
|
||||
RadioEntryData::new("relative")
|
||||
.label("Relative")
|
||||
@@ -1597,32 +1459,16 @@ pub fn rectangle_properties(document_node: &DocumentNode, node_id: NodeId, _cont
|
||||
corner_radius_row_2.push(TextLabel::new("").widget_holder());
|
||||
add_blank_assist(&mut corner_radius_row_2);
|
||||
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::Bool(is_individual),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[corner_rounding_type_index]
|
||||
{
|
||||
if let Some(&TaggedValue::Bool(is_individual)) = &document_node.inputs[corner_rounding_type_index].as_non_exposed_value() {
|
||||
// Values
|
||||
let uniform_val = match document_node.inputs[corner_radius_index] {
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64(x),
|
||||
exposed: false,
|
||||
} => x,
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64Array4(x),
|
||||
exposed: false,
|
||||
} => x[0],
|
||||
let uniform_val = match document_node.inputs[corner_radius_index].as_non_exposed_value() {
|
||||
Some(TaggedValue::F64(x)) => *x,
|
||||
Some(TaggedValue::F64Array4(x)) => x[0],
|
||||
_ => 0.,
|
||||
};
|
||||
let individual_val = match document_node.inputs[corner_radius_index] {
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64Array4(x),
|
||||
exposed: false,
|
||||
} => x,
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64(x),
|
||||
exposed: false,
|
||||
} => [x; 4],
|
||||
let individual_val = match document_node.inputs[corner_radius_index].as_non_exposed_value() {
|
||||
Some(&TaggedValue::F64Array4(x)) => x,
|
||||
Some(&TaggedValue::F64(x)) => [x; 4],
|
||||
_ => [0.; 4],
|
||||
};
|
||||
|
||||
@@ -1747,11 +1593,7 @@ pub fn transform_properties(document_node: &DocumentNode, node_id: NodeId, _cont
|
||||
|
||||
let mut widgets = start_widgets(document_node, node_id, index, "Rotation", FrontendGraphDataType::Number, true);
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64(val),
|
||||
exposed: false,
|
||||
} = document_node.inputs[index]
|
||||
{
|
||||
if let Some(&TaggedValue::F64(val)) = document_node.inputs[index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
NumberInput::new(Some(val.to_degrees()))
|
||||
@@ -1846,20 +1688,12 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||
LayoutGroup::Row { widgets }.with_tooltip("Connection status to the server that computes generated images")
|
||||
};
|
||||
|
||||
let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::ImaginateController(ref controller),
|
||||
..
|
||||
} = controller
|
||||
else {
|
||||
let Some(TaggedValue::ImaginateController(controller)) = controller.as_value() else {
|
||||
panic!("Invalid output status input")
|
||||
};
|
||||
let imaginate_status = controller.get_status();
|
||||
|
||||
let use_base_image = if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::Bool(use_base_image),
|
||||
..
|
||||
} = &document_node.inputs[base_img_index]
|
||||
{
|
||||
let use_base_image = if let Some(&TaggedValue::Bool(use_base_image)) = &document_node.inputs[base_img_index].as_value() {
|
||||
use_base_image
|
||||
} else {
|
||||
true
|
||||
@@ -1958,11 +1792,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||
let seed = {
|
||||
let mut widgets = start_widgets(document_node, node_id, seed_index, "Seed", FrontendGraphDataType::Number, false);
|
||||
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::F64(seed),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[seed_index]
|
||||
{
|
||||
if let Some(&TaggedValue::F64(seed)) = &document_node.inputs[seed_index].as_non_exposed_value() {
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
IconButton::new("Regenerate", 24)
|
||||
@@ -2029,11 +1859,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||
DVec2::new(x as f64, y as f64)
|
||||
};
|
||||
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::OptionalDVec2(vec2),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[resolution_index]
|
||||
{
|
||||
if let Some(&TaggedValue::OptionalDVec2(vec2)) = &document_node.inputs[resolution_index].as_non_exposed_value() {
|
||||
let dimensions_is_auto = vec2.is_none();
|
||||
let vec2 = vec2.unwrap_or_else(|| round((image_size.0 as f64, image_size.1 as f64).into()));
|
||||
|
||||
@@ -2112,11 +1938,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||
let sampling_method = {
|
||||
let mut widgets = start_widgets(document_node, node_id, sampling_method_index, "Sampling Method", FrontendGraphDataType::General, true);
|
||||
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::ImaginateSamplingMethod(sampling_method),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[sampling_method_index]
|
||||
{
|
||||
if let Some(&TaggedValue::ImaginateSamplingMethod(sampling_method)) = &document_node.inputs[sampling_method_index].as_non_exposed_value() {
|
||||
let sampling_methods = ImaginateSamplingMethod::list();
|
||||
let mut entries = Vec::with_capacity(sampling_methods.len());
|
||||
for method in sampling_methods {
|
||||
@@ -2197,10 +2019,8 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||
// let in_paint = {
|
||||
// let mut widgets = start_widgets(document_node, node_id, inpaint_index, "Inpaint", FrontendGraphDataType::Boolean, true);
|
||||
|
||||
// if let &NodeInput::Value {
|
||||
// tagged_value: TaggedValue::Bool(in_paint),
|
||||
// exposed: false,
|
||||
// } = &document_node.inputs[inpaint_index]
|
||||
// if let Some(& TaggedValue::Bool(in_paint)
|
||||
//)/ } = &document_node.inputs[inpaint_index].as_non_exposed_value()
|
||||
// {
|
||||
// widgets.extend_from_slice(&[
|
||||
// Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
@@ -2232,10 +2052,8 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
||||
// let mask_starting_fill = {
|
||||
// let mut widgets = start_widgets(document_node, node_id, mask_fill_index, "Mask Starting Fill", FrontendGraphDataType::General, true);
|
||||
|
||||
// if let &NodeInput::Value {
|
||||
// tagged_value: TaggedValue::ImaginateMaskStartingFill(starting_fill),
|
||||
// exposed: false,
|
||||
// } = &document_node.inputs[mask_fill_index]
|
||||
// if let Some(& TaggedValue::ImaginateMaskStartingFill(starting_fill)
|
||||
//)/ } = &document_node.inputs[mask_fill_index].as_non_exposed_value()
|
||||
// {
|
||||
// let mask_fill_content_modes = ImaginateMaskStartingFill::list();
|
||||
// let mut entries = Vec::with_capacity(mask_fill_content_modes.len());
|
||||
@@ -2450,30 +2268,17 @@ pub fn fill_properties(document_node: &DocumentNode, node_id: NodeId, _context:
|
||||
|
||||
let mut widgets_first_row = start_widgets(document_node, node_id, fill_index, "Fill", FrontendGraphDataType::General, true);
|
||||
|
||||
let (fill, backup_color, backup_gradient) = if let (
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::Fill(fill),
|
||||
..
|
||||
},
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::OptionalColor(backup_color),
|
||||
..
|
||||
},
|
||||
NodeInput::Value {
|
||||
tagged_value: TaggedValue::Gradient(backup_gradient),
|
||||
..
|
||||
},
|
||||
) = (
|
||||
&document_node.inputs[fill_index],
|
||||
&document_node.inputs[backup_color_index],
|
||||
&document_node.inputs[backup_gradient_index],
|
||||
let (fill, backup_color, backup_gradient) = if let (Some(TaggedValue::Fill(fill)), Some(&TaggedValue::OptionalColor(backup_color)), Some(TaggedValue::Gradient(backup_gradient))) = (
|
||||
&document_node.inputs[fill_index].as_value(),
|
||||
&document_node.inputs[backup_color_index].as_value(),
|
||||
&document_node.inputs[backup_gradient_index].as_value(),
|
||||
) {
|
||||
(fill, backup_color, backup_gradient)
|
||||
} else {
|
||||
return vec![LayoutGroup::Row { widgets: widgets_first_row }];
|
||||
};
|
||||
let fill2 = fill.clone();
|
||||
let backup_color_fill: Fill = (*backup_color).into();
|
||||
let backup_color_fill: Fill = backup_color.into();
|
||||
let backup_gradient_fill: Fill = backup_gradient.clone().into();
|
||||
|
||||
widgets_first_row.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
|
||||
Reference in New Issue
Block a user