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
This commit is contained in:
parent
b8b7b47a00
commit
d7caae56c4
Notes:
blender-bot
2023-02-14 11:28:39 +01:00
Referenced by issue #87567, Crash when typing in attribute to a node that doesn't have a linkage in Geometry Node.
|
@ -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);
|
||||
|
|
|
@ -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<AttributeSearchData *>(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<AvailableAttributeInfo> &attribute_hints = ui_storage->attribute_hints;
|
||||
const Set<AvailableAttributeInfo> &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<bNodeSocket *>(socket_ptr->data)});
|
||||
AttributeSearchData *data = OBJECT_GUARDED_NEW(AttributeSearchData,
|
||||
{tree_ui_storage->dummy_info_for_search,
|
||||
*ui_storage,
|
||||
*static_cast<bNodeSocket *>(socket_ptr->data)});
|
||||
|
||||
UI_but_func_search_set_results_are_suggestions(but, true);
|
||||
UI_but_func_search_set_sep_string(but, MENU_SEP);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue