From d7caae56c4e33c21453fdeebab6c519e7cb99de6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 19 Apr 2021 12:31:18 -0500 Subject: Fix T87567: Crash adding item in empty attribute search The function applying the search used the dummy search info for when the item doesn't exist even when there was no UI data associated with the node at all. A fix is to only add the search menu when there is attribute info stored for the node. This is something I wanted to do anyway, since it makes it look more purposeful when there are no attribute info for a node, less like a bug. Differential Revision: https://developer.blender.org/D11016 --- source/blender/editors/space_node/drawnode.c | 2 +- .../space_node/node_geometry_attribute_search.cc | 49 ++++++++++++---------- source/blender/editors/space_node/node_intern.h | 3 +- source/blender/editors/space_node/node_templates.c | 2 +- 4 files changed, 32 insertions(+), 24 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 3d1f5231366..5110c14ef4d 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3458,7 +3458,7 @@ static void std_node_socket_draw( const bNodeTree *node_tree = (const bNodeTree *)node_ptr->owner_id; if (node_tree->type == NTREE_GEOMETRY) { - node_geometry_add_attribute_search_button(node_tree, node, ptr, row); + node_geometry_add_attribute_search_button(C, node_tree, node, ptr, row); } else { uiItemR(row, ptr, "default_value", DEFAULT_FLAGS, "", 0); diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc index 87944842079..856a90be5ae 100644 --- a/source/blender/editors/space_node/node_geometry_attribute_search.cc +++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc @@ -46,8 +46,8 @@ using blender::Set; using blender::StringRef; struct AttributeSearchData { - const bNodeTree &node_tree; - const bNode &node; + AvailableAttributeInfo &dummy_info_for_search; + const NodeUIStorage &ui_storage; bNodeSocket &socket; }; @@ -82,37 +82,31 @@ static bool attribute_search_item_add(uiSearchItems *items, const AvailableAttri items, search_item_text.c_str(), (void *)&item, ICON_NONE, UI_BUT_HAS_SEP_CHAR, 0); } -static void attribute_search_update_fn( - const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first) +static void attribute_search_update_fn(const bContext *UNUSED(C), + void *arg, + const char *str, + uiSearchItems *items, + const bool is_first) { AttributeSearchData *data = static_cast(arg); - NodeTreeUIStorage *tree_ui_storage = data->node_tree.ui_storage; - if (tree_ui_storage == nullptr) { - return; - } - const NodeUIStorage *ui_storage = BKE_node_tree_ui_storage_get_from_context( - C, data->node_tree, data->node); - if (ui_storage == nullptr) { - return; - } - const Set &attribute_hints = ui_storage->attribute_hints; + const Set &attribute_hints = data->ui_storage.attribute_hints; /* Any string may be valid, so add the current search string along with the hints. */ if (str[0] != '\0') { /* Note that the attribute domain and data type are dummies, since * #AvailableAttributeInfo equality is only based on the string. */ if (!attribute_hints.contains(AvailableAttributeInfo{str, ATTR_DOMAIN_AUTO, CD_PROP_BOOL})) { - tree_ui_storage->dummy_info_for_search.name = std::string(str); - UI_search_item_add(items, str, &tree_ui_storage->dummy_info_for_search, ICON_ADD, 0, 0); + data->dummy_info_for_search.name = std::string(str); + UI_search_item_add(items, str, &data->dummy_info_for_search, ICON_ADD, 0, 0); } } if (str[0] == '\0' && !is_first) { /* Allow clearing the text field when the string is empty, but not on the first pass, * or opening an attribute field for the first time would show this search item. */ - tree_ui_storage->dummy_info_for_search.name = std::string(str); - UI_search_item_add(items, str, &tree_ui_storage->dummy_info_for_search, ICON_X, 0, 0); + data->dummy_info_for_search.name = std::string(str); + UI_search_item_add(items, str, &data->dummy_info_for_search, ICON_X, 0, 0); } /* Don't filter when the menu is first opened, but still run the search @@ -148,11 +142,22 @@ static void attribute_search_exec_fn(bContext *UNUSED(C), void *data_v, void *it BLI_strncpy(value->value, item->name.c_str(), MAX_NAME); } -void node_geometry_add_attribute_search_button(const bNodeTree *node_tree, +void node_geometry_add_attribute_search_button(const bContext *C, + const bNodeTree *node_tree, const bNode *node, PointerRNA *socket_ptr, uiLayout *layout) { + const NodeUIStorage *ui_storage = BKE_node_tree_ui_storage_get_from_context( + C, *node_tree, *node); + + if (ui_storage == nullptr) { + uiItemR(layout, socket_ptr, "default_value", 0, "", 0); + return; + } + + const NodeTreeUIStorage *tree_ui_storage = node_tree->ui_storage; + uiBlock *block = uiLayoutGetBlock(layout); uiBut *but = uiDefIconTextButR(block, UI_BTYPE_SEARCH_MENU, @@ -172,8 +177,10 @@ void node_geometry_add_attribute_search_button(const bNodeTree *node_tree, 0.0f, ""); - AttributeSearchData *data = OBJECT_GUARDED_NEW( - AttributeSearchData, {*node_tree, *node, *static_cast(socket_ptr->data)}); + AttributeSearchData *data = OBJECT_GUARDED_NEW(AttributeSearchData, + {tree_ui_storage->dummy_info_for_search, + *ui_storage, + *static_cast(socket_ptr->data)}); UI_but_func_search_set_results_are_suggestions(but, true); UI_but_func_search_set_sep_string(but, MENU_SEP); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index c350e50b524..2fcc59cde0b 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -310,7 +310,8 @@ void NODE_OT_cryptomatte_layer_add(struct wmOperatorType *ot); void NODE_OT_cryptomatte_layer_remove(struct wmOperatorType *ot); /* node_geometry_attribute_search.cc */ -void node_geometry_add_attribute_search_button(const struct bNodeTree *node_tree, +void node_geometry_add_attribute_search_button(const struct bContext *C, + const struct bNodeTree *node_tree, const struct bNode *node, struct PointerRNA *socket_ptr, struct uiLayout *layout); diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 54145f62895..c880f3e99d8 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -846,7 +846,7 @@ static void ui_node_draw_input( case SOCK_STRING: { const bNodeTree *node_tree = (const bNodeTree *)nodeptr.owner_id; if (node_tree->type == NTREE_GEOMETRY) { - node_geometry_add_attribute_search_button(node_tree, node, &inputptr, row); + node_geometry_add_attribute_search_button(C, node_tree, node, &inputptr, row); } else { uiItemR(sub, &inputptr, "default_value", 0, "", ICON_NONE); -- cgit v1.2.3