diff --git a/source/blender/editors/space_node/add_node_search.cc b/source/blender/editors/space_node/add_node_search.cc index 56cfb2480e9..afacad6f247 100644 --- a/source/blender/editors/space_node/add_node_search.cc +++ b/source/blender/editors/space_node/add_node_search.cc @@ -37,16 +37,10 @@ struct bContext; namespace blender::ed::space_node { -struct AddNodeItem { - nodes::AddNodeInfo info; - std::string identifier; - const AssetRepresentation *asset; -}; - struct AddNodeSearchStorage { float2 cursor; bool use_transform; - Vector search_add_items; + Vector search_add_items; char search[256]; bool update_items_tag = true; }; @@ -67,7 +61,7 @@ static void add_node_search_listen_fn(const wmRegionListenerParams *params, void static void search_items_for_asset_metadata(const bNodeTree &node_tree, const AssetHandle asset_handle, - Vector &search_items) + nodes::GatherAddNodeSearchParams ¶ms) { const AssetMetaData &asset_data = *ED_asset_handle_get_metadata(&asset_handle); const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&asset_data, "type"); @@ -76,28 +70,27 @@ static void search_items_for_asset_metadata(const bNodeTree &node_tree, } const AssetRepresentation *asset = ED_asset_handle_get_representation(&asset_handle); - AddNodeItem item{}; - item.info.ui_name = ED_asset_handle_get_name(&asset_handle); - item.identifier = node_tree.typeinfo->group_idname; - item.info.description = asset_data.description == nullptr ? "" : asset_data.description; - item.asset = asset; - item.info.after_add_fn = [asset](const bContext &C, bNodeTree &node_tree, bNode &node) { - Main &bmain = *CTX_data_main(&C); - node.flag &= ~NODE_OPTIONS; - node.id = ED_asset_get_local_id_from_asset_or_append_and_reuse(&bmain, asset, ID_NT); - id_us_plus(node.id); - BKE_ntree_update_tag_node_property(&node_tree, &node); - DEG_relations_tag_update(&bmain); - }; - - search_items.append(std::move(item)); + params.add_single_node_item(ED_asset_handle_get_name(&asset_handle), + asset_data.description == nullptr ? "" : asset_data.description, + [asset](const bContext &C, bNodeTree &node_tree, bNode &node) { + Main &bmain = *CTX_data_main(&C); + node.flag &= ~NODE_OPTIONS; + node.id = ED_asset_get_local_id_from_asset_or_append_and_reuse( + &bmain, asset, ID_NT); + id_us_plus(node.id); + BKE_ntree_update_tag_node_property(&node_tree, &node); + DEG_relations_tag_update(&bmain); + }); } static void gather_search_items_for_all_assets(const bContext &C, const bNodeTree &node_tree, Set &r_added_assets, - Vector &search_items) + Vector &search_items) { + const bNodeType &group_node_type = *nodeTypeFind(node_tree.typeinfo->group_idname); + nodes::GatherAddNodeSearchParams params(C, group_node_type, node_tree, search_items); + AssetLibraryReference library_ref{}; library_ref.custom_library_index = -1; library_ref.type = ASSET_LIBRARY_ALL; @@ -115,7 +108,7 @@ static void gather_search_items_for_all_assets(const bContext &C, /* If an asset with the same name has already been added, skip this. */ return true; } - search_items_for_asset_metadata(node_tree, asset, search_items); + search_items_for_asset_metadata(node_tree, asset, params); return true; }); } @@ -123,9 +116,11 @@ static void gather_search_items_for_all_assets(const bContext &C, static void gather_search_items_for_node_groups(const bContext &C, const bNodeTree &node_tree, const Set &local_assets, - Vector &search_items) + Vector &search_items) { - const StringRef group_node_id = node_tree.typeinfo->group_idname; + const StringRefNull group_node_id = node_tree.typeinfo->group_idname; + const bNodeType &group_node_type = *nodeTypeFind(group_node_id.c_str()); + nodes::GatherAddNodeSearchParams params(C, group_node_type, node_tree, search_items); Main &bmain = *CTX_data_main(&C); LISTBASE_FOREACH (bNodeTree *, node_group, &bmain.nodetrees) { @@ -138,23 +133,22 @@ static void gather_search_items_for_node_groups(const bContext &C, if (!nodeGroupPoll(&node_tree, node_group, nullptr)) { continue; } - AddNodeItem item{}; - item.info.ui_name = node_group->id.name + 2; - item.identifier = node_tree.typeinfo->group_idname; - item.info.after_add_fn = [node_group](const bContext &C, bNodeTree &node_tree, bNode &node) { - Main &bmain = *CTX_data_main(&C); - node.id = &node_group->id; - id_us_plus(node.id); - BKE_ntree_update_tag_node_property(&node_tree, &node); - DEG_relations_tag_update(&bmain); - }; - search_items.append(std::move(item)); + params.add_single_node_item( + node_group->id.name + 2, + "", + [node_group](const bContext &C, bNodeTree &node_tree, bNode &node) { + Main &bmain = *CTX_data_main(&C); + node.id = &node_group->id; + id_us_plus(node.id); + BKE_ntree_update_tag_node_property(&node_tree, &node); + DEG_relations_tag_update(&bmain); + }); } } static void gather_add_node_operations(const bContext &C, bNodeTree &node_tree, - Vector &r_search_items) + Vector &r_search_items) { NODE_TYPES_BEGIN (node_type) { const char *disabled_hint; @@ -167,15 +161,8 @@ static void gather_add_node_operations(const bContext &C, if (!node_type->gather_add_node_search_ops) { continue; } - Vector info_items; - nodes::GatherAddNodeSearchParams params(C, *node_type, node_tree, info_items); + nodes::GatherAddNodeSearchParams params(C, *node_type, node_tree, r_search_items); node_type->gather_add_node_search_ops(params); - for (nodes::AddNodeInfo &info : info_items) { - AddNodeItem item{}; - item.info = std::move(info); - item.identifier = node_type->idname; - r_search_items.append(item); - } } NODE_TYPES_END; @@ -200,19 +187,19 @@ static void add_node_search_update_fn( StringSearch *search = BLI_string_search_new(); - for (AddNodeItem &item : storage.search_add_items) { - BLI_string_search_add(search, item.info.ui_name.c_str(), &item, item.info.weight); + for (nodes::AddNodeItem &item : storage.search_add_items) { + BLI_string_search_add(search, item.ui_name.c_str(), &item, item.weight); } /* Don't filter when the menu is first opened, but still run the search * so the items are in the same order they will appear in while searching. */ const char *string = is_first ? "" : str; - AddNodeItem **filtered_items; + nodes::AddNodeItem **filtered_items; const int filtered_amount = BLI_string_search_query(search, string, (void ***)&filtered_items); for (const int i : IndexRange(filtered_amount)) { - AddNodeItem &item = *filtered_items[i]; - if (!UI_search_item_add(items, item.info.ui_name.c_str(), &item, ICON_NONE, 0, 0)) { + nodes::AddNodeItem &item = *filtered_items[i]; + if (!UI_search_item_add(items, item.ui_name.c_str(), &item, ICON_NONE, 0, 0)) { break; } } @@ -227,24 +214,13 @@ static void add_node_search_exec_fn(bContext *C, void *arg1, void *arg2) SpaceNode &snode = *CTX_wm_space_node(C); bNodeTree &node_tree = *snode.edittree; AddNodeSearchStorage &storage = *static_cast(arg1); - AddNodeItem *item = static_cast(arg2); + nodes::AddNodeItem *item = static_cast(arg2); if (item == nullptr) { return; } node_deselect_all(node_tree); - bNode *new_node = nodeAddNode(C, &node_tree, item->identifier.c_str()); - BLI_assert(new_node != nullptr); - - if (item->info.after_add_fn) { - item->info.after_add_fn(*C, node_tree, *new_node); - } - - new_node->locx = storage.cursor.x / UI_SCALE_FAC; - new_node->locy = storage.cursor.y / UI_SCALE_FAC + 20; - - nodeSetSelected(new_node, true); - nodeSetActive(&node_tree, new_node); + Vector new_nodes = item->add_fn(*C, node_tree, storage.cursor); /* Ideally it would be possible to tag the node tree in some way so it updates only after the * translate operation is finished, but normally moving nodes around doesn't cause updates. */ @@ -263,13 +239,12 @@ static void add_node_search_exec_fn(bContext *C, void *arg1, void *arg2) static ARegion *add_node_search_tooltip_fn( bContext *C, ARegion *region, const rcti *item_rect, void * /*arg*/, void *active) { - const AddNodeItem *item = static_cast(active); + const nodes::AddNodeItem *item = static_cast(active); uiSearchItemTooltipData tooltip_data{}; - BLI_strncpy(tooltip_data.description, - item->asset ? item->info.description.c_str() : TIP_(item->info.description.c_str()), - sizeof(tooltip_data.description)); + BLI_strncpy( + tooltip_data.description, TIP_(item->description.c_str()), sizeof(tooltip_data.description)); return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data); } diff --git a/source/blender/nodes/NOD_add_node_search.hh b/source/blender/nodes/NOD_add_node_search.hh index 0fa5395a33c..c499df813f4 100644 --- a/source/blender/nodes/NOD_add_node_search.hh +++ b/source/blender/nodes/NOD_add_node_search.hh @@ -5,6 +5,7 @@ #include #include "BLI_function_ref.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string_ref.hh" #include "BLI_vector.hh" @@ -16,25 +17,27 @@ struct bContext; namespace blender::nodes { -struct AddNodeInfo { - using AfterAddFn = std::function; +struct AddNodeItem { + using AddFn = + std::function(const bContext &C, bNodeTree &node_tree, float2 cursor)>; std::string ui_name; std::string description; - AfterAddFn after_add_fn; int weight = 0; + AddFn add_fn; }; class GatherAddNodeSearchParams { + using AfterAddFn = std::function; const bContext &C_; const bNodeType &node_type_; const bNodeTree &node_tree_; - Vector &r_items; + Vector &r_items; public: GatherAddNodeSearchParams(const bContext &C, const bNodeType &node_type, const bNodeTree &node_tree, - Vector &r_items) + Vector &r_items) : C_(C), node_type_(node_type), node_tree_(node_tree), r_items(r_items) { } @@ -57,10 +60,11 @@ class GatherAddNodeSearchParams { /** * \param weight: Used to customize the order when multiple search items match. */ - void add_item(std::string ui_name, - std::string description, - AddNodeInfo::AfterAddFn fn = {}, - int weight = 0); + void add_single_node_item(std::string ui_name, + std::string description, + AfterAddFn after_add_fn = {}, + int weight = 0); + void add_item(AddNodeItem item); }; void search_node_add_ops_for_basic_node(GatherAddNodeSearchParams ¶ms); diff --git a/source/blender/nodes/intern/add_node_search.cc b/source/blender/nodes/intern/add_node_search.cc index 241c6f80cb9..2f58f1ecff0 100644 --- a/source/blender/nodes/intern/add_node_search.cc +++ b/source/blender/nodes/intern/add_node_search.cc @@ -9,17 +9,39 @@ namespace blender::nodes { -void GatherAddNodeSearchParams::add_item(std::string ui_name, - std::string description, - AddNodeInfo::AfterAddFn fn, - int weight) +void GatherAddNodeSearchParams::add_single_node_item(std::string ui_name, + std::string description, + AfterAddFn after_add_fn, + int weight) { - r_items.append(AddNodeInfo{std::move(ui_name), std::move(description), std::move(fn), weight}); + AddNodeItem item; + item.ui_name = std::move(ui_name); + item.description = std::move(description); + item.weight = weight; + item.add_fn = [after_add_fn = std::move(after_add_fn), node_type = node_type_]( + const bContext &C, bNodeTree &node_tree, const float2 cursor) { + bNode *new_node = nodeAddNode(&C, &node_tree, node_type.idname); + new_node->locx = cursor.x / UI_SCALE_FAC; + new_node->locy = cursor.y / UI_SCALE_FAC + 20; + nodeSetSelected(new_node, true); + nodeSetActive(&node_tree, new_node); + if (after_add_fn) { + after_add_fn(C, node_tree, *new_node); + } + return Vector{new_node}; + }; + r_items.append(std::move(item)); +} + +void GatherAddNodeSearchParams::add_item(AddNodeItem item) +{ + r_items.append(std::move(item)); } void search_node_add_ops_for_basic_node(GatherAddNodeSearchParams ¶ms) { - params.add_item(IFACE_(params.node_type().ui_name), TIP_(params.node_type().ui_description)); + params.add_single_node_item(IFACE_(params.node_type().ui_name), + TIP_(params.node_type().ui_description)); } } // namespace blender::nodes diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index 20e0bacbf1d..65d209caaac 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -227,12 +227,12 @@ static void node_mix_gather_link_searches(GatherLinkSearchOpParams ¶ms) static void gather_add_node_searches(GatherAddNodeSearchParams ¶ms) { - params.add_item(IFACE_("Mix"), params.node_type().ui_description); - params.add_item(IFACE_("Mix Color"), - params.node_type().ui_description, - [](const bContext & /*C*/, bNodeTree & /*node_tree*/, bNode &node) { - node_storage(node).data_type = SOCK_RGBA; - }); + params.add_single_node_item(IFACE_("Mix"), params.node_type().ui_description); + params.add_single_node_item(IFACE_("Mix Color"), + params.node_type().ui_description, + [](const bContext & /*C*/, bNodeTree & /*node_tree*/, bNode &node) { + node_storage(node).data_type = SOCK_RGBA; + }); } static void node_mix_init(bNodeTree * /*tree*/, bNode *node)