diff options
Diffstat (limited to 'source/blender/nodes/NOD_socket_search_link.hh')
-rw-r--r-- | source/blender/nodes/NOD_socket_search_link.hh | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/source/blender/nodes/NOD_socket_search_link.hh b/source/blender/nodes/NOD_socket_search_link.hh new file mode 100644 index 00000000000..b7594561dc4 --- /dev/null +++ b/source/blender/nodes/NOD_socket_search_link.hh @@ -0,0 +1,151 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include <functional> + +#include "BLI_string_ref.hh" +#include "BLI_vector.hh" + +#include "DNA_node_types.h" /* Necessary for eNodeSocketInOut. */ + +#include "NOD_node_declaration.hh" + +struct bContext; + +namespace blender::nodes { + +/** + * Parameters for the operation operation of adding a node after the link drag search menu closes. + */ +class LinkSearchOpParams { + private: + /** + * Keep track of the nodes added by the callback, so they can be selected or moved afterwards. + */ + Vector<bNode *> &added_nodes_; + + public: + const bContext &C; + bNodeTree &node_tree; + /** + * The node that contains the #socket. + */ + bNode &node; + /** + * The existing socket to connect any added nodes to. Might be an input or output socket. + */ + bNodeSocket &socket; + + LinkSearchOpParams(const bContext &C, + bNodeTree &node_tree, + bNode &node, + bNodeSocket &socket, + Vector<bNode *> &added_nodes) + : added_nodes_(added_nodes), C(C), node_tree(node_tree), node(node), socket(socket) + { + } + + bNode &add_node(StringRef idname); + bNode &add_node(const bNodeType &type); + /** + * Find a socket with the given name (correctly checks for inputs and outputs) + * and connect it to the socket the link drag started from (#socket). + */ + void connect_available_socket(bNode &new_node, StringRef socket_name); + /** + * Like #connect_available_socket, but also calls the node's update function. + */ + void update_and_connect_available_socket(bNode &new_node, StringRef socket_name); +}; + +struct SocketLinkOperation { + using LinkSocketFn = std::function<void(LinkSearchOpParams &link_params)>; + + std::string name; + LinkSocketFn fn; + int weight = 0; +}; + +class GatherLinkSearchOpParams { + /** The current node type. */ + const bNodeType &node_type_; + + const bNodeTree &node_tree_; + + const bNodeSocket &other_socket_; + + /* The operations currently being built. Owned by the caller. */ + Vector<SocketLinkOperation> &items_; + + public: + GatherLinkSearchOpParams(const bNodeType &node_type, + const bNodeTree &node_tree, + const bNodeSocket &other_socket, + Vector<SocketLinkOperation> &items) + : node_type_(node_type), node_tree_(node_tree), other_socket_(other_socket), items_(items) + { + } + + /** + * The node on the other side of the dragged link. + */ + const bNodeSocket &other_socket() const; + + /** + * The node tree the user is editing when the search menu is created. + */ + const bNodeTree &node_tree() const; + + /** + * The type of the node in the current callback. + */ + const bNodeType &node_type() const; + + /** + * Whether to list the input or output sockets of the node. + */ + eNodeSocketInOut in_out() const; + + /** + * \param weight: Used to customize the order when multiple search items match. + * + * \warning When creating lambdas for the #fn argument, be careful not to capture this class + * itself, since it is temporary. That is why we tend to use the same variable name for this + * class (`params`) that we do for the argument to `LinkSocketFn`. + */ + void add_item(std::string socket_name, SocketLinkOperation::LinkSocketFn fn, int weight = 0); +}; + +/** + * This callback can be used for a node type when a few things are true about its inputs. + * To avoid creating more boilerplate, it is the default callback for node types. + * - Either all declared sockets are visible in the default state of the node, *OR* the node's + * type's declaration has been extended with #make_available functions for those sockets. + * + * If a node type does not meet these criteria, the function will do nothing in a release build. + * In a debug build, an assert will most likely be hit. + * + * \note For nodes with the deprecated #bNodeSocketTemplate instead of a declaration, + * these criteria do not apply and the function just tries its best without asserting. + */ +void search_link_ops_for_basic_node(GatherLinkSearchOpParams ¶ms); + +void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms, + Span<SocketDeclarationPtr> declarations); + +} // namespace blender::nodes |