UI: String Search: Add an optional weight parameter
This builds off of rBf951aa063f7, adding a weight parameter which can be used to change the order of items when they have the same match score. In the future, if string searching gets a C++ API, we could use an optional parameter for the weight, since it is not used yet. This will be used for the node link drag search menu (D8286). Differential Revision: https://developer.blender.org/D13559
This commit is contained in:
parent
a90c356467
commit
0606adceb3
|
@ -26,8 +26,11 @@ StringSearch *BLI_string_search_new(void);
|
|||
/**
|
||||
* Add a new possible result to the search.
|
||||
* The caller keeps ownership of all parameters.
|
||||
*
|
||||
* \param weight: Can be used to customize the order when multiple items have the same match score.
|
||||
*/
|
||||
void BLI_string_search_add(StringSearch *search, const char *str, void *user_data);
|
||||
void BLI_string_search_add(StringSearch *search, const char *str, void *user_data, int weight);
|
||||
|
||||
/**
|
||||
* Filter and sort all previously added search items.
|
||||
* Returns an array containing the filtered user data.
|
||||
|
|
|
@ -389,6 +389,7 @@ struct SearchItem {
|
|||
blender::Span<blender::StringRef> normalized_words;
|
||||
int length;
|
||||
void *user_data;
|
||||
int weight;
|
||||
};
|
||||
|
||||
struct StringSearch {
|
||||
|
@ -401,14 +402,19 @@ StringSearch *BLI_string_search_new()
|
|||
return new StringSearch();
|
||||
}
|
||||
|
||||
void BLI_string_search_add(StringSearch *search, const char *str, void *user_data)
|
||||
void BLI_string_search_add(StringSearch *search,
|
||||
const char *str,
|
||||
void *user_data,
|
||||
const int weight)
|
||||
{
|
||||
using namespace blender;
|
||||
Vector<StringRef, 64> words;
|
||||
StringRef str_ref{str};
|
||||
string_search::extract_normalized_words(str_ref, search->allocator, words);
|
||||
search->items.append(
|
||||
{search->allocator.construct_array_copy(words.as_span()), (int)str_ref.size(), user_data});
|
||||
search->items.append({search->allocator.construct_array_copy(words.as_span()),
|
||||
(int)str_ref.size(),
|
||||
user_data,
|
||||
weight});
|
||||
}
|
||||
|
||||
int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data)
|
||||
|
@ -449,6 +455,11 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d
|
|||
std::sort(indices.begin(), indices.end(), [&](int a, int b) {
|
||||
return search->items[a].length < search->items[b].length;
|
||||
});
|
||||
/* Prefer items with larger weights. Use `stable_sort` so that if the weights are the same,
|
||||
* the order won't be changed. */
|
||||
std::stable_sort(indices.begin(), indices.end(), [&](int a, int b) {
|
||||
return search->items[a].weight > search->items[b].weight;
|
||||
});
|
||||
}
|
||||
sorted_result_indices.extend(indices);
|
||||
}
|
||||
|
|
|
@ -6733,7 +6733,7 @@ static void operator_enum_search_update_fn(const struct bContext *C,
|
|||
|
||||
StringSearch *search = BLI_string_search_new();
|
||||
for (const EnumPropertyItem *item = all_items; item->identifier; item++) {
|
||||
BLI_string_search_add(search, item->name, (void *)item);
|
||||
BLI_string_search_add(search, item->name, (void *)item, 0);
|
||||
}
|
||||
|
||||
const EnumPropertyItem **filtered_items;
|
||||
|
|
|
@ -106,7 +106,7 @@ void attribute_search_add_items(StringRefNull str,
|
|||
continue;
|
||||
}
|
||||
|
||||
BLI_string_search_add(search, item->name.c_str(), (void *)item);
|
||||
BLI_string_search_add(search, item->name.c_str(), (void *)item, 0);
|
||||
}
|
||||
|
||||
GeometryAttributeInfo **filtered_items;
|
||||
|
|
|
@ -1014,7 +1014,7 @@ static void menu_search_update_fn(const bContext *UNUSED(C),
|
|||
StringSearch *search = BLI_string_search_new();
|
||||
|
||||
LISTBASE_FOREACH (MenuSearch_Item *, item, &data->items) {
|
||||
BLI_string_search_add(search, item->drawwstr_full, item);
|
||||
BLI_string_search_add(search, item->drawwstr_full, item, 0);
|
||||
}
|
||||
|
||||
MenuSearch_Item **filtered_items;
|
||||
|
|
|
@ -435,7 +435,7 @@ static void id_search_cb(const bContext *C,
|
|||
/* ID listbase */
|
||||
LISTBASE_FOREACH (ID *, id, lb) {
|
||||
if (id_search_allows_id(template_ui, flag, id, str)) {
|
||||
BLI_string_search_add(search, id->name + 2, id);
|
||||
BLI_string_search_add(search, id->name + 2, id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -470,7 +470,7 @@ static void id_search_cb_tagged(const bContext *C,
|
|||
LISTBASE_FOREACH (ID *, id, lb) {
|
||||
if (id->tag & LIB_TAG_DOIT) {
|
||||
if (id_search_allows_id(template_ui, flag, id, str)) {
|
||||
BLI_string_search_add(search, id->name + 2, id);
|
||||
BLI_string_search_add(search, id->name + 2, id, 0);
|
||||
}
|
||||
id->tag &= ~LIB_TAG_DOIT;
|
||||
}
|
||||
|
|
|
@ -546,7 +546,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
|||
cis->name_prefix_offset = name_prefix_offset;
|
||||
cis->has_sep_char = has_sep_char;
|
||||
if (!skip_filter) {
|
||||
BLI_string_search_add(search, name, cis);
|
||||
BLI_string_search_add(search, name, cis, 0);
|
||||
}
|
||||
BLI_addtail(items_list, cis);
|
||||
if (name != name_buf) {
|
||||
|
|
|
@ -1204,7 +1204,7 @@ static void node_find_update_fn(const struct bContext *C,
|
|||
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
|
||||
char name[256];
|
||||
node_find_create_label(node, name, ARRAY_SIZE(name));
|
||||
BLI_string_search_add(search, name, node);
|
||||
BLI_string_search_add(search, name, node, 0);
|
||||
}
|
||||
|
||||
bNode **filtered_nodes;
|
||||
|
|
Loading…
Reference in New Issue