11#include <fmt/format.h>
73 if (win->scene != scene) {
79 const View3D *v3d = (
const View3D *)area->spacedata.first;
100 node.
runtime->draw_bounds.ymin,
101 node.
runtime->draw_bounds.ymax,
133 switch (node->type_legacy) {
141 if (
BLI_rctf_isect_pt(&node->runtime->draw_bounds,
int(mouse.x),
int(mouse.y))) {
189 if (node && deselect_node) {
224 bool changed =
false;
225 for (
bNode *node : node_tree.all_nodes()) {
238 for (
bNode *node : node_tree.all_nodes()) {
246 if (deselect_nodes) {
248 if (socket->flag &
SELECT) {
268 for (
bNode *node : node_tree.all_nodes()) {
276 if (deselect_nodes) {
278 if (socket->flag &
SELECT) {
293 node_tree.ensure_topology_cache();
295 for (
bNode *input_node : node_tree.nodes_by_type(zone_type->input_idname)) {
296 if (
bNode *output_node = zone_type->get_corresponding_output(node_tree, *input_node)) {
311 for (
bNode *node : node_tree.all_nodes()) {
313 selected_nodes.
add(node);
316 return selected_nodes;
329 bool changed =
false;
330 for (
bNode *node : node_tree.all_nodes()) {
331 if ((node->flag &
SELECT) == 0) {
343 bool changed =
false;
344 for (
bNode *node : node_tree.all_nodes()) {
345 if ((node->flag &
SELECT) == 0) {
357 bool changed =
false;
358 const uint delims[] = {
'.',
'-',
'_',
'\0'};
359 size_t pref_len_act, pref_len_curr;
360 const char *sep, *suf_act, *suf_curr;
363 node_act.
name,
nullptr, delims, &sep, &suf_act, from_right);
366 if (from_right && !(sep && suf_act)) {
368 suf_act = node_act.
name;
371 for (
bNode *node : node_tree.all_nodes()) {
372 if (node->flag &
SELECT) {
376 node->name,
nullptr, delims, &sep, &suf_curr, from_right);
379 if (from_right && !(sep && suf_curr)) {
381 suf_curr = node->name;
384 if ((from_right &&
STREQ(suf_act, suf_curr)) ||
385 (!from_right && (pref_len_act == pref_len_curr) &&
409 if (node_act ==
nullptr) {
413 bool changed =
false;
456 {0,
nullptr, 0,
nullptr,
nullptr},
460 ot->name =
"Select Grouped";
461 ot->description =
"Select nodes with similar properties";
462 ot->idname =
"NODE_OT_select_grouped";
477 "Extend selection instead of deselecting everything first");
479 ot->prop =
RNA_def_enum(
ot->srna,
"type", prop_select_grouped_types, 0,
"Type",
"");
496 bool active_texture_changed =
false;
498 for (
bNode *node_iter : node_tree.all_nodes()) {
499 if (node_iter != &node) {
528 bNode *node =
nullptr;
534 bool changed =
false;
536 bool node_was_selected =
false;
548 node = &sock->owner_node();
560 node = &sock->owner_node();
573 for (
bNodeSocket *tsock : node->output_sockets()) {
581 for (
bNode *tnode : node_tree.all_nodes()) {
585 for (
bNodeSocket *tsock : tnode->output_sockets()) {
602 found = (node !=
nullptr);
603 node_was_selected = node && (node->
flag &
SELECT);
609 else if (found ||
params.deselect_all) {
643 if (node ==
nullptr) {
646 if (
const std::optional<viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
660 if (!(changed || found)) {
664 bool active_texture_changed =
false;
665 bool viewer_node_changed =
false;
666 if ((node !=
nullptr) && (node_was_selected ==
false ||
params.select_passthrough ==
false)) {
723 ot->idname =
"NODE_OT_select";
724 ot->description =
"Select the node under the cursor";
756 "Deactivate geometry nodes viewer when clicking in empty space");
781 for (
bNode *node : node_tree.all_nodes()) {
784 switch (node->type_legacy) {
789 if (
BLI_rctf_isect(&rectf, &node->runtime->draw_bounds,
nullptr) &&
830 ot->name =
"Box Select";
831 ot->idname =
"NODE_OT_select_box";
832 ot->description =
"Use box selection to select nodes";
850 "Only activate when mouse is not over a node (useful for tweak gesture)");
888 for (
bNode *node : node_tree.all_nodes()) {
889 switch (node->type_legacy) {
894 const float radius_adjusted = float(radius) / zoom;
895 BLI_rctf_pad(&frame_inside, -2.0f * radius_adjusted, -2.0f * radius_adjusted);
921 ot->name =
"Circle Select";
922 ot->idname =
"NODE_OT_select_circle";
923 ot->description =
"Use circle selection to select nodes";
965 bool changed =
false;
976 for (
bNode *node : node_tree.all_nodes()) {
981 switch (node->type_legacy) {
989 if (
BLI_rctf_isect(&rectf, &node->runtime->draw_bounds,
nullptr) &&
1004 ®ion->
v2d, center.x, center.y, &screen_co.x, &screen_co.y) &&
1042 ot->name =
"Lasso Select";
1043 ot->description =
"Select nodes using lasso selection";
1044 ot->idname =
"NODE_OT_select_lasso";
1061 "Only activate when mouse is not over a node (useful for tweak gesture)");
1075 for (
const bNode *node : node_tree.all_nodes()) {
1088 node_tree.ensure_topology_cache();
1102 for (
bNode *node : node_tree.all_nodes()) {
1110 for (
bNode *node : node_tree.all_nodes()) {
1126 ot->name =
"(De)select All";
1127 ot->description =
"(De)select all nodes";
1128 ot->idname =
"NODE_OT_select_all";
1151 node_tree.ensure_topology_cache();
1155 for (
bNode *node : initial_selection) {
1156 for (
bNodeSocket *output_socket : node->output_sockets()) {
1157 if (!output_socket->is_available()) {
1160 for (
bNodeSocket *input_socket : output_socket->directly_linked_sockets()) {
1161 if (!input_socket->is_available()) {
1178 ot->name =
"Select Linked To";
1179 ot->description =
"Select nodes linked to the selected ones";
1180 ot->idname =
"NODE_OT_select_linked_to";
1201 node_tree.ensure_topology_cache();
1205 for (
bNode *node : initial_selection) {
1206 for (
bNodeSocket *input_socket : node->input_sockets()) {
1207 if (!input_socket->is_available()) {
1210 for (
bNodeSocket *output_socket : input_socket->directly_linked_sockets()) {
1211 if (!output_socket->is_available()) {
1228 ot->name =
"Select Linked From";
1229 ot->description =
"Select nodes linked from the selected ones";
1230 ot->idname =
"NODE_OT_select_linked_from";
1258 if (active_node ==
nullptr) {
1263 node_tree.ensure_topology_cache();
1264 if (node_tree.all_nodes().size() == 1) {
1269 const int index = toposort.
first_index(active_node);
1271 int new_index = index;
1273 new_index += (prev ? -1 : 1);
1282 bNode *new_active_node = node_tree.all_nodes()[toposort[new_index]->index()];
1283 if (new_active_node == active_node) {
1300 ot->name =
"Activate Same Type Next/Prev";
1301 ot->description =
"Activate and view same node type, step by step";
1302 ot->idname =
"NODE_OT_select_same_type_step";
1323 if (label == node.
name) {
1326 return fmt::format(
"{} ({})", label, node.
name);
1343 search.
add(name, node);
1348 for (
bNode *node : filtered_nodes) {
1373 static char search[256] =
"";
1385 block, search, 0, ICON_VIEWZOOM,
sizeof(search), 0, 0, box_width,
UI_UNIT_Y,
"");
1393 block,
UI_BTYPE_LABEL, 0,
"", 0, -height, box_width, height,
nullptr, 0, 0, std::nullopt);
1396 std::array<int, 2> bounds_offset = {0, -
UI_UNIT_Y};
1413 ot->name =
"Find Node";
1414 ot->description =
"Search for a node by name and focus and select it";
1415 ot->idname =
"NODE_OT_find_node";
WorkSpace * CTX_wm_workspace(const bContext *C)
SpaceNode * CTX_wm_space_node(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
void BKE_viewer_path_clear(ViewerPath *viewer_path)
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
#define BLI_assert_unreachable()
bool BLI_lasso_is_point_inside(blender::Span< blender::int2 > mcoords, int sx, int sy, int error_value)
void BLI_lasso_boundbox(rcti *rect, blender::Span< blender::int2 > mcoords)
#define LISTBASE_FOREACH(type, var, list)
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest)
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
bool BLI_rcti_isect_pt(const struct rcti *rect, int x, int y)
bool BLI_rctf_isect_circle(const struct rctf *rect, const float xy[2], float radius)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
void BLI_rctf_pad(struct rctf *rect, float pad_x, float pad_y)
bool BLI_rctf_isect_pt(const struct rctf *rect, float x, float y)
void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b)
size_t size_t size_t BLI_str_partition_ex_utf8(const char *str, const char *end, const unsigned int delim[], const char **r_sep, const char **r_suf, bool from_right) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define STREQLEN(a, b, n)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_id_tag_update_for_side_effect_request(Depsgraph *depsgraph, ID *id, unsigned int flags)
void ED_node_set_active(Main *bmain, SpaceNode *snode, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
void ED_node_set_active_viewer_key(SpaceNode *snode)
bool ED_operator_node_active(bContext *C)
eSelectOp ED_select_op_modal(eSelectOp sel_op, bool is_first)
#define SEL_OP_USE_PRE_DESELECT(sel_op)
std::string ED_select_circle_get_name(wmOperatorType *ot, PointerRNA *ptr)
SelectPick_Params ED_select_pick_params_from_operator(PointerRNA *ptr) ATTR_NONNULL(1)
std::string ED_select_pick_get_name(wmOperatorType *ot, PointerRNA *ptr)
bool ED_view3d_has_workbench_in_texture_color(const Scene *scene, const Object *ob, const View3D *v3d)
@ UI_BLOCK_THEME_STYLE_POPUP
void UI_block_theme_style_set(uiBlock *block, char theme_style)
uiBlock * UI_block_begin(const bContext *C, ARegion *region, std::string name, blender::ui::EmbossType emboss)
void UI_block_bounds_set_popup(uiBlock *block, int addval, const int bounds_offset[2])
uiBut * uiDefBut(uiBlock *block, int type, int retval, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg, uiFreeArgFunc arg_free)
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, bool free_arg, uiFreeArgFunc search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
uiBut * uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxncpy, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
int UI_searchbox_size_x_guess(const bContext *C, const uiButSearchUpdateFn update_fn, void *arg)
bool UI_search_item_add(uiSearchItems *items, blender::StringRef name, void *poin, int iconid, int but_flag, uint8_t name_prefix_offset)
#define UI_SEARCHBOX_BOUNDS
int UI_searchbox_size_y()
@ UI_BLOCK_MOVEMOUSE_QUIT
void UI_block_flag_enable(uiBlock *block, int flag)
@ UI_BUT_ACTIVATE_ON_INIT
void UI_but_flag_enable(uiBut *but, int flag)
bool UI_view2d_view_to_region_clip(const View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL()
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
void UI_view2d_region_to_view_rctf(const View2D *v2d, const rctf *rect_src, rctf *rect_dst) ATTR_NONNULL()
@ OPTYPE_DEPENDS_ON_CURSOR
BPy_StructRNA * depsgraph
constexpr bool contains(int64_t value) const
constexpr int64_t first_index(const T &search_value) const
constexpr IndexRange index_range() const
void add(const StringRef str, T *user_data, const int weight=0)
Vector< T * > query(const StringRef query) const
static bool is_inside(int x, int y, int cols, int rows)
std::string node_label(const bNodeTree &ntree, const bNode &node)
bNode * node_get_active(bNodeTree &ntree)
Span< const bNodeZoneType * > all_zone_types()
bool node_set_selected(bNode &node, bool select)
static bool has_workbench_in_texture_color(const wmWindowManager *wm, const Scene *scene, const Object *ob)
static uiBlock * node_find_menu(bContext *C, ARegion *region, void *arg_optype)
static bool node_select_grouped_type(bNodeTree &node_tree, bNode &node_act)
static std::string node_find_create_label(const bNodeTree &ntree, const bNode &node)
rctf node_frame_rect_inside(const SpaceNode &snode, const bNode &node)
void node_deselect_all_input_sockets(bNodeTree &node_tree, bool deselect_nodes)
static void node_find_exec_fn(bContext *C, void *, void *arg2)
void NODE_OT_select_circle(wmOperatorType *ot)
static bool is_position_over_node_or_socket(SpaceNode &snode, ARegion ®ion, const float2 &mouse)
void tree_draw_order_update(bNodeTree &ntree)
static wmOperatorStatus node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus node_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool space_node_view_flag(bContext &C, SpaceNode &snode, ARegion ®ion, int node_flag, int smooth_viewtx)
static bool node_mouse_select(bContext *C, wmOperator *op, const int2 mval, const SelectPick_Params ¶ms)
static wmOperatorStatus node_select_linked_from_exec(bContext *C, wmOperator *)
static bool do_lasso_select_node(bContext *C, const Span< int2 > mcoords, eSelectOp sel_op)
static wmOperatorStatus node_box_select_exec(bContext *C, wmOperator *op)
static wmOperatorStatus node_lasso_select_exec(bContext *C, wmOperator *op)
void node_select_paired(bNodeTree &node_tree)
static wmOperatorStatus node_select_grouped_exec(bContext *C, wmOperator *op)
void NODE_OT_find_node(wmOperatorType *ot)
static void node_find_update_fn(const bContext *C, void *, const char *str, uiSearchItems *items, const bool)
void NODE_OT_select_lasso(wmOperatorType *ot)
bool node_deselect_all(bNodeTree &node_tree)
void node_socket_select(bNode *node, bNodeSocket &sock)
bNodeSocket * node_find_indicated_socket(SpaceNode &snode, ARegion ®ion, const float2 &cursor, const eNodeSocketInOut in_out)
void NODE_OT_select(wmOperatorType *ot)
static bool node_select_grouped_name(bNodeTree &node_tree, bNode &node_act, const bool from_right)
Array< bNode * > tree_draw_order_calc_nodes_reversed(bNodeTree &ntree)
static void node_socket_toggle(bNode *node, bNodeSocket &sock, bool deselect_node)
static bool nodes_are_same_type_for_select(const bNode &a, const bNode &b)
static wmOperatorStatus node_select_same_type_step_exec(bContext *C, wmOperator *op)
static wmOperatorStatus node_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void node_socket_deselect(bNode *node, bNodeSocket &sock, bool deselect_node)
void NODE_OT_select_grouped(wmOperatorType *ot)
VectorSet< bNode * > get_selected_nodes(bNodeTree &node_tree)
void NODE_OT_select_linked_from(wmOperatorType *ot)
void node_deselect_all_output_sockets(bNodeTree &node_tree, bool deselect_nodes)
static wmOperatorStatus node_select_exec(bContext *C, wmOperator *op)
static bNode * node_under_mouse_select(const SpaceNode &snode, const float2 mouse)
void NODE_OT_select_same_type_step(wmOperatorType *ot)
void node_select_single(bContext &C, bNode &node)
static bool node_select_grouped_color(bNodeTree &node_tree, bNode &node_act)
void NODE_OT_select_linked_to(wmOperatorType *ot)
static bool any_node_selected(const bNodeTree &node_tree)
@ NODE_SELECT_GROUPED_SUFIX
@ NODE_SELECT_GROUPED_TYPE
@ NODE_SELECT_GROUPED_PREFIX
@ NODE_SELECT_GROUPED_COLOR
bool node_or_socket_isect_event(const bContext &C, const wmEvent &event)
static wmOperatorStatus node_circleselect_exec(bContext *C, wmOperator *op)
static wmOperatorStatus node_select_all_exec(bContext *C, wmOperator *op)
static bool is_event_over_node_or_socket(const bContext &C, const wmEvent &event)
static bool node_frame_select_isect_mouse(const SpaceNode &snode, const bNode &node, const float2 &mouse)
static wmOperatorStatus node_select_linked_to_exec(bContext *C, wmOperator *)
void NODE_OT_select_box(wmOperatorType *ot)
void NODE_OT_select_all(wmOperatorType *ot)
static wmOperatorStatus node_lasso_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
std::optional< ViewerPathForGeometryNodesViewer > parse_geometry_nodes_viewer(const ViewerPath &viewer_path)
void activate_geometry_node(Main &bmain, SpaceNode &snode, bNode &node)
T max(const T &a, const T &b)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
#define NODE_RESIZE_MARGIN
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, const int len, const int *default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
SpaceNode_Runtime * runtime
struct bNodeTree * edittree
bNodeRuntimeHandle * runtime
struct wmOperatorType * type
void WM_event_drag_start_mval(const wmEvent *event, const ARegion *region, int r_mval[2])
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
bool WM_gesture_is_modal_first(const wmGesture *gesture)
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
wmOperatorStatus WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Array< int2 > WM_gesture_lasso_path_to_array(bContext *, wmOperator *op)
wmOperatorStatus WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
wmOperatorStatus WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_operator_properties_gesture_box(wmOperatorType *ot)
void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
void WM_operator_properties_border_to_rctf(wmOperator *op, rctf *r_rect)
void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
void WM_operator_properties_gesture_circle(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
void WM_operator_properties_mouse_select(wmOperatorType *ot)
wmOperatorStatus WM_operator_flag_only_pass_through_on_press(wmOperatorStatus retval, const wmEvent *event)
wmOperatorStatus WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
int WM_operator_smooth_viewtx_get(const wmOperator *op)