mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 05:18: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();
|
let mut fonts = HashSet::new();
|
||||||
for (_node_id, node) in self.network.recursive_nodes() {
|
for (_node_id, node) in self.network.recursive_nodes() {
|
||||||
for input in &node.inputs {
|
for input in &node.inputs {
|
||||||
if let NodeInput::Value {
|
if let Some(TaggedValue::Font(font)) = input.as_value() {
|
||||||
tagged_value: TaggedValue::Font(font),
|
|
||||||
..
|
|
||||||
} = input
|
|
||||||
{
|
|
||||||
fonts.insert(font.clone());
|
fonts.insert(font.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2134,7 +2130,7 @@ fn root_network() -> NodeNetwork {
|
|||||||
{
|
{
|
||||||
NodeNetwork {
|
NodeNetwork {
|
||||||
exports: vec![NodeInput::Value {
|
exports: vec![NodeInput::Value {
|
||||||
tagged_value: TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY),
|
tagged_value: TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY).into(),
|
||||||
exposed: true,
|
exposed: true,
|
||||||
}],
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
@@ -70,56 +70,24 @@ impl LayerBounds {
|
|||||||
|
|
||||||
/// Get the current affine transform from the transform node's inputs
|
/// Get the current affine transform from the transform node's inputs
|
||||||
pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 {
|
pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 {
|
||||||
let translation = if let NodeInput::Value {
|
let translation = if let Some(&TaggedValue::DVec2(translation)) = inputs[1].as_value() {
|
||||||
tagged_value: TaggedValue::DVec2(translation),
|
|
||||||
..
|
|
||||||
} = inputs[1]
|
|
||||||
{
|
|
||||||
translation
|
translation
|
||||||
} else {
|
} else {
|
||||||
DVec2::ZERO
|
DVec2::ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
let angle = if let NodeInput::Value {
|
let angle = if let Some(&TaggedValue::F64(angle)) = inputs[2].as_value() { angle } else { 0. };
|
||||||
tagged_value: TaggedValue::F64(angle),
|
|
||||||
..
|
|
||||||
} = inputs[2]
|
|
||||||
{
|
|
||||||
angle
|
|
||||||
} else {
|
|
||||||
0.
|
|
||||||
};
|
|
||||||
|
|
||||||
let scale = if let NodeInput::Value {
|
let scale = if let Some(&TaggedValue::DVec2(scale)) = inputs[3].as_value() { scale } else { DVec2::ONE };
|
||||||
tagged_value: TaggedValue::DVec2(scale),
|
|
||||||
..
|
|
||||||
} = inputs[3]
|
|
||||||
{
|
|
||||||
scale
|
|
||||||
} else {
|
|
||||||
DVec2::ONE
|
|
||||||
};
|
|
||||||
|
|
||||||
let shear = if let NodeInput::Value {
|
let shear = if let Some(&TaggedValue::DVec2(shear)) = inputs[4].as_value() { shear } else { DVec2::ZERO };
|
||||||
tagged_value: TaggedValue::DVec2(shear),
|
|
||||||
..
|
|
||||||
} = inputs[4]
|
|
||||||
{
|
|
||||||
shear
|
|
||||||
} else {
|
|
||||||
DVec2::ZERO
|
|
||||||
};
|
|
||||||
|
|
||||||
DAffine2::from_scale_angle_translation(scale, angle, translation) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.])
|
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
|
/// Extract the current normalized pivot from the layer
|
||||||
pub fn get_current_normalized_pivot(inputs: &[NodeInput]) -> DVec2 {
|
pub fn get_current_normalized_pivot(inputs: &[NodeInput]) -> DVec2 {
|
||||||
if let NodeInput::Value {
|
if let Some(&TaggedValue::DVec2(pivot)) = inputs[5].as_value() {
|
||||||
tagged_value: TaggedValue::DVec2(pivot),
|
|
||||||
..
|
|
||||||
} = inputs[5]
|
|
||||||
{
|
|
||||||
pivot
|
pivot
|
||||||
} else {
|
} else {
|
||||||
DVec2::splat(0.5)
|
DVec2::splat(0.5)
|
||||||
|
|||||||
@@ -657,14 +657,12 @@ impl<'a> ModifyInputsContext<'a> {
|
|||||||
|
|
||||||
pub fn vector_modify(&mut self, modification_type: VectorModificationType) {
|
pub fn vector_modify(&mut self, modification_type: VectorModificationType) {
|
||||||
self.modify_inputs("Path", false, |inputs, _node_id, _metadata| {
|
self.modify_inputs("Path", false, |inputs, _node_id, _metadata| {
|
||||||
let [_, NodeInput::Value {
|
let Some(NodeInput::Value { tagged_value, .. }) = inputs.iter_mut().skip(1).next() else {
|
||||||
tagged_value: TaggedValue::VectorModification(modification),
|
panic!("Path node does not have modification input");
|
||||||
..
|
};
|
||||||
}] = inputs.as_mut_slice()
|
let TaggedValue::VectorModification(modification) = &mut *tagged_value.inner_mut() else {
|
||||||
else {
|
|
||||||
panic!("Path node does not have modification input");
|
panic!("Path node does not have modification input");
|
||||||
};
|
};
|
||||||
|
|
||||||
modification.modify(&modification_type);
|
modification.modify(&modification_type);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ impl DocumentInputType {
|
|||||||
Self { name, data_type, default }
|
Self { name, data_type, default }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn none() -> Self {
|
pub fn none() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: "None",
|
name: "None",
|
||||||
data_type: FrontendGraphDataType::General,
|
data_type: FrontendGraphDataType::General,
|
||||||
|
|||||||
@@ -1189,7 +1189,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let Some(node) = network.nodes.get(&node_id) {
|
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(NodeGraphMessage::SetNodeInput { node_id, input_index, input });
|
||||||
responses.add(PropertiesPanelMessage::Refresh);
|
responses.add(PropertiesPanelMessage::Refresh);
|
||||||
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id) {
|
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() {
|
if input_index >= node.inputs.len() {
|
||||||
node.inputs.extend(((node.inputs.len() - 1)..input_index).map(|_| NodeInput::network(generic!(T), 0)));
|
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) {
|
if network.connected_to_output(node_id) {
|
||||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
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> {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(TaggedValue::String(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::String(x),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
TextInput::new(x.clone())
|
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> {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(TaggedValue::String(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::String(x),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
TextAreaInput::new(x.clone())
|
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> {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(&TaggedValue::Bool(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::Bool(x),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
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_update(update_value(|x: &CheckboxInput| TaggedValue::Bool(x.checked), node_id, index))
|
||||||
.on_commit(commit_value)
|
.on_commit(commit_value)
|
||||||
.widget_holder(),
|
.widget_holder(),
|
||||||
@@ -157,12 +145,7 @@ fn footprint_widget(document_node: &DocumentNode, node_id: NodeId, index: usize)
|
|||||||
add_blank_assist(&mut resolution_widgets);
|
add_blank_assist(&mut resolution_widgets);
|
||||||
resolution_widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
resolution_widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(&TaggedValue::Footprint(footprint)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::Footprint(footprint),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let footprint = *footprint;
|
|
||||||
let top_left = footprint.transform.transform_point2(DVec2::ZERO);
|
let top_left = footprint.transform.transform_point2(DVec2::ZERO);
|
||||||
let bounds = footprint.scale();
|
let bounds = footprint.scale();
|
||||||
let oversample = footprint.resolution.as_dvec2() / bounds;
|
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);
|
assist(&mut widgets);
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(&TaggedValue::DVec2(dvec2)) = document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::DVec2(dvec2),
|
|
||||||
exposed: false,
|
|
||||||
} = document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
NumberInput::new(Some(dvec2.x))
|
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)
|
.on_commit(commit_value)
|
||||||
.widget_holder(),
|
.widget_holder(),
|
||||||
]);
|
]);
|
||||||
} else if let NodeInput::Value {
|
} else if let Some(&TaggedValue::IVec2(ivec2)) = document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::IVec2(ivec2),
|
|
||||||
exposed: false,
|
|
||||||
} = document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let update_x = move |input: &NumberInput| TaggedValue::IVec2(IVec2::new(input.value.unwrap() as i32, ivec2.y));
|
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));
|
let update_y = move |input: &NumberInput| TaggedValue::IVec2(IVec2::new(ivec2.x, input.value.unwrap() as i32));
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
@@ -346,11 +321,7 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
|
|||||||
.on_commit(commit_value)
|
.on_commit(commit_value)
|
||||||
.widget_holder(),
|
.widget_holder(),
|
||||||
]);
|
]);
|
||||||
} else if let NodeInput::Value {
|
} else if let Some(&TaggedValue::UVec2(uvec2)) = document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::UVec2(uvec2),
|
|
||||||
exposed: false,
|
|
||||||
} = document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let update_x = move |input: &NumberInput| TaggedValue::UVec2(UVec2::new(input.value.unwrap() as u32, uvec2.y));
|
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));
|
let update_y = move |input: &NumberInput| TaggedValue::UVec2(UVec2::new(uvec2.x, input.value.unwrap() as u32));
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
@@ -393,11 +364,7 @@ fn vec_f64_input(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
|||||||
.map(TaggedValue::VecF64)
|
.map(TaggedValue::VecF64)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(TaggedValue::VecF64(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::VecF64(x),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
text_props
|
text_props
|
||||||
@@ -422,11 +389,7 @@ fn vec_dvec2_input(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
|||||||
.map(TaggedValue::VecDVec2)
|
.map(TaggedValue::VecDVec2)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(TaggedValue::VecDVec2(x)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::VecDVec2(x),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
text_props
|
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()));
|
let from_font_input = |font: &FontInput| TaggedValue::Font(Font::new(font.font_family.clone(), font.font_style.clone()));
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(TaggedValue::Font(font)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::Font(font),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
first_widgets.extend_from_slice(&[
|
first_widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
FontInput::new(font.font_family.clone(), font.font_style.clone())
|
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> {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Number, blank_assist);
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(&TaggedValue::F64(x)) = document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::F64(x),
|
|
||||||
exposed: false,
|
|
||||||
} = document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
number_props
|
number_props
|
||||||
@@ -497,11 +452,7 @@ fn number_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
|||||||
.on_commit(commit_value)
|
.on_commit(commit_value)
|
||||||
.widget_holder(),
|
.widget_holder(),
|
||||||
])
|
])
|
||||||
} else if let NodeInput::Value {
|
} else if let Some(&TaggedValue::U32(x)) = document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::U32(x),
|
|
||||||
exposed: false,
|
|
||||||
} = document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
number_props
|
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
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::RedGreenBlue(mode)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::RedGreenBlue(mode),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let calculation_modes = [RedGreenBlue::Red, RedGreenBlue::Green, RedGreenBlue::Blue];
|
let calculation_modes = [RedGreenBlue::Red, RedGreenBlue::Green, RedGreenBlue::Blue];
|
||||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||||
for method in calculation_modes {
|
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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::RedGreenBlueAlpha(mode)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::RedGreenBlueAlpha(mode),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let calculation_modes = [RedGreenBlueAlpha::Red, RedGreenBlueAlpha::Green, RedGreenBlueAlpha::Blue, RedGreenBlueAlpha::Alpha];
|
let calculation_modes = [RedGreenBlueAlpha::Red, RedGreenBlueAlpha::Green, RedGreenBlueAlpha::Blue, RedGreenBlueAlpha::Alpha];
|
||||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||||
for method in calculation_modes {
|
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
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::NoiseType(noise_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::NoiseType(noise_type),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = NoiseType::list()
|
let entries = NoiseType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|noise_type| {
|
.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
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::FractalType(fractal_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::FractalType(fractal_type),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = FractalType::list()
|
let entries = FractalType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|fractal_type| {
|
.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
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::CellularDistanceFunction(cellular_distance_function)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::CellularDistanceFunction(cellular_distance_function),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = CellularDistanceFunction::list()
|
let entries = CellularDistanceFunction::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cellular_distance_function| {
|
.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
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::CellularReturnType(cellular_return_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::CellularReturnType(cellular_return_type),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = CellularReturnType::list()
|
let entries = CellularReturnType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cellular_return_type| {
|
.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
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::DomainWarpType(domain_warp_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::DomainWarpType(domain_warp_type),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = DomainWarpType::list()
|
let entries = DomainWarpType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|domain_warp_type| {
|
.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
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::BlendMode(blend_mode)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::BlendMode(blend_mode),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = BlendMode::list_svg_subset()
|
let entries = BlendMode::list_svg_subset()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|category| {
|
.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)
|
// 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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::LuminanceCalculation(calculation)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::LuminanceCalculation(calculation),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let calculation_modes = LuminanceCalculation::list();
|
let calculation_modes = LuminanceCalculation::list();
|
||||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||||
for method in calculation_modes {
|
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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
|
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::BooleanOperation(calculation)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::BooleanOperation(calculation),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let operations = BooleanOperation::list();
|
let operations = BooleanOperation::list();
|
||||||
let icons = BooleanOperation::icons();
|
let icons = BooleanOperation::icons();
|
||||||
let mut entries = Vec::with_capacity(operations.len());
|
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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::LineCap(line_cap)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::LineCap(line_cap),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = [("Butt", LineCap::Butt), ("Round", LineCap::Round), ("Square", LineCap::Square)]
|
let entries = [("Butt", LineCap::Butt), ("Round", LineCap::Round), ("Square", LineCap::Square)]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, val)| {
|
.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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::LineJoin(line_join)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::LineJoin(line_join),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = [("Miter", LineJoin::Miter), ("Bevel", LineJoin::Bevel), ("Round", LineJoin::Round)]
|
let entries = [("Miter", LineJoin::Miter), ("Bevel", LineJoin::Bevel), ("Round", LineJoin::Round)]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, val)| {
|
.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());
|
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||||
|
|
||||||
match tagged_value {
|
match &**tagged_value {
|
||||||
TaggedValue::Color(color) => widgets.push(
|
TaggedValue::Color(color) => widgets.push(
|
||||||
color_props
|
color_props
|
||||||
.value(FillChoice::Solid(*color))
|
.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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(TaggedValue::Curve(curve)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::Curve(curve),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
CurveInput::new(curve.clone())
|
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 {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, "Centroid Type", FrontendGraphDataType::General, true);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::CentroidType(centroid_type)) = &document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::CentroidType(centroid_type),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[index]
|
|
||||||
{
|
|
||||||
let entries = vec![
|
let entries = vec![
|
||||||
RadioEntryData::new("area")
|
RadioEntryData::new("area")
|
||||||
.label("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.
|
// 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> {
|
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.
|
// 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] {
|
let current_noise_type = match &document_node.inputs[4].as_value() {
|
||||||
NodeInput::Value {
|
Some(&TaggedValue::NoiseType(noise_type)) => Some(noise_type),
|
||||||
tagged_value: TaggedValue::NoiseType(noise_type),
|
|
||||||
..
|
|
||||||
} => Some(*noise_type),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let current_domain_warp_type = match &document_node.inputs[5] {
|
let current_domain_warp_type = match &document_node.inputs[5].as_value() {
|
||||||
NodeInput::Value {
|
Some(&TaggedValue::DomainWarpType(domain_warp_type)) => Some(domain_warp_type),
|
||||||
tagged_value: TaggedValue::DomainWarpType(domain_warp_type),
|
|
||||||
..
|
|
||||||
} => Some(*domain_warp_type),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let current_fractal_type = match &document_node.inputs[7] {
|
let current_fractal_type = match &document_node.inputs[7].as_value() {
|
||||||
NodeInput::Value {
|
Some(&TaggedValue::FractalType(fractal_type)) => Some(fractal_type),
|
||||||
tagged_value: TaggedValue::FractalType(fractal_type),
|
|
||||||
..
|
|
||||||
} => Some(*fractal_type),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let fractal_active = current_fractal_type != Some(FractalType::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
|
// Monochrome
|
||||||
let monochrome_index = 1;
|
let monochrome_index = 1;
|
||||||
let monochrome = bool_widget(document_node, node_id, monochrome_index, "Monochrome", true);
|
let monochrome = bool_widget(document_node, node_id, monochrome_index, "Monochrome", true);
|
||||||
let is_monochrome = if let &NodeInput::Value {
|
let is_monochrome = if let Some(&TaggedValue::Bool(monochrome_choice)) = &document_node.inputs[monochrome_index].as_value() {
|
||||||
tagged_value: TaggedValue::Bool(monochrome_choice),
|
|
||||||
..
|
|
||||||
} = &document_node.inputs[monochrome_index]
|
|
||||||
{
|
|
||||||
monochrome_choice
|
monochrome_choice
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -1276,11 +1158,7 @@ pub fn adjust_channel_mixer_properties(document_node: &DocumentNode, node_id: No
|
|||||||
let output_channel_index = 18;
|
let output_channel_index = 18;
|
||||||
let mut output_channel = vec![TextLabel::new("Output Channel").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()];
|
let mut output_channel = vec![TextLabel::new("Output Channel").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()];
|
||||||
add_blank_assist(&mut output_channel);
|
add_blank_assist(&mut output_channel);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::RedGreenBlue(choice)) = &document_node.inputs[output_channel_index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::RedGreenBlue(choice),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[output_channel_index]
|
|
||||||
{
|
|
||||||
let entries = vec![
|
let entries = vec![
|
||||||
RadioEntryData::new(format!("{:?}", RedGreenBlue::Red))
|
RadioEntryData::new(format!("{:?}", RedGreenBlue::Red))
|
||||||
.label(RedGreenBlue::Red.to_string())
|
.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()]);
|
output_channel.extend([RadioInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
||||||
};
|
};
|
||||||
let is_output_channel = if let &NodeInput::Value {
|
let is_output_channel = if let Some(&TaggedValue::RedGreenBlue(choice)) = &document_node.inputs[output_channel_index].as_value() {
|
||||||
tagged_value: TaggedValue::RedGreenBlue(choice),
|
|
||||||
..
|
|
||||||
} = &document_node.inputs[output_channel_index]
|
|
||||||
{
|
|
||||||
choice
|
choice
|
||||||
} else {
|
} else {
|
||||||
warn!("Channel Mixer node properties panel could not be displayed.");
|
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 colors_index = 38;
|
||||||
let mut colors = vec![TextLabel::new("Colors").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()];
|
let mut colors = vec![TextLabel::new("Colors").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()];
|
||||||
add_blank_assist(&mut colors);
|
add_blank_assist(&mut colors);
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::SelectiveColorChoice(choice)) = &document_node.inputs[colors_index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::SelectiveColorChoice(choice),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[colors_index]
|
|
||||||
{
|
|
||||||
use SelectiveColorChoice::*;
|
use SelectiveColorChoice::*;
|
||||||
let entries = [[Reds, Yellows, Greens, Cyans, Blues, Magentas].as_slice(), [Whites, Neutrals, Blacks].as_slice()]
|
let entries = [[Reds, Yellows, Greens, Cyans, Blues, Magentas].as_slice(), [Whites, Neutrals, Blacks].as_slice()]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -1391,11 +1261,7 @@ pub fn adjust_selective_color_properties(document_node: &DocumentNode, node_id:
|
|||||||
.collect();
|
.collect();
|
||||||
colors.extend([DropdownInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
colors.extend([DropdownInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
||||||
};
|
};
|
||||||
let colors_choice_index = if let &NodeInput::Value {
|
let colors_choice_index = if let Some(&TaggedValue::SelectiveColorChoice(choice)) = &document_node.inputs[colors_index].as_value() {
|
||||||
tagged_value: TaggedValue::SelectiveColorChoice(choice),
|
|
||||||
..
|
|
||||||
} = &document_node.inputs[colors_index]
|
|
||||||
{
|
|
||||||
choice
|
choice
|
||||||
} else {
|
} else {
|
||||||
warn!("Selective Color node properties panel could not be displayed.");
|
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 mode_index = 1;
|
||||||
let mut mode = start_widgets(document_node, node_id, mode_index, "Mode", FrontendGraphDataType::General, true);
|
let mut mode = start_widgets(document_node, node_id, mode_index, "Mode", FrontendGraphDataType::General, true);
|
||||||
mode.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
mode.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::RelativeAbsolute(relative_or_absolute)) = &document_node.inputs[mode_index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::RelativeAbsolute(relative_or_absolute),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[mode_index]
|
|
||||||
{
|
|
||||||
let entries = vec![
|
let entries = vec![
|
||||||
RadioEntryData::new("relative")
|
RadioEntryData::new("relative")
|
||||||
.label("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());
|
corner_radius_row_2.push(TextLabel::new("").widget_holder());
|
||||||
add_blank_assist(&mut corner_radius_row_2);
|
add_blank_assist(&mut corner_radius_row_2);
|
||||||
|
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::Bool(is_individual)) = &document_node.inputs[corner_rounding_type_index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::Bool(is_individual),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[corner_rounding_type_index]
|
|
||||||
{
|
|
||||||
// Values
|
// Values
|
||||||
let uniform_val = match document_node.inputs[corner_radius_index] {
|
let uniform_val = match document_node.inputs[corner_radius_index].as_non_exposed_value() {
|
||||||
NodeInput::Value {
|
Some(TaggedValue::F64(x)) => *x,
|
||||||
tagged_value: TaggedValue::F64(x),
|
Some(TaggedValue::F64Array4(x)) => x[0],
|
||||||
exposed: false,
|
|
||||||
} => x,
|
|
||||||
NodeInput::Value {
|
|
||||||
tagged_value: TaggedValue::F64Array4(x),
|
|
||||||
exposed: false,
|
|
||||||
} => x[0],
|
|
||||||
_ => 0.,
|
_ => 0.,
|
||||||
};
|
};
|
||||||
let individual_val = match document_node.inputs[corner_radius_index] {
|
let individual_val = match document_node.inputs[corner_radius_index].as_non_exposed_value() {
|
||||||
NodeInput::Value {
|
Some(&TaggedValue::F64Array4(x)) => x,
|
||||||
tagged_value: TaggedValue::F64Array4(x),
|
Some(&TaggedValue::F64(x)) => [x; 4],
|
||||||
exposed: false,
|
|
||||||
} => x,
|
|
||||||
NodeInput::Value {
|
|
||||||
tagged_value: TaggedValue::F64(x),
|
|
||||||
exposed: false,
|
|
||||||
} => [x; 4],
|
|
||||||
_ => [0.; 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);
|
let mut widgets = start_widgets(document_node, node_id, index, "Rotation", FrontendGraphDataType::Number, true);
|
||||||
|
|
||||||
if let NodeInput::Value {
|
if let Some(&TaggedValue::F64(val)) = document_node.inputs[index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::F64(val),
|
|
||||||
exposed: false,
|
|
||||||
} = document_node.inputs[index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
NumberInput::new(Some(val.to_degrees()))
|
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")
|
LayoutGroup::Row { widgets }.with_tooltip("Connection status to the server that computes generated images")
|
||||||
};
|
};
|
||||||
|
|
||||||
let &NodeInput::Value {
|
let Some(TaggedValue::ImaginateController(controller)) = controller.as_value() else {
|
||||||
tagged_value: TaggedValue::ImaginateController(ref controller),
|
|
||||||
..
|
|
||||||
} = controller
|
|
||||||
else {
|
|
||||||
panic!("Invalid output status input")
|
panic!("Invalid output status input")
|
||||||
};
|
};
|
||||||
let imaginate_status = controller.get_status();
|
let imaginate_status = controller.get_status();
|
||||||
|
|
||||||
let use_base_image = if let &NodeInput::Value {
|
let use_base_image = if let Some(&TaggedValue::Bool(use_base_image)) = &document_node.inputs[base_img_index].as_value() {
|
||||||
tagged_value: TaggedValue::Bool(use_base_image),
|
|
||||||
..
|
|
||||||
} = &document_node.inputs[base_img_index]
|
|
||||||
{
|
|
||||||
use_base_image
|
use_base_image
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@@ -1958,11 +1792,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
|||||||
let seed = {
|
let seed = {
|
||||||
let mut widgets = start_widgets(document_node, node_id, seed_index, "Seed", FrontendGraphDataType::Number, false);
|
let mut widgets = start_widgets(document_node, node_id, seed_index, "Seed", FrontendGraphDataType::Number, false);
|
||||||
|
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::F64(seed)) = &document_node.inputs[seed_index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::F64(seed),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[seed_index]
|
|
||||||
{
|
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
IconButton::new("Regenerate", 24)
|
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)
|
DVec2::new(x as f64, y as f64)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::OptionalDVec2(vec2)) = &document_node.inputs[resolution_index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::OptionalDVec2(vec2),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[resolution_index]
|
|
||||||
{
|
|
||||||
let dimensions_is_auto = vec2.is_none();
|
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()));
|
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 sampling_method = {
|
||||||
let mut widgets = start_widgets(document_node, node_id, sampling_method_index, "Sampling Method", FrontendGraphDataType::General, true);
|
let mut widgets = start_widgets(document_node, node_id, sampling_method_index, "Sampling Method", FrontendGraphDataType::General, true);
|
||||||
|
|
||||||
if let &NodeInput::Value {
|
if let Some(&TaggedValue::ImaginateSamplingMethod(sampling_method)) = &document_node.inputs[sampling_method_index].as_non_exposed_value() {
|
||||||
tagged_value: TaggedValue::ImaginateSamplingMethod(sampling_method),
|
|
||||||
exposed: false,
|
|
||||||
} = &document_node.inputs[sampling_method_index]
|
|
||||||
{
|
|
||||||
let sampling_methods = ImaginateSamplingMethod::list();
|
let sampling_methods = ImaginateSamplingMethod::list();
|
||||||
let mut entries = Vec::with_capacity(sampling_methods.len());
|
let mut entries = Vec::with_capacity(sampling_methods.len());
|
||||||
for method in sampling_methods {
|
for method in sampling_methods {
|
||||||
@@ -2197,10 +2019,8 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
|||||||
// let in_paint = {
|
// let in_paint = {
|
||||||
// let mut widgets = start_widgets(document_node, node_id, inpaint_index, "Inpaint", FrontendGraphDataType::Boolean, true);
|
// let mut widgets = start_widgets(document_node, node_id, inpaint_index, "Inpaint", FrontendGraphDataType::Boolean, true);
|
||||||
|
|
||||||
// if let &NodeInput::Value {
|
// if let Some(& TaggedValue::Bool(in_paint)
|
||||||
// tagged_value: TaggedValue::Bool(in_paint),
|
//)/ } = &document_node.inputs[inpaint_index].as_non_exposed_value()
|
||||||
// exposed: false,
|
|
||||||
// } = &document_node.inputs[inpaint_index]
|
|
||||||
// {
|
// {
|
||||||
// widgets.extend_from_slice(&[
|
// widgets.extend_from_slice(&[
|
||||||
// Separator::new(SeparatorType::Unrelated).widget_holder(),
|
// 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 mask_starting_fill = {
|
||||||
// let mut widgets = start_widgets(document_node, node_id, mask_fill_index, "Mask Starting Fill", FrontendGraphDataType::General, true);
|
// let mut widgets = start_widgets(document_node, node_id, mask_fill_index, "Mask Starting Fill", FrontendGraphDataType::General, true);
|
||||||
|
|
||||||
// if let &NodeInput::Value {
|
// if let Some(& TaggedValue::ImaginateMaskStartingFill(starting_fill)
|
||||||
// tagged_value: TaggedValue::ImaginateMaskStartingFill(starting_fill),
|
//)/ } = &document_node.inputs[mask_fill_index].as_non_exposed_value()
|
||||||
// exposed: false,
|
|
||||||
// } = &document_node.inputs[mask_fill_index]
|
|
||||||
// {
|
// {
|
||||||
// let mask_fill_content_modes = ImaginateMaskStartingFill::list();
|
// let mask_fill_content_modes = ImaginateMaskStartingFill::list();
|
||||||
// let mut entries = Vec::with_capacity(mask_fill_content_modes.len());
|
// 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 mut widgets_first_row = start_widgets(document_node, node_id, fill_index, "Fill", FrontendGraphDataType::General, true);
|
||||||
|
|
||||||
let (fill, backup_color, backup_gradient) = if let (
|
let (fill, backup_color, backup_gradient) = if let (Some(TaggedValue::Fill(fill)), Some(&TaggedValue::OptionalColor(backup_color)), Some(TaggedValue::Gradient(backup_gradient))) = (
|
||||||
NodeInput::Value {
|
&document_node.inputs[fill_index].as_value(),
|
||||||
tagged_value: TaggedValue::Fill(fill),
|
&document_node.inputs[backup_color_index].as_value(),
|
||||||
..
|
&document_node.inputs[backup_gradient_index].as_value(),
|
||||||
},
|
|
||||||
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],
|
|
||||||
) {
|
) {
|
||||||
(fill, backup_color, backup_gradient)
|
(fill, backup_color, backup_gradient)
|
||||||
} else {
|
} else {
|
||||||
return vec![LayoutGroup::Row { widgets: widgets_first_row }];
|
return vec![LayoutGroup::Row { widgets: widgets_first_row }];
|
||||||
};
|
};
|
||||||
let fill2 = fill.clone();
|
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();
|
let backup_gradient_fill: Fill = backup_gradient.clone().into();
|
||||||
|
|
||||||
widgets_first_row.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
widgets_first_row.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||||
|
|||||||
@@ -129,29 +129,10 @@ pub fn get_text_id(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -
|
|||||||
/// Gets properties from the Text node
|
/// Gets properties from the Text node
|
||||||
pub fn get_text(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> Option<(&String, &Font, f64)> {
|
pub fn get_text(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> Option<(&String, &Font, f64)> {
|
||||||
let inputs = NodeGraphLayer::new(layer, document_network).find_node_inputs("Text")?;
|
let inputs = NodeGraphLayer::new(layer, document_network).find_node_inputs("Text")?;
|
||||||
let NodeInput::Value {
|
|
||||||
tagged_value: TaggedValue::String(text),
|
|
||||||
..
|
|
||||||
} = &inputs[1]
|
|
||||||
else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let NodeInput::Value {
|
let Some(TaggedValue::String(text)) = &inputs[1].as_value() else { return None };
|
||||||
tagged_value: TaggedValue::Font(font),
|
let Some(TaggedValue::Font(font)) = &inputs[2].as_value() else { return None };
|
||||||
..
|
let Some(&TaggedValue::F64(font_size)) = inputs[3].as_value() else { return None };
|
||||||
} = &inputs[2]
|
|
||||||
else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let NodeInput::Value {
|
|
||||||
tagged_value: TaggedValue::F64(font_size),
|
|
||||||
..
|
|
||||||
} = inputs[3]
|
|
||||||
else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
Some((text, font, font_size))
|
Some((text, font, font_size))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
|
|||||||
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
||||||
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNodeMetadata, NodeId, NodeInput};
|
use graph_craft::document::{DocumentNodeMetadata, NodeId};
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
use graphene_core::uuid::generate_uuid;
|
use graphene_core::uuid::generate_uuid;
|
||||||
use graphene_core::vector::brush_stroke::{BrushInputSample, BrushStroke, BrushStyle};
|
use graphene_core::vector::brush_stroke::{BrushInputSample, BrushStroke, BrushStyle};
|
||||||
@@ -268,11 +268,7 @@ impl BrushToolData {
|
|||||||
for (node, node_id) in document.network().upstream_flow_back_from_nodes(vec![layer.to_node()], graph_craft::document::FlowType::HorizontalFlow) {
|
for (node, node_id) in document.network().upstream_flow_back_from_nodes(vec![layer.to_node()], graph_craft::document::FlowType::HorizontalFlow) {
|
||||||
if node.name == "Brush" && node_id != layer.to_node() {
|
if node.name == "Brush" && node_id != layer.to_node() {
|
||||||
let points_input = node.inputs.get(2)?;
|
let points_input = node.inputs.get(2)?;
|
||||||
let NodeInput::Value {
|
let Some(TaggedValue::BrushStrokes(strokes)) = points_input.as_value() else {
|
||||||
tagged_value: TaggedValue::BrushStrokes(strokes),
|
|
||||||
..
|
|
||||||
} = points_input
|
|
||||||
else {
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
self.strokes.clone_from(strokes);
|
self.strokes.clone_from(strokes);
|
||||||
|
|||||||
@@ -751,26 +751,14 @@ impl EditorHandle {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let empty_vec = Vec::new();
|
let path_data = match &inputs[0].as_value() {
|
||||||
let path_data = if let NodeInput::Value {
|
Some(TaggedValue::Subpaths(translation)) => translation,
|
||||||
tagged_value: TaggedValue::Subpaths(translation),
|
_ => &Vec::new(),
|
||||||
..
|
|
||||||
} = &inputs[0]
|
|
||||||
{
|
|
||||||
translation
|
|
||||||
} else {
|
|
||||||
&empty_vec
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let empty_vec = Vec::new();
|
let colinear_manipulators = match &inputs[1].as_value() {
|
||||||
let colinear_manipulators = if let NodeInput::Value {
|
Some(TaggedValue::PointIds(translation)) => translation,
|
||||||
tagged_value: TaggedValue::PointIds(translation),
|
_ => &Vec::new(),
|
||||||
..
|
|
||||||
} = &inputs[1]
|
|
||||||
{
|
|
||||||
translation
|
|
||||||
} else {
|
|
||||||
&empty_vec
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut vector_data = VectorData::from_subpaths(path_data, false);
|
let mut vector_data = VectorData::from_subpaths(path_data, false);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ pub mod application_io;
|
|||||||
pub mod quantization;
|
pub mod quantization;
|
||||||
|
|
||||||
use core::any::TypeId;
|
use core::any::TypeId;
|
||||||
|
pub use memo::MemoHash;
|
||||||
pub use raster::Color;
|
pub use raster::Color;
|
||||||
pub use types::Cow;
|
pub use types::Cow;
|
||||||
|
|
||||||
|
|||||||
@@ -142,3 +142,101 @@ impl<I, T, N> MonitorNode<I, T, N> {
|
|||||||
MonitorNode { io: Arc::new(Mutex::new(None)), node }
|
MonitorNode { io: Arc::new(Mutex::new(None)), node }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use core::hash::{Hash, Hasher};
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
|
pub struct MemoHash<T: Hash> {
|
||||||
|
hash: u64,
|
||||||
|
value: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<'de, T: serde::Deserialize<'de> + Hash> serde::Deserialize<'de> for MemoHash<T> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
T::deserialize(deserializer).map(|value| Self::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<T: Hash + serde::Serialize> serde::Serialize for MemoHash<T> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
self.value.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<T: Hash> MemoHash<T> {
|
||||||
|
pub fn new(value: T) -> Self {
|
||||||
|
let hash = Self::calc_hash(&value);
|
||||||
|
Self { hash, value }
|
||||||
|
}
|
||||||
|
pub fn new_with_hash(value: T, hash: u64) -> Self {
|
||||||
|
Self { hash, value }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_hash(data: &T) -> u64 {
|
||||||
|
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||||
|
data.hash(&mut hasher);
|
||||||
|
hasher.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inner_mut<'a>(&'a mut self) -> MemoHashGuard<'a, T> {
|
||||||
|
MemoHashGuard { inner: self }
|
||||||
|
}
|
||||||
|
pub fn into_inner<'a>(self) -> T {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
pub fn hash_code(&self) -> u64 {
|
||||||
|
self.hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: Hash> From<T> for MemoHash<T> {
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Self::new(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Hash> Hash for MemoHash<T> {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.hash.hash(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Hash> core::ops::Deref for MemoHash<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MemoHashGuard<'a, T: Hash> {
|
||||||
|
inner: &'a mut MemoHash<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Hash> core::ops::Drop for MemoHashGuard<'a, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let hash = MemoHash::<T>::calc_hash(&self.inner.value);
|
||||||
|
self.inner.hash = hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Hash> core::ops::Deref for MemoHashGuard<'a, T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Hash> core::ops::DerefMut for MemoHashGuard<'a, T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -830,9 +830,9 @@ impl Color {
|
|||||||
/// ```
|
/// ```
|
||||||
/// use graphene_core::raster::color::Color;
|
/// use graphene_core::raster::color::Color;
|
||||||
/// let color1 = Color::from_rgba8_srgb(0x52, 0x67, 0xFA, 0x61).to_gamma_srgb();
|
/// let color1 = Color::from_rgba8_srgb(0x52, 0x67, 0xFA, 0x61).to_gamma_srgb();
|
||||||
/// assert_eq!("3240a261", color1.rgb_optional_a_hex())
|
/// assert_eq!("3240a261", color1.rgb_optional_a_hex());
|
||||||
/// let color2 = Color::from_rgba8_srgb(0x52, 0x67, 0xFA, 0x61).to_gamma_srgb();
|
/// let color2 = Color::from_rgba8_srgb(0x52, 0x67, 0xFA, 0xFF).to_gamma_srgb();
|
||||||
/// assert_eq!("3240a2", color2.rgb_optional_a_hex())
|
/// assert_eq!("5267fa", color2.rgb_optional_a_hex());
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn rgb_optional_a_hex(&self) -> String {
|
pub fn rgb_optional_a_hex(&self) -> String {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::uuid::generate_uuid;
|
||||||
use crate::Node;
|
use crate::Node;
|
||||||
|
|
||||||
use bezier_rs::BezierHandles;
|
use bezier_rs::BezierHandles;
|
||||||
@@ -18,15 +19,7 @@ pub struct PointModification {
|
|||||||
|
|
||||||
impl Hash for PointModification {
|
impl Hash for PointModification {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.add.hash(state);
|
generate_uuid().hash(state)
|
||||||
|
|
||||||
let mut remove = self.remove.iter().collect::<Vec<_>>();
|
|
||||||
remove.sort_unstable();
|
|
||||||
remove.hash(state);
|
|
||||||
|
|
||||||
let mut delta = self.delta.iter().map(|(&a, &b)| (a, [b.x.to_bits(), b.y.to_bits()])).collect::<Vec<_>>();
|
|
||||||
delta.sort_unstable();
|
|
||||||
delta.hash(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,36 +97,6 @@ pub struct SegmentModification {
|
|||||||
stroke: HashMap<SegmentId, StrokeId>,
|
stroke: HashMap<SegmentId, StrokeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for SegmentModification {
|
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.add.hash(state);
|
|
||||||
|
|
||||||
let mut remove = self.remove.iter().collect::<Vec<_>>();
|
|
||||||
remove.sort_unstable();
|
|
||||||
remove.hash(state);
|
|
||||||
|
|
||||||
let mut start_point = self.start_point.iter().map(|(&a, &b)| (a, b)).collect::<Vec<_>>();
|
|
||||||
start_point.sort_unstable();
|
|
||||||
start_point.hash(state);
|
|
||||||
|
|
||||||
let mut end_point = self.end_point.iter().map(|(&a, &b)| (a, b)).collect::<Vec<_>>();
|
|
||||||
end_point.sort_unstable();
|
|
||||||
end_point.hash(state);
|
|
||||||
|
|
||||||
let mut handle_primary = self.handle_primary.iter().map(|(&a, &b)| (a, b.map(|b| [b.x.to_bits(), b.y.to_bits()]))).collect::<Vec<_>>();
|
|
||||||
handle_primary.sort_unstable();
|
|
||||||
handle_primary.hash(state);
|
|
||||||
|
|
||||||
let mut handle_end = self.handle_end.iter().map(|(&a, &b)| (a, b.map(|b| [b.x.to_bits(), b.y.to_bits()]))).collect::<Vec<_>>();
|
|
||||||
handle_end.sort_unstable();
|
|
||||||
handle_end.hash(state);
|
|
||||||
|
|
||||||
let mut stroke = self.stroke.iter().map(|(&a, &b)| (a, b)).collect::<Vec<_>>();
|
|
||||||
stroke.sort_unstable();
|
|
||||||
stroke.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SegmentModification {
|
impl SegmentModification {
|
||||||
/// Apply this modification to the specified [`SegmentDomain`].
|
/// Apply this modification to the specified [`SegmentDomain`].
|
||||||
pub fn apply(&self, segment_domain: &mut SegmentDomain, point_domain: &PointDomain) {
|
pub fn apply(&self, segment_domain: &mut SegmentDomain, point_domain: &PointDomain) {
|
||||||
@@ -289,24 +252,6 @@ pub struct RegionModification {
|
|||||||
fill: HashMap<RegionId, FillId>,
|
fill: HashMap<RegionId, FillId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for RegionModification {
|
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.add.hash(state);
|
|
||||||
|
|
||||||
let mut remove = self.remove.iter().collect::<Vec<_>>();
|
|
||||||
remove.sort_unstable();
|
|
||||||
remove.hash(state);
|
|
||||||
|
|
||||||
let mut segment_range = self.segment_range.iter().map(|(&a, b)| (a, (*b.start(), *b.end()))).collect::<Vec<_>>();
|
|
||||||
segment_range.sort_unstable();
|
|
||||||
segment_range.hash(state);
|
|
||||||
|
|
||||||
let mut fill = self.fill.iter().map(|(&a, &b)| (a, b)).collect::<Vec<_>>();
|
|
||||||
fill.sort_unstable();
|
|
||||||
fill.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RegionModification {
|
impl RegionModification {
|
||||||
/// Apply this modification to the specified [`RegionDomain`].
|
/// Apply this modification to the specified [`RegionDomain`].
|
||||||
pub fn apply(&self, region_domain: &mut RegionDomain) {
|
pub fn apply(&self, region_domain: &mut RegionDomain) {
|
||||||
@@ -460,19 +405,7 @@ impl VectorModification {
|
|||||||
|
|
||||||
impl core::hash::Hash for VectorModification {
|
impl core::hash::Hash for VectorModification {
|
||||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.points.hash(state);
|
generate_uuid().hash(state)
|
||||||
|
|
||||||
self.segments.hash(state);
|
|
||||||
|
|
||||||
self.regions.hash(state);
|
|
||||||
|
|
||||||
let mut add_g1_continuous = self.add_g1_continuous.iter().copied().collect::<Vec<_>>();
|
|
||||||
add_g1_continuous.sort_unstable();
|
|
||||||
add_g1_continuous.hash(state);
|
|
||||||
|
|
||||||
let mut remove_g1_continuous = self.remove_g1_continuous.iter().copied().collect::<Vec<_>>();
|
|
||||||
remove_g1_continuous.sort_unstable();
|
|
||||||
remove_g1_continuous.hash(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use crate::proto::{ConstructionArgs, ProtoNetwork, ProtoNode, ProtoNodeInput};
|
|||||||
|
|
||||||
use dyn_any::{DynAny, StaticType};
|
use dyn_any::{DynAny, StaticType};
|
||||||
pub use graphene_core::uuid::generate_uuid;
|
pub use graphene_core::uuid::generate_uuid;
|
||||||
use graphene_core::{Cow, ProtoNodeIdentifier, Type};
|
use graphene_core::{Cow, MemoHash, ProtoNodeIdentifier, Type};
|
||||||
|
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
@@ -442,7 +442,7 @@ pub enum NodeInput {
|
|||||||
Node { node_id: NodeId, output_index: usize, lambda: bool },
|
Node { node_id: NodeId, output_index: usize, lambda: bool },
|
||||||
|
|
||||||
/// A hardcoded value that can't change after the graph is compiled. Gets converted into a value node during graph compilation.
|
/// A hardcoded value that can't change after the graph is compiled. Gets converted into a value node during graph compilation.
|
||||||
Value { tagged_value: TaggedValue, exposed: bool },
|
Value { tagged_value: MemoHash<TaggedValue>, exposed: bool },
|
||||||
|
|
||||||
// TODO: Remove import_type and get type from parent node input
|
// TODO: Remove import_type and get type from parent node input
|
||||||
/// Input that is provided by the parent network to this document node, instead of from a hardcoded value or another node within the same network.
|
/// Input that is provided by the parent network to this document node, instead of from a hardcoded value or another node within the same network.
|
||||||
@@ -478,7 +478,8 @@ impl NodeInput {
|
|||||||
Self::Node { node_id, output_index, lambda: true }
|
Self::Node { node_id, output_index, lambda: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn value(tagged_value: TaggedValue, exposed: bool) -> Self {
|
pub fn value(tagged_value: TaggedValue, exposed: bool) -> Self {
|
||||||
|
let tagged_value = tagged_value.into();
|
||||||
Self::Value { tagged_value, exposed }
|
Self::Value { tagged_value, exposed }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +528,13 @@ impl NodeInput {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn as_non_exposed_value(&self) -> Option<&TaggedValue> {
|
||||||
|
if let NodeInput::Value { tagged_value, exposed: false } = self {
|
||||||
|
Some(tagged_value)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_node(&self) -> Option<NodeId> {
|
pub fn as_node(&self) -> Option<NodeId> {
|
||||||
if let NodeInput::Node { node_id, .. } = self {
|
if let NodeInput::Node { node_id, .. } = self {
|
||||||
@@ -1610,7 +1618,7 @@ mod test {
|
|||||||
assert_eq!(extraction_network.nodes.len(), 1);
|
assert_eq!(extraction_network.nodes.len(), 1);
|
||||||
let inputs = extraction_network.nodes.get(&NodeId(1)).unwrap().inputs.clone();
|
let inputs = extraction_network.nodes.get(&NodeId(1)).unwrap().inputs.clone();
|
||||||
assert_eq!(inputs.len(), 1);
|
assert_eq!(inputs.len(), 1);
|
||||||
assert!(matches!(&inputs[0], &NodeInput::Value{ tagged_value: TaggedValue::DocumentNode(ref network), ..} if network == &id_node));
|
assert!(matches!(&inputs[0].as_value(), &Some(TaggedValue::DocumentNode(ref network), ..) if network == &id_node));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1621,13 +1629,7 @@ mod test {
|
|||||||
NodeId(1),
|
NodeId(1),
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
name: "Inc".into(),
|
name: "Inc".into(),
|
||||||
inputs: vec![
|
inputs: vec![NodeInput::network(concrete!(u32), 0), NodeInput::value(TaggedValue::U32(2), false)],
|
||||||
NodeInput::network(concrete!(u32), 0),
|
|
||||||
NodeInput::Value {
|
|
||||||
tagged_value: TaggedValue::U32(2),
|
|
||||||
exposed: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
implementation: DocumentNodeImplementation::Network(add_network()),
|
implementation: DocumentNodeImplementation::Network(add_network()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -1712,7 +1714,7 @@ mod test {
|
|||||||
ProtoNode {
|
ProtoNode {
|
||||||
identifier: "graphene_core::value::ClonedNode".into(),
|
identifier: "graphene_core::value::ClonedNode".into(),
|
||||||
input: ProtoNodeInput::None,
|
input: ProtoNodeInput::None,
|
||||||
construction_args: ConstructionArgs::Value(TaggedValue::U32(2)),
|
construction_args: ConstructionArgs::Value(TaggedValue::U32(2).into()),
|
||||||
original_location: OriginalLocation {
|
original_location: OriginalLocation {
|
||||||
path: Some(vec![NodeId(1), NodeId(4)]),
|
path: Some(vec![NodeId(1), NodeId(4)]),
|
||||||
inputs_source: HashMap::new(),
|
inputs_source: HashMap::new(),
|
||||||
@@ -1759,10 +1761,7 @@ mod test {
|
|||||||
NodeId(14),
|
NodeId(14),
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
name: "Value".into(),
|
name: "Value".into(),
|
||||||
inputs: vec![NodeInput::Value {
|
inputs: vec![NodeInput::value(TaggedValue::U32(2), false)],
|
||||||
tagged_value: TaggedValue::U32(2),
|
|
||||||
exposed: false,
|
|
||||||
}],
|
|
||||||
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::value::ClonedNode".into()),
|
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::value::ClonedNode".into()),
|
||||||
original_location: OriginalLocation {
|
original_location: OriginalLocation {
|
||||||
path: Some(vec![NodeId(1), NodeId(4)]),
|
path: Some(vec![NodeId(1), NodeId(4)]),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::wasm_application_io::WasmEditorApi;
|
|||||||
|
|
||||||
use graphene_core::raster::brush_cache::BrushCache;
|
use graphene_core::raster::brush_cache::BrushCache;
|
||||||
use graphene_core::raster::{BlendMode, LuminanceCalculation};
|
use graphene_core::raster::{BlendMode, LuminanceCalculation};
|
||||||
use graphene_core::{Color, Node, Type};
|
use graphene_core::{Color, MemoHash, Node, Type};
|
||||||
|
|
||||||
use dyn_any::DynAny;
|
use dyn_any::DynAny;
|
||||||
pub use dyn_any::StaticType;
|
pub use dyn_any::StaticType;
|
||||||
@@ -207,17 +207,17 @@ impl Display for TaggedValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct UpcastNode {
|
pub struct UpcastNode {
|
||||||
value: TaggedValue,
|
value: MemoHash<TaggedValue>,
|
||||||
}
|
}
|
||||||
impl<'input> Node<'input, DAny<'input>> for UpcastNode {
|
impl<'input> Node<'input, DAny<'input>> for UpcastNode {
|
||||||
type Output = FutureAny<'input>;
|
type Output = FutureAny<'input>;
|
||||||
|
|
||||||
fn eval(&'input self, _: DAny<'input>) -> Self::Output {
|
fn eval(&'input self, _: DAny<'input>) -> Self::Output {
|
||||||
Box::pin(async move { self.value.clone().to_any() })
|
Box::pin(async move { self.value.clone().into_inner().to_any() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl UpcastNode {
|
impl UpcastNode {
|
||||||
pub fn new(value: TaggedValue) -> Self {
|
pub fn new(value: MemoHash<TaggedValue>) -> Self {
|
||||||
Self { value }
|
Self { value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ impl core::fmt::Display for ProtoNetwork {
|
|||||||
/// Defines the arguments used to construct the boxed node struct. This is used to call the constructor function in the `node_registry.rs` file - which is hidden behind a wall of macros.
|
/// Defines the arguments used to construct the boxed node struct. This is used to call the constructor function in the `node_registry.rs` file - which is hidden behind a wall of macros.
|
||||||
pub enum ConstructionArgs {
|
pub enum ConstructionArgs {
|
||||||
/// A value of a type that is known, allowing serialization (serde::Deserialize is not object safe)
|
/// A value of a type that is known, allowing serialization (serde::Deserialize is not object safe)
|
||||||
Value(value::TaggedValue),
|
Value(MemoHash<value::TaggedValue>),
|
||||||
// TODO: use a struct for clearer naming.
|
// TODO: use a struct for clearer naming.
|
||||||
/// A list of nodes used as inputs to the constructor function in `node_registry.rs`.
|
/// A list of nodes used as inputs to the constructor function in `node_registry.rs`.
|
||||||
/// The bool indicates whether to treat the node as lambda node.
|
/// The bool indicates whether to treat the node as lambda node.
|
||||||
@@ -230,7 +230,7 @@ impl Default for ProtoNode {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
identifier: ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode"),
|
identifier: ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode"),
|
||||||
construction_args: ConstructionArgs::Value(value::TaggedValue::U32(0)),
|
construction_args: ConstructionArgs::Value(value::TaggedValue::U32(0).into()),
|
||||||
input: ProtoNodeInput::None,
|
input: ProtoNodeInput::None,
|
||||||
original_location: OriginalLocation::default(),
|
original_location: OriginalLocation::default(),
|
||||||
skip_deduplication: false,
|
skip_deduplication: false,
|
||||||
@@ -940,12 +940,12 @@ mod test {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
ids,
|
ids,
|
||||||
vec![
|
vec![
|
||||||
NodeId(5686040524603683634),
|
NodeId(12083027370457564588),
|
||||||
NodeId(13787140740513543798),
|
NodeId(10127202135369428481),
|
||||||
NodeId(1280393769237740322),
|
NodeId(3781642984881236270),
|
||||||
NodeId(3100442468152897091),
|
NodeId(9447822059040146367),
|
||||||
NodeId(14834729712909816752),
|
NodeId(15916837829094140504),
|
||||||
NodeId(8678825113056010444)
|
NodeId(1758919868423328454)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -996,7 +996,7 @@ mod test {
|
|||||||
ProtoNode {
|
ProtoNode {
|
||||||
identifier: "value".into(),
|
identifier: "value".into(),
|
||||||
input: ProtoNodeInput::None,
|
input: ProtoNodeInput::None,
|
||||||
construction_args: ConstructionArgs::Value(value::TaggedValue::U32(2)),
|
construction_args: ConstructionArgs::Value(value::TaggedValue::U32(2).into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use graphene_core::{transform::Footprint, GraphicGroup};
|
|||||||
use graphene_core::{vector::misc::BooleanOperation, GraphicElement};
|
use graphene_core::{vector::misc::BooleanOperation, GraphicElement};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
pub struct BinaryBooleanOperationNode<LowerVectorData, BooleanOp> {
|
pub struct BinaryBooleanOperationNode<LowerVectorData, BooleanOp> {
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ impl BorrowTree {
|
|||||||
|
|
||||||
match &proto_node.construction_args {
|
match &proto_node.construction_args {
|
||||||
ConstructionArgs::Value(value) => {
|
ConstructionArgs::Value(value) => {
|
||||||
let node = if let TaggedValue::EditorApi(api) = value {
|
let node = if let TaggedValue::EditorApi(api) = &**value {
|
||||||
let editor_api = UpcastAsRefNode::new(api.clone());
|
let editor_api = UpcastAsRefNode::new(api.clone());
|
||||||
let node = Box::new(editor_api) as TypeErasedBox<'_>;
|
let node = Box::new(editor_api) as TypeErasedBox<'_>;
|
||||||
NodeContainer::new(node)
|
NodeContainer::new(node)
|
||||||
@@ -263,7 +263,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn push_node_sync() {
|
fn push_node_sync() {
|
||||||
let mut tree = BorrowTree::default();
|
let mut tree = BorrowTree::default();
|
||||||
let val_1_protonode = ProtoNode::value(ConstructionArgs::Value(TaggedValue::U32(2u32)), vec![]);
|
let val_1_protonode = ProtoNode::value(ConstructionArgs::Value(TaggedValue::U32(2u32).into()), vec![]);
|
||||||
let context = TypingContext::default();
|
let context = TypingContext::default();
|
||||||
let future = tree.push_node(NodeId(0), val_1_protonode, &context);
|
let future = tree.push_node(NodeId(0), val_1_protonode, &context);
|
||||||
futures::executor::block_on(future).unwrap();
|
futures::executor::block_on(future).unwrap();
|
||||||
|
|||||||
@@ -48,13 +48,7 @@ mod tests {
|
|||||||
NodeId(0),
|
NodeId(0),
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
name: "Inc".into(),
|
name: "Inc".into(),
|
||||||
inputs: vec![
|
inputs: vec![NodeInput::network(concrete!(u32), 0), NodeInput::value(graph_craft::document::value::TaggedValue::U32(1u32), false)],
|
||||||
NodeInput::network(concrete!(u32), 0),
|
|
||||||
NodeInput::Value {
|
|
||||||
tagged_value: graph_craft::document::value::TaggedValue::U32(1u32),
|
|
||||||
exposed: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
implementation: DocumentNodeImplementation::Network(add_network()),
|
implementation: DocumentNodeImplementation::Network(add_network()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user