Files
test/source/blender/editors/space_node/node_intern.hh

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

388 lines
13 KiB
C++
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2008 Blender Foundation. All rights reserved. */
2011-02-27 20:29:51 +00:00
/** \file
* \ingroup spnode
2011-02-27 20:29:51 +00:00
*/
#pragma once
#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "BLI_vector.hh"
#include "BKE_node.h"
#include "UI_interface.h"
#include "UI_interface.hh"
#include "UI_view2d.h"
struct ARegion;
struct ARegionType;
struct Main;
2021-02-18 14:14:17 +11:00
struct NodeInsertOfsData;
struct View2D;
struct bContext;
struct bNode;
struct bNodeLink;
struct bNodeSocket;
struct wmGizmoGroupType;
Holiday coding log :) Nice formatted version (pictures soon): http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability Short list of main changes: - Transparent region option (over main region), added code to blend in/out such panels. - Min size window now 640 x 480 - Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake. - Macbook retina support, use command line --no-native-pixels to disable it - Timeline Marker label was drawing wrong - Trackpad and magic mouse: supports zoom (hold ctrl) - Fix for splash position: removed ghost function and made window size update after creation immediate - Fast undo buffer save now adds UI as well. Could be checked for regular file save even... Quit.blend and temp file saving use this now. - Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)" - New Userpref option "Keep Session" - this always saves quit.blend, and loads on start. This allows keeping UI and data without actual saves, until you actually save. When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header) - Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v). Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards. - User preferences (themes, keymaps, user settings) now can be saved as a separate file. Old option is called "Save Startup File" the new one "Save User Settings". To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still. - OSX: fixed bug that stopped giving mouse events outside window. This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
struct wmKeyConfig;
struct wmWindow;
/* Outside of blender namespace to avoid Python documentation build error with `ctypes`. */
extern "C" {
extern const char *node_context_dir[];
};
namespace blender::ed::space_node {
/** Temporary data used in node link drag modal operator. */
struct bNodeLinkDrag {
/** Links dragged by the operator. */
Vector<bNodeLink *> links;
bool from_multi_input_socket;
eNodeSocketInOut in_out;
/** Draw handler for the "+" icon when dragging a link in empty space. */
void *draw_handle;
/** Temporarily stores the last picked link from multi-input socket operator. */
bNodeLink *last_picked_multi_input_socket_link;
/**
* Temporarily stores the last hovered socket for multi-input socket operator.
* Store it to recalculate sorting after it is no longer hovered.
*/
bNode *last_node_hovered_while_dragging_a_link;
/* The cursor position, used for drawing a + icon when dragging a node link. */
std::array<int, 2> cursor;
/** The node the drag started at. */
bNode *start_node;
/** The socket the drag started at. */
bNodeSocket *start_socket;
/** The number of links connected to the #start_socket when the drag started. */
int start_link_count;
Edge-scrolling for node editor Starts scrolling when dragging a node or node link and going outside the current window. Largely copied from the VIEW2D_OT_edge_pan operator. Edge panning operator customdata and supporting functions now in UI_view2d.h, so they could be used by operators in other editor libraries. The VIEW2D_OT_edge_pan operator also uses this customdata and shared functions now. Operators properties can be used to configure edge panning margins and speed for each use case, rather than using hardcoded values. The speed function for edge panning has been tweaked somewhat: * "Speed per pixel" has been replaced with a "speed ramp" distance. This is more intuitive and also creates an upper bound for the speed, which can otherwise become extreme with large cursor distance. * "Max speed" is reached at the end of the speed ramp. * Padding the region inside and outside is applied as before, but both values are operator properties now. Node transform operator also supports edge panning. This requires an offset for changes in the view2d rect, otherwise nodes are "stuck" to the original view. Transform operator had cursor wrapping categorically enabled, but this gets quite confusing with the edge scrolling mechanism. A new TransInfo option T_NO_CURSOR_WRAP has been introduced to disable this behavior. The double negative is a bit annoying, but want to avoid affecting the existing transform modes, so by default it should still set the OP_IS_MODAL_GRAB_CURSOR flag (which then sets the WM_CURSOR_WRAP_XY flag during modal execution). Reviewed By: HooglyBoogly, JacquesLucke Differential Revision: https://developer.blender.org/D11073
2021-06-16 18:17:07 +01:00
/* Data for edge panning */
View2DEdgePanData pan_data;
};
struct SpaceNode_Runtime {
float aspect;
/** Mouse position for drawing socket-less links and adding nodes. */
float2 cursor;
/**
* Indicates that the compositing tree in the space needs to be re-evaluated using the
* auto-compositing pipeline.
* Takes priority over the regular compositing.
*/
bool recalc_auto_compositing;
/**
* Indicates that the compositing int the space tree needs to be re-evaluated using
* regular compositing pipeline.
*/
bool recalc_regular_compositing;
/** Temporary data for modal linking operator. */
std::unique_ptr<bNodeLinkDrag> linkdrag;
/* XXX hack for translate_attach op-macros to pass data from transform op to insert_offset op */
/** Temporary data for node insert offset (in UI called Auto-offset). */
struct NodeInsertOfsData *iofsd;
};
enum NodeResizeDirection {
NODE_RESIZE_NONE = 0,
NODE_RESIZE_TOP = (1 << 0),
NODE_RESIZE_BOTTOM = (1 << 1),
NODE_RESIZE_RIGHT = (1 << 2),
NODE_RESIZE_LEFT = (1 << 3),
};
ENUM_OPERATORS(NodeResizeDirection, NODE_RESIZE_LEFT);
/* Nodes draw without DPI - the view zoom is flexible. */
#define HIDDEN_RAD (0.75f * U.widget_unit)
#define BASIS_RAD (0.2f * U.widget_unit)
#define NODE_DYS (U.widget_unit / 2)
#define NODE_DY U.widget_unit
#define NODE_SOCKDY (0.1f * U.widget_unit)
#define NODE_WIDTH(node) (node.width * UI_DPI_FAC)
#define NODE_HEIGHT(node) (node.height * UI_DPI_FAC)
#define NODE_MARGIN_X (1.2f * U.widget_unit)
#define NODE_SOCKSIZE (0.25f * U.widget_unit)
#define NODE_SOCKSIZE_DRAW_MULIPLIER 2.25f
#define NODE_SOCK_OUTLINE_SCALE 1.0f
#define NODE_MULTI_INPUT_LINK_GAP (0.25f * U.widget_unit)
#define NODE_RESIZE_MARGIN (0.20f * U.widget_unit)
#define NODE_LINK_RESOL 12
/* space_node.cc */
/**
* Transform between View2Ds in the tree path.
*/
float2 space_node_group_offset(const SpaceNode &snode);
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
int node_get_resize_cursor(NodeResizeDirection directions);
/**
* Usual convention here would be #node_socket_get_color(),
* but that's already used (for setting a color property socket).
*/
void node_socket_color_get(const bContext &C,
const bNodeTree &ntree,
PointerRNA &node_ptr,
const bNodeSocket &sock,
float r_color[4]);
/* node_draw.cc */
void node_draw_space(const bContext &C, ARegion &region);
UI: Add support for showing socket descriptions in tooltips Currently, hovering over a socket itself shows no tooltip at all, while hovering over its value field shows "Default value", which is not helpful. This patch therefore implements socket tooltips following the proposal at https://blender.community/c/rightclickselect/2Qgbbc/. A lot of the basic functionality was already implemented for Geometry Nodes, where hovering over the socket itself shows introspection info. This patch extends this by: - Supporting dynamic tooltips on labels, which is important for good tooltip coverage in a socket's region of the node. - Adding a function to setting a dynamic tooltip for an entire uiLayout, which avoids needing to set it manually for a wide variety of socket types. - Hiding the property label field in a tooltip when dynamic tooltip is also provided. If really needed, this label can be restored through the dynamic tooltip, but in all current cases the label is actually pointless anyways since the dynamic tooltip gives more accurate and specific information. - Adding dynamic tooltips to a socket's UI layout row if it has a description configured, both in the Node Editor as well as in the Material Properties. Note that the patch does not add any actual tooltip content yet, just the infrastructure to show them. By default, sockets without a description still show the old "Default value" tooltip. For an example of how to add socket descriptions, check the Cylinder node in the Geometry Nodes. Differential Revision: https://developer.blender.org/D9967
2022-04-11 02:02:12 +02:00
void node_socket_add_tooltip(bNodeTree *ntree, bNode *node, bNodeSocket *sock, uiLayout *layout);
/**
* Sort nodes by selection: unselected nodes first, then selected,
* then the active node at the very end. Relative order is kept intact.
*/
void node_sort(bNodeTree &ntree);
void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor);
Holiday coding log :) Nice formatted version (pictures soon): http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability Short list of main changes: - Transparent region option (over main region), added code to blend in/out such panels. - Min size window now 640 x 480 - Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake. - Macbook retina support, use command line --no-native-pixels to disable it - Timeline Marker label was drawing wrong - Trackpad and magic mouse: supports zoom (hold ctrl) - Fix for splash position: removed ghost function and made window size update after creation immediate - Fast undo buffer save now adds UI as well. Could be checked for regular file save even... Quit.blend and temp file saving use this now. - Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)" - New Userpref option "Keep Session" - this always saves quit.blend, and loads on start. This allows keeping UI and data without actual saves, until you actually save. When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header) - Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v). Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards. - User preferences (themes, keymaps, user settings) now can be saved as a separate file. Old option is called "Save Startup File" the new one "Save User Settings". To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still. - OSX: fixed bug that stopped giving mouse events outside window. This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
/* DPI scaled coords */
float2 node_to_view(const bNode &node, const float2 &co);
void node_to_updated_rect(const bNode &node, rctf &r_rect);
float2 node_from_view(const bNode &node, const float2 &co);
/* node_ops.cc */
void node_operatortypes();
void node_keymap(wmKeyConfig *keyconf);
/* node_select.cc */
rctf node_frame_rect_inside(const bNode &node);
bool node_or_socket_isect_event(bContext *C, const wmEvent *event);
void node_deselect_all(SpaceNode &snode);
void node_socket_select(bNode *node, bNodeSocket &sock);
void node_socket_deselect(bNode *node, bNodeSocket &sock, bool deselect_node);
void node_deselect_all_input_sockets(SpaceNode &snode, bool deselect_nodes);
void node_deselect_all_output_sockets(SpaceNode &snode, bool deselect_nodes);
void node_select_single(bContext &C, bNode &node);
void NODE_OT_select(wmOperatorType *ot);
void NODE_OT_select_all(wmOperatorType *ot);
void NODE_OT_select_linked_to(wmOperatorType *ot);
void NODE_OT_select_linked_from(wmOperatorType *ot);
void NODE_OT_select_box(wmOperatorType *ot);
void NODE_OT_select_circle(wmOperatorType *ot);
void NODE_OT_select_lasso(wmOperatorType *ot);
void NODE_OT_select_grouped(wmOperatorType *ot);
void NODE_OT_select_same_type_step(wmOperatorType *ot);
void NODE_OT_find_node(wmOperatorType *ot);
/* node_view.cc */
bool space_node_view_flag(
bContext &C, SpaceNode &snode, ARegion &region, int node_flag, int smooth_viewtx);
void NODE_OT_view_all(wmOperatorType *ot);
void NODE_OT_view_selected(wmOperatorType *ot);
void NODE_OT_backimage_move(wmOperatorType *ot);
void NODE_OT_backimage_zoom(wmOperatorType *ot);
void NODE_OT_backimage_fit(wmOperatorType *ot);
void NODE_OT_backimage_sample(wmOperatorType *ot);
/* drawnode.cc */
NodeResizeDirection node_get_resize_direction(const bNode *node, int x, int y);
void nodelink_batch_start(SpaceNode &snode);
void nodelink_batch_end(SpaceNode &snode);
/**
* \note this is used for fake links in groups too.
*/
void node_draw_link(const bContext &C,
const View2D &v2d,
const SpaceNode &snode,
const bNodeLink &link,
bool selected);
void node_draw_link_dragged(const bContext &C,
const View2D &v2d,
const SpaceNode &snode,
const bNodeLink &link);
/**
* Don't do shadows if th_col3 is -1.
*/
void node_draw_link_bezier(const bContext &C,
const View2D &v2d,
const SpaceNode &snode,
const bNodeLink &link,
int th_col1,
int th_col2,
int th_col3,
bool selected);
/** If v2d not nullptr, it clips and returns 0 if not visible. */
bool node_link_bezier_points(const View2D *v2d,
const SpaceNode *snode,
const bNodeLink &link,
float coord_array[][2],
int resol);
/**
* Return quadratic beziers points for a given nodelink and clip if v2d is not nullptr.
*/
bool node_link_bezier_handles(const View2D *v2d,
const SpaceNode *snode,
const bNodeLink &ink,
float vec[4][2]);
void draw_nodespace_back_pix(const bContext &C,
ARegion &region,
SpaceNode &snode,
bNodeInstanceKey parent_key);
/* node_add.cc */
bNode *add_node(const bContext &C, StringRef idname, const float2 &location);
bNode *add_static_node(const bContext &C, int type, const float2 &location);
void NODE_OT_add_reroute(wmOperatorType *ot);
void NODE_OT_add_group(wmOperatorType *ot);
void NODE_OT_add_object(wmOperatorType *ot);
void NODE_OT_add_collection(wmOperatorType *ot);
void NODE_OT_add_file(wmOperatorType *ot);
void NODE_OT_add_mask(wmOperatorType *ot);
void NODE_OT_new_node_tree(wmOperatorType *ot);
/* node_group.cc */
const char *node_group_idname(bContext *C);
void NODE_OT_group_make(wmOperatorType *ot);
void NODE_OT_group_insert(wmOperatorType *ot);
void NODE_OT_group_ungroup(wmOperatorType *ot);
void NODE_OT_group_separate(wmOperatorType *ot);
void NODE_OT_group_edit(wmOperatorType *ot);
/* node_relationships.cc */
void sort_multi_input_socket_links(SpaceNode &snode,
bNode &node,
bNodeLink *drag_link,
const float2 *cursor);
void NODE_OT_link(wmOperatorType *ot);
void NODE_OT_link_make(wmOperatorType *ot);
void NODE_OT_links_cut(wmOperatorType *ot);
void NODE_OT_links_detach(wmOperatorType *ot);
void NODE_OT_links_mute(wmOperatorType *ot);
void NODE_OT_parent_set(wmOperatorType *ot);
void NODE_OT_join(wmOperatorType *ot);
void NODE_OT_attach(wmOperatorType *ot);
void NODE_OT_detach(wmOperatorType *ot);
void NODE_OT_link_viewer(wmOperatorType *ot);
void NODE_OT_insert_offset(wmOperatorType *ot);
/* node_edit.cc */
float2 node_link_calculate_multi_input_position(const float2 &socket_position,
int index,
int total_inputs);
void node_select_all(ListBase *lb, int action);
float node_socket_calculate_height(const bNodeSocket &socket);
void snode_set_context(const bContext &C);
bool composite_node_active(bContext *C);
/** Operator poll callback. */
bool composite_node_editable(bContext *C);
bool node_has_hidden_sockets(bNode *node);
void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set);
int node_render_changed_exec(bContext *, wmOperator *);
/** Type is #SOCK_IN and/or #SOCK_OUT. */
bool node_find_indicated_socket(SpaceNode &snode,
bNode **nodep,
bNodeSocket **sockp,
const float2 &cursor,
eNodeSocketInOut in_out);
float node_link_dim_factor(const View2D &v2d, const bNodeLink &link);
bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link);
void NODE_OT_duplicate(wmOperatorType *ot);
void NODE_OT_delete(wmOperatorType *ot);
void NODE_OT_delete_reconnect(wmOperatorType *ot);
void NODE_OT_resize(wmOperatorType *ot);
void NODE_OT_mute_toggle(wmOperatorType *ot);
void NODE_OT_hide_toggle(wmOperatorType *ot);
void NODE_OT_hide_socket_toggle(wmOperatorType *ot);
void NODE_OT_preview_toggle(wmOperatorType *ot);
void NODE_OT_options_toggle(wmOperatorType *ot);
void NODE_OT_node_copy_color(wmOperatorType *ot);
void NODE_OT_read_viewlayers(wmOperatorType *ot);
void NODE_OT_render_changed(wmOperatorType *ot);
void NODE_OT_output_file_add_socket(wmOperatorType *ot);
void NODE_OT_output_file_remove_active_socket(wmOperatorType *ot);
void NODE_OT_output_file_move_active_socket(wmOperatorType *ot);
void NODE_OT_switch_view_update(wmOperatorType *ot);
Multi-View and Stereo 3D Official Documentation: http://www.blender.org/manual/render/workflows/multiview.html Implemented Features ==================== Builtin Stereo Camera * Convergence Mode * Interocular Distance * Convergence Distance * Pivot Mode Viewport * Cameras * Plane * Volume Compositor * View Switch Node * Image Node Multi-View OpenEXR support Sequencer * Image/Movie Strips 'Use Multiview' UV/Image Editor * Option to see Multi-View images in Stereo-3D or its individual images * Save/Open Multi-View (OpenEXR, Stereo3D, individual views) images I/O * Save/Open Multi-View (OpenEXR, Stereo3D, individual views) images Scene Render Views * Ability to have an arbitrary number of views in the scene Missing Bits ============ First rule of Multi-View bug report: If something is not working as it should *when Views is off* this is a severe bug, do mention this in the report. Second rule is, if something works *when Views is off* but doesn't (or crashes) when *Views is on*, this is a important bug. Do mention this in the report. Everything else is likely small todos, and may wait until we are sure none of the above is happening. Apart from that there are those known issues: * Compositor Image Node poorly working for Multi-View OpenEXR (this was working prefectly before the 'Use Multi-View' functionality) * Selecting camera from Multi-View when looking from camera is problematic * Animation Playback (ctrl+F11) doesn't support stereo formats * Wrong filepath when trying to play back animated scene * Viewport Rendering doesn't support Multi-View * Overscan Rendering * Fullscreen display modes need to warn the user * Object copy should be aware of views suffix Acknowledgments =============== * Francesco Siddi for the help with the original feature specs and design * Brecht Van Lommel for the original review of the code and design early on * Blender Foundation for the Development Fund to support the project wrap up Final patch reviewers: * Antony Riakiotakis (psy-fi) * Campbell Barton (ideasman42) * Julian Eisel (Severin) * Sergey Sharybin (nazgul) * Thomas Dinged (dingto) Code contributors of the original branch in github: * Alexey Akishin * Gabriel Caraballo
2015-04-06 10:40:12 -03:00
/**
* \note clipboard_cut is a simple macro of copy + delete.
*/
void NODE_OT_clipboard_copy(wmOperatorType *ot);
void NODE_OT_clipboard_paste(wmOperatorType *ot);
void NODE_OT_tree_socket_add(wmOperatorType *ot);
void NODE_OT_tree_socket_remove(wmOperatorType *ot);
void NODE_OT_tree_socket_change_type(wmOperatorType *ot);
void NODE_OT_tree_socket_move(wmOperatorType *ot);
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
void NODE_OT_shader_script_update(wmOperatorType *ot);
void NODE_OT_viewer_border(wmOperatorType *ot);
void NODE_OT_clear_viewer_border(wmOperatorType *ot);
void NODE_OT_cryptomatte_layer_add(wmOperatorType *ot);
void NODE_OT_cryptomatte_layer_remove(wmOperatorType *ot);
/* node_gizmo.cc */
void NODE_GGT_backdrop_transform(wmGizmoGroupType *gzgt);
void NODE_GGT_backdrop_crop(wmGizmoGroupType *gzgt);
void NODE_GGT_backdrop_sun_beams(wmGizmoGroupType *gzgt);
void NODE_GGT_backdrop_corner_pin(wmGizmoGroupType *gzgt);
/* node_geometry_attribute_search.cc */
void node_geometry_add_attribute_search_button(const bContext &C,
const bNode &node,
PointerRNA &socket_ptr,
uiLayout &layout);
/* node_context_path.c */
Vector<ui::ContextPathItem> context_path_for_space_node(const bContext &C);
/* link_drag_search.cc */
void invoke_node_link_drag_add_menu(bContext &C,
bNode &node,
bNodeSocket &socket,
const float2 &cursor);
} // namespace blender::ed::space_node