Page MenuHome
Paste P1380

WIP fix for search menus for string properties
ActivePublic

Authored by Julian Eisel (Severin) on May 11 2020, 11:05 AM.
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 4aca3b41381..1979bbb650a 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1590,7 +1590,8 @@ void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string
int UI_searchbox_size_y(void);
int UI_searchbox_size_x(void);
/* check if a string is in an existing search box */
-int UI_search_items_find_index(uiSearchItems *items, const char *name);
+int UI_search_items_find_index_from_name(uiSearchItems *items, const char *name);
+int UI_search_items_find_index_from_data(uiSearchItems *items, const void *data);
void UI_but_node_link_set(uiBut *but, struct bNodeSocket *socket, const float draw_color[4]);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 18df67be545..8118ccf8290 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2921,6 +2921,7 @@ static void ui_but_string_free_internal(uiBut *but)
}
}
+#include "BKE_lib_id.h"
bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
{
if (but->rnaprop && but->rnapoin.data && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
@@ -2930,6 +2931,23 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
type = RNA_property_type(but->rnaprop);
if (type == PROP_STRING) {
+ /* Special treatment for search buttons. */
+ if (but->rnasearchprop && but->func_arg2) {
+ PointerRNA rptr;
+ char *name = NULL;
+
+ if (RNA_property_collection_lookup_data(
+ &but->rnasearchpoin, but->rnasearchprop, but->func_arg2, &rptr)) {
+ name = RNA_struct_name_get_alloc(&rptr, NULL, 0, NULL);
+ }
+
+ if (name) {
+ RNA_property_string_set(&but->rnapoin, but->rnaprop, name);
+ MEM_freeN(name);
+ return true;
+ }
+ }
+
/* RNA string */
RNA_property_string_set(&but->rnapoin, but->rnaprop, str);
return true;
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index cefb584eed4..9f5af73fea2 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -174,7 +174,7 @@ int UI_searchbox_size_x(void)
return 12 * UI_UNIT_X;
}
-int UI_search_items_find_index(uiSearchItems *items, const char *name)
+int UI_search_items_find_index_from_name(uiSearchItems *items, const char *name)
{
int i;
for (i = 0; i < items->totitem; i++) {
@@ -185,6 +185,17 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name)
return -1;
}
+int UI_search_items_find_index_from_data(uiSearchItems *items, const void *data)
+{
+ for (int i = 0; i < items->totitem; i++) {
+ if (items->pointers[i] == data) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
/* region is the search box itself */
static void ui_searchbox_select(bContext *C, ARegion *region, uiBut *but, int step)
{
@@ -256,7 +267,7 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr
int ui_searchbox_find_index(ARegion *region, const char *name)
{
uiSearchboxData *data = region->regiondata;
- return UI_search_items_find_index(&data->items, name);
+ return UI_search_items_find_index_from_name(&data->items, name);
}
/* x and y in screencoords */
@@ -416,9 +427,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
int a;
for (a = 0; a < data->items.totitem; a++) {
- const char *name = data->items.names[a];
- const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
- if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
+ if (but->func_arg2 == data->items.pointers[a]) {
data->active = a;
break;
}
@@ -914,7 +923,7 @@ void ui_but_search_refresh(uiBut *but)
UI_but_flag_enable(but, UI_BUT_REDALERT);
}
else if (items->more == 0) {
- if (UI_search_items_find_index(items, but->drawstr) == -1) {
+ if (but->func_arg2 && (UI_search_items_find_index_from_data(items, but->func_arg2) == -1)) {
UI_but_flag_enable(but, UI_BUT_REDALERT);
}
}
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 0ccf982fd29..f84cacce5c3 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -540,7 +540,7 @@ static void merged_element_search_cb_recursive(
iconid = tree_element_get_icon(tselem, te).icon;
/* Don't allow duplicate named items */
- if (UI_search_items_find_index(items, name) == -1) {
+ if (UI_search_items_find_index_from_name(items, name) == -1) {
if (!UI_search_item_add(items, name, te, iconid, 0)) {
break;
}
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index d2e27bdbcad..e0c011ddb51 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1004,6 +1004,10 @@ void RNA_property_collection_next(CollectionPropertyIterator *iter);
void RNA_property_collection_skip(CollectionPropertyIterator *iter, int num);
void RNA_property_collection_end(CollectionPropertyIterator *iter);
int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop);
+int RNA_property_collection_lookup_data(PointerRNA *ptr,
+ PropertyRNA *prop,
+ const void *data,
+ PointerRNA *r_ptr);
int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr);
int RNA_property_collection_lookup_int(PointerRNA *ptr,
PropertyRNA *prop,
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 85892758a88..91886351b9a 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -4079,6 +4079,32 @@ void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
}
}
+int RNA_property_collection_lookup_data(PointerRNA *ptr,
+ PropertyRNA *prop,
+ const void *data,
+ PointerRNA *r_ptr)
+{
+ BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
+
+ /* no callback defined, just iterate and find the nth item */
+ CollectionPropertyIterator iter;
+
+ RNA_property_collection_begin(ptr, prop, &iter);
+ for (; iter.valid; RNA_property_collection_next(&iter)) {
+ if (data && iter.ptr.data == data) {
+ *r_ptr = iter.ptr;
+ break;
+ }
+ }
+ RNA_property_collection_end(&iter);
+
+ if (!iter.valid) {
+ memset(r_ptr, 0, sizeof(*r_ptr));
+ }
+
+ return iter.valid;
+}
+
int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
{
CollectionPropertyIterator iter;
@@ -5302,8 +5328,8 @@ static bool rna_path_parse(PointerRNA *ptr,
* indicated by fully resolving the path.
*
* \warning Unlike \a RNA_path_resolve_property(), that one *will* try to follow RNAPointers,
- * e.g. the path 'parent' applied to a RNAObject \a ptr will return the object.parent in \a r_ptr,
- * and a NULL \a r_prop...
+ * e.g. the path 'parent' applied to a RNAObject \a ptr will return the object.parent in \a
+ * r_ptr, and a NULL \a r_prop...
*
* \note Assumes all pointers provided are valid
* \return True if path can be resolved to a valid "pointer + property" OR "pointer only"
@@ -5937,8 +5963,8 @@ char *RNA_path_from_real_ID_to_property_index(
{
char *path = RNA_path_from_ID_to_property_index(ptr, prop, index_dim, index);
- /* NULL path is always an error here, in that case do not return the 'fake ID from real ID' part
- * of the path either. */
+ /* NULL path is always an error here, in that case do not return the 'fake ID from real ID'
+ * part of the path either. */
return path != NULL ? rna_prepend_real_ID_path(bmain, ptr->owner_id, path, r_real_id) : NULL;
}