/* SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include #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 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 &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 &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; 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 &items_; public: GatherLinkSearchOpParams(const bNodeType &node_type, const bNodeTree &node_tree, const bNodeSocket &other_socket, Vector &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 declarations); } // namespace blender::nodes