Skip to content

Commit

Permalink
Add some additional image effect nodes (#869)
Browse files Browse the repository at this point in the history
* Move the Subpath type to graphene-std

* Add the transform subpath node

* Delete selected nodes

* Inserting node list on right click

* Add several bitmap manipulator nodes

* Convert add node to use f64

* Add posterize node

* Rename names randomly

* Fix naming

* Exposure node

* Fix typo

* Adjust exposure node range

* Comment out vector nodes

* Adjust exposure range again

* Posterise as ints

* Rename input

* Use >= in the to hsl function
  • Loading branch information
0HyperCube committed Dec 3, 2022
1 parent 0fb12bf commit f9d7720
Show file tree
Hide file tree
Showing 50 changed files with 1,310 additions and 481 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions editor/src/messages/input_mapper/default_mapping.rs
Expand Up @@ -27,6 +27,10 @@ pub fn default_mapping() -> Mapping {
),
// NORMAL PRIORITY:
//
// NodeGraphMessage
entry!(KeyDown(Delete); action_dispatch=NodeGraphMessage::DeleteSelectedNodes),
entry!(KeyDown(Backspace); action_dispatch=NodeGraphMessage::DeleteSelectedNodes),
//
// TransformLayerMessage
entry!(KeyDown(Enter); action_dispatch=TransformLayerMessage::ApplyTransformOperation),
entry!(KeyDown(Lmb); action_dispatch=TransformLayerMessage::ApplyTransformOperation),
Expand Down
12 changes: 12 additions & 0 deletions editor/src/messages/layout/utility_types/layout_widget.rs
Expand Up @@ -263,6 +263,18 @@ impl WidgetHolder {
pub fn new(widget: Widget) -> Self {
Self { widget_id: generate_uuid(), widget }
}
pub fn unrelated_seperator() -> Self {
WidgetHolder::new(Widget::Separator(Separator {
separator_type: SeparatorType::Unrelated,
direction: SeparatorDirection::Horizontal,
}))
}
pub fn text_widget(text: impl Into<String>) -> Self {
WidgetHolder::new(Widget::TextLabel(TextLabel {
value: text.into(),
..Default::default()
}))
}
}

#[derive(Clone)]
Expand Down
Expand Up @@ -29,8 +29,8 @@ use graphene::layers::imaginate_layer::{ImaginateBaseImage, ImaginateGenerationP
use graphene::layers::layer_info::{LayerDataType, LayerDataTypeDiscriminant};
use graphene::layers::style::{Fill, RenderData, ViewMode};
use graphene::layers::text_layer::{Font, FontCache};
use graphene::layers::vector::subpath::Subpath;
use graphene::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
use graphene_std::vector::subpath::Subpath;

use glam::{DAffine2, DVec2};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -928,6 +928,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
}
common.extend(self.navigation_handler.actions());
common.extend(self.transform_layer_handler.actions());
common.extend(self.node_graph_handler.actions());
common
}
}
Expand Down
Expand Up @@ -15,12 +15,14 @@ pub enum NodeGraphMessage {
CreateNode {
// Having the caller generate the id means that we don't have to return it. This can be a random u64.
node_id: Option<NodeId>,
// I don't really know what this is for (perhaps a user identifiable name).
node_type: String,
x: i32,
y: i32,
},
DeleteNode {
node_id: NodeId,
},
DeleteSelectedNodes,
ExposeInput {
node_id: NodeId,
input_index: usize,
Expand Down
@@ -1,6 +1,6 @@
use crate::messages::layout::utility_types::layout_widget::LayoutGroup;
use crate::messages::prelude::*;
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, DocumentNodeMetadata, NodeInput, NodeNetwork};
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, DocumentNodeMetadata, NodeId, NodeInput, NodeNetwork};
use graphene::document::Document;
use graphene::layers::layer_info::LayerDataType;
use graphene::layers::nodegraph_layer::NodeGraphFrameLayer;
Expand All @@ -18,9 +18,13 @@ pub enum FrontendGraphDataType {
#[serde(rename = "color")]
Color,
#[serde(rename = "vector")]
Vector,
Subpath,
#[serde(rename = "number")]
Number,
#[serde(rename = "boolean")]
Boolean,
#[serde(rename = "vec2")]
Vector,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
Expand Down Expand Up @@ -57,10 +61,14 @@ pub struct FrontendNodeLink {
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct FrontendNodeType {
pub name: String,
pub category: String,
}
impl FrontendNodeType {
pub fn new(name: &'static str) -> Self {
Self { name: name.to_string() }
pub fn new(name: &'static str, category: &'static str) -> Self {
Self {
name: name.to_string(),
category: category.to_string(),
}
}
}

Expand Down Expand Up @@ -148,6 +156,54 @@ impl NodeGraphMessageHandler {
log::debug!("Nodes:\n{:#?}\n\nFrontend Nodes:\n{:#?}\n\nLinks:\n{:#?}", network.nodes, nodes, links);
responses.push_back(FrontendMessage::UpdateNodeGraph { nodes, links }.into());
}

fn remove_node(&mut self, network: &mut NodeNetwork, node_id: NodeId) -> bool {
fn remove_from_network(network: &mut NodeNetwork, node_id: NodeId) -> bool {
if network.inputs.iter().any(|&id| id == node_id) {
warn!("Deleting input node");
return false;
}
if network.output == node_id {
warn!("Deleting the output node!");
return false;
}
for (id, node) in network.nodes.iter_mut() {
if *id == node_id {
continue;
}
for (input_index, input) in node.inputs.iter_mut().enumerate() {
let NodeInput::Node(id) = input else {
continue;
};
if *id != node_id {
continue;
}

let Some(node_type) = document_node_types::resolve_document_node_type(&node.name) else{
warn!("Removing input of invalid node type '{}'", node.name);
return false;
};
if let NodeInput::Value { tagged_value, .. } = &node_type.inputs[input_index].default {
*input = NodeInput::Value {
tagged_value: tagged_value.clone(),
exposed: true,
};
}
}
if let DocumentNodeImplementation::Network(network) = &mut node.implementation {
remove_from_network(network, node_id);
}
}
true
}
if remove_from_network(network, node_id) {
network.nodes.remove(&node_id);
self.selected_nodes.retain(|&id| id != node_id);
true
} else {
false
}
}
}

impl MessageHandler<NodeGraphMessage, (&mut Document, &InputPreprocessorMessageHandler)> for NodeGraphMessageHandler {
Expand Down Expand Up @@ -188,7 +244,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &InputPreprocessorMessageH
Self::send_graph(network, responses);
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
}
NodeGraphMessage::CreateNode { node_id, node_type } => {
NodeGraphMessage::CreateNode { node_id, node_type, x, y } => {
let node_id = node_id.unwrap_or_else(crate::application::generate_uuid);
let Some(network) = self.get_active_network_mut(document) else{
warn!("No network");
Expand Down Expand Up @@ -218,7 +274,6 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &InputPreprocessorMessageH
.into_iter()
.collect(),
};
let far_right_node = network.nodes.iter().map(|node| node.1.metadata.position).max_by_key(|pos| pos.0).unwrap_or_default();

network.nodes.insert(
node_id,
Expand All @@ -227,19 +282,29 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &InputPreprocessorMessageH
inputs: document_node_type.inputs.iter().map(|input| input.default.clone()).collect(),
// TODO: Allow inserting nodes that contain other nodes.
implementation: DocumentNodeImplementation::Network(inner_network),
metadata: graph_craft::document::DocumentNodeMetadata {
// TODO: Better position default
position: (far_right_node.0 + 7, far_right_node.1 + 2),
},
metadata: graph_craft::document::DocumentNodeMetadata { position: (x, y) },
},
);
Self::send_graph(network, responses);
}
NodeGraphMessage::DeleteNode { node_id } => {
if let Some(network) = self.get_active_network_mut(document) {
network.nodes.remove(&node_id);
Self::send_graph(network, responses);
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
if self.remove_node(network, node_id) {
Self::send_graph(network, responses);
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
}
}
}
NodeGraphMessage::DeleteSelectedNodes => {
if let Some(network) = self.get_active_network_mut(document) {
let mut modified = false;
for node_id in self.selected_nodes.clone() {
modified = modified || self.remove_node(network, node_id);
}
if modified {
Self::send_graph(network, responses);
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
}
}
}
NodeGraphMessage::ExposeInput { node_id, input_index, new_exposed } => {
Expand Down Expand Up @@ -314,5 +379,11 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &InputPreprocessorMessageH
}
}

advertise_actions!(NodeGraphMessageDiscriminant; DeleteNode,);
fn actions(&self) -> ActionList {
if self.layer_path.is_some() && !self.selected_nodes.is_empty() {
actions!(NodeGraphMessageDiscriminant; DeleteSelectedNodes,)
} else {
actions!(NodeGraphMessageDiscriminant;)
}
}
}

0 comments on commit f9d7720

Please sign in to comment.