Cleanup: Deduplicate UI list filtering checks

Followup to 303014bfac.
This commit is contained in:
Julian Eisel 2024-03-22 16:04:03 +01:00
parent 9f0cc7fe64
commit b1db1702c6
4 changed files with 33 additions and 30 deletions

View File

@ -2704,6 +2704,12 @@ void uiTemplateNodeTreeInterface(uiLayout *layout, PointerRNA *ptr);
*/
void uiTemplateNodeInputs(uiLayout *layout, bContext *C, PointerRNA *ptr);
/**
* \return: True if the list item with unfiltered, unordered index \a item_idx is visible given the
* current filter settings.
*/
bool UI_list_item_index_is_filtered_visible(const struct uiList *ui_list, int item_idx);
/**
* \return An RNA pointer for the operator properties.
*/

View File

@ -9755,13 +9755,9 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
const int *new_order = dyn_data->items_filter_neworder;
int org_idx = -1, len = dyn_data->items_len;
int current_idx = -1;
const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
for (int i = 0; i < len; i++) {
if (!dyn_data->items_filter_flags ||
(((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM_NEVER_SHOW) == 0) &&
(dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude))
{
if (UI_list_item_index_is_filtered_visible(ui_list, i)) {
org_order[new_order ? new_order[++org_idx] : ++org_idx] = i;
if (i == value) {
current_idx = new_order ? new_order[org_idx] : org_idx;

View File

@ -303,6 +303,23 @@ void UI_list_filter_and_sort_items(uiList *ui_list,
}
}
bool UI_list_item_index_is_filtered_visible(const uiList *ui_list, const int item_idx)
{
const uiListDyn *dyn_data = ui_list->dyn_data;
if (!dyn_data->items_filter_flags) {
/* If there are no filter flags to check, always consider all items visible. */
return true;
}
if (dyn_data->items_filter_flags[item_idx] & UILST_FLT_ITEM_NEVER_SHOW) {
return false;
}
const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
return (dyn_data->items_filter_flags[item_idx] & UILST_FLT_ITEM) ^ filter_exclude;
}
/**
* Default UI List filtering: Filter by name.
*/
@ -418,21 +435,18 @@ static bool ui_template_list_data_retrieve(const char *listtype_name,
static void ui_template_list_collect_items(PointerRNA *list_ptr,
PropertyRNA *list_prop,
uiListDyn *dyn_data,
int filter_exclude,
bool order_reverse,
const uiList *ui_list,
int activei,
TemplateListItems *r_items)
{
const uiListDyn *dyn_data = ui_list->dyn_data;
const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0;
int i = 0;
int reorder_i = 0;
bool activei_mapping_pending = true;
RNA_PROP_BEGIN (list_ptr, itemptr, list_prop) {
if (!dyn_data->items_filter_flags ||
(((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM_NEVER_SHOW) == 0) &&
((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)))
{
if (UI_list_item_index_is_filtered_visible(ui_list, i)) {
int new_order_idx;
if (dyn_data->items_filter_neworder) {
new_order_idx = dyn_data->items_filter_neworder[reorder_i++];
@ -493,8 +507,6 @@ static void ui_template_list_collect_display_items(const bContext *C,
/* Filter list items! (not for compact layout, though) */
if (input_data->dataptr.data && input_data->prop) {
const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0;
int items_shown;
#if 0
int prev_ii = -1, prev_i;
@ -516,13 +528,8 @@ static void ui_template_list_collect_display_items(const bContext *C,
MEM_mallocN(sizeof(*r_items->item_vec) * items_shown, __func__));
// printf("%s: items shown: %d.\n", __func__, items_shown);
ui_template_list_collect_items(&input_data->dataptr,
input_data->prop,
dyn_data,
filter_exclude,
order_reverse,
input_data->active_item_idx,
r_items);
ui_template_list_collect_items(
&input_data->dataptr, input_data->prop, ui_list, input_data->active_item_idx, r_items);
}
if (dyn_data->items_shown >= 0) {
r_items->tot_items = dyn_data->items_shown;

View File

@ -612,7 +612,7 @@ static void uilist_filter_items(uiList *ui_list,
/* We have to do some final checks and transforms... */
{
int i, filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
int i;
if (filter_flags) {
flt_data->items_filter_flags = static_cast<int *>(MEM_mallocN(sizeof(int) * len, __func__));
memcpy(flt_data->items_filter_flags, filter_flags, sizeof(int) * len);
@ -625,10 +625,7 @@ static void uilist_filter_items(uiList *ui_list,
int t_idx, t_ni, prev_ni;
flt_data->items_shown = 0;
for (i = 0, shown_idx = 0; i < len; i++) {
if (filter_flags[i] & UILST_FLT_ITEM_NEVER_SHOW) {
BLI_assert_msg(false, "Bit reserved for internal use");
}
else if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
if (UI_list_item_index_is_filtered_visible(ui_list, i)) {
filter_neworder[shown_idx++] = filter_neworder[i];
}
}
@ -656,10 +653,7 @@ static void uilist_filter_items(uiList *ui_list,
/* we still have to set flt_data->items_shown... */
flt_data->items_shown = 0;
for (i = 0; i < len; i++) {
if (filter_flags[i] & UILST_FLT_ITEM_NEVER_SHOW) {
/* Pass. */
}
else if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
if (UI_list_item_index_is_filtered_visible(ui_list, i)) {
flt_data->items_shown++;
}
}