[Bf-blender-cvs] [eef2a348a74] ui-asset-view-template: Refactor UIList template for further changes and to fix some glitches

Julian Eisel noreply at git.blender.org
Tue Mar 2 16:30:54 CET 2021


Commit: eef2a348a74a8a79b1ebd70b9e5028ba18bb13b9
Author: Julian Eisel
Date:   Tue Mar 2 16:23:32 2021 +0100
Branches: ui-asset-view-template
https://developer.blender.org/rBeef2a348a74a8a79b1ebd70b9e5028ba18bb13b9

Refactor UIList template for further changes and to fix some glitches

Could go further than that, I think this would benefit from some C++
features, but we can do that in another pass.

===================================================================

M	release/scripts/addons
M	source/blender/editors/include/UI_interface_icons.h
M	source/blender/editors/interface/interface_icons.c
M	source/blender/editors/interface/interface_template_asset_view.cc
M	source/blender/editors/interface/interface_templates.c
M	source/blender/makesdna/DNA_screen_types.h

===================================================================

diff --git a/release/scripts/addons b/release/scripts/addons
index 24e756c0da8..d142dc2d11d 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 24e756c0da89bdbf88dc22163ae3b7ef4f1fbb73
+Subproject commit d142dc2d11daf8100085fb8b345088e8de8154ec
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 266a538b6c3..37cf7229ffb 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -105,7 +105,10 @@ int UI_iconfile_get_index(const char *filename);
 
 struct PreviewImage *UI_icon_to_preview(int icon_id);
 
-int UI_icon_from_rnaptr(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big);
+int UI_icon_from_rnaptr(const struct bContext *C,
+                        struct PointerRNA *ptr,
+                        int rnaicon,
+                        const bool big);
 int UI_icon_from_idcode(const int idcode);
 int UI_icon_from_library(const struct ID *id);
 int UI_icon_from_object_mode(const int mode);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index c16c3d2c49a..39bac71e0c1 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -2205,7 +2205,7 @@ int UI_icon_from_library(const ID *id)
   return ICON_NONE;
 }
 
-int UI_icon_from_rnaptr(bContext *C, PointerRNA *ptr, int rnaicon, const bool big)
+int UI_icon_from_rnaptr(const bContext *C, PointerRNA *ptr, int rnaicon, const bool big)
 {
   ID *id = NULL;
 
diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc
index 9d973515200..23058bdab44 100644
--- a/source/blender/editors/interface/interface_template_asset_view.cc
+++ b/source/blender/editors/interface/interface_template_asset_view.cc
@@ -188,7 +188,7 @@ void uiTemplateAssetView(uiLayout *layout,
                     nullptr,
                     0,
                     0,
-                    UILST_LAYOUT_FLEXIBLE_GRID,
+                    UILST_LAYOUT_BIG_PREVIEW_GRID,
                     0,
                     false,
                     false,
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 5252cad3cc2..efd16b5804f 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -5804,36 +5804,304 @@ static void uilist_filter_items_default(struct uiList *ui_list,
   }
 }
 
+/**
+ * The validated data that was passed to #uiTemplateList (typically through Python).
+ * Populated through #ui_template_list_data_retrieve().
+ */
+typedef struct {
+  PointerRNA *dataptr;
+  PropertyRNA *prop;
+  PointerRNA *active_dataptr;
+  PropertyRNA *activeprop;
+  const char *item_dyntip_propname;
+
+  /* Index as stored in the input property. I.e. the index before sorting. */
+  int active_item_idx;
+} TemplateListInputData;
+
 typedef struct {
   PointerRNA item;
   int org_idx;
   int flt_flag;
 } _uilist_item;
 
+/**
+ * Container for the item vector and additional info.
+ */
+typedef struct {
+  _uilist_item *item_vec;
+  /* Index of the active item following visual order. I.e. unlike
+   * TemplateListInputData.active_item_idx, this is the index after sorting. */
+  int active_item_idx;
+  int tot_items;
+} TemplateListItems;
+
+typedef struct {
+  uiListDrawItemFunc draw_item;
+  uiListDrawFilterFunc draw_filter;
+
+  int rows;
+  int maxrows;
+  int columns;
+} TemplateListLayoutDrawData;
+
 typedef struct {
   int visual_items; /* Visual number of items (i.e. number of items we have room to display). */
   int start_idx;    /* Index of first item to display. */
   int end_idx;      /* Index of last item to display + 1. */
-} uiListLayoutdata;
+} TemplateListVisualInfo;
+
+/**
+ * For internal use only, but external users that set the iterator-callback via #uiTemplate
+ */
+typedef struct TemplateListIterData {
+  uiListDyn *dyn_data;
+
+  _uilist_item *items_ptr;
+
+  int filter_exclude;
+  bool order_reverse;
+  bool activei_mapping_pending;
+  int activei;
+
+  /* Just for the callback */
+  int current_iter_idx;
+  int reorder_idx;
+} TemplateListIterData;
+
+/**
+ * Validate input parameters and initialize \a r_data from that. Plus find the list-type and return
+ * it in \a r_list_type.
+ *
+ * \return false if the input data isn't valid. Will also raise an RNA warning in that case.
+ */
+static bool ui_template_list_data_retrieve(const char *listtype_name,
+                                           const char *list_id,
+                                           PointerRNA *dataptr,
+                                           const char *propname,
+                                           PointerRNA *active_dataptr,
+                                           const char *active_propname,
+                                           const char *item_dyntip_propname,
+                                           TemplateListInputData *r_input_data,
+                                           uiListType **r_list_type)
+{
+  /* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */
+  if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
+    RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
+                UI_UL_DEFAULT_CLASS_NAME);
+    return false;
+  }
+
+  if (!active_dataptr->data) {
+    RNA_warning("No active data");
+    return false;
+  }
+
+  if (dataptr->data) {
+    r_input_data->dataptr = dataptr;
+    r_input_data->prop = RNA_struct_find_property(dataptr, propname);
+    if (!r_input_data->prop) {
+      RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
+      return false;
+    }
+  }
+
+  r_input_data->active_dataptr = active_dataptr;
+  r_input_data->activeprop = RNA_struct_find_property(active_dataptr, active_propname);
+  if (!r_input_data->activeprop) {
+    RNA_warning(
+        "Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
+    return false;
+  }
+
+  if (r_input_data->prop) {
+    const PropertyType type = RNA_property_type(r_input_data->prop);
+    if (type != PROP_COLLECTION) {
+      RNA_warning("Expected a collection data property");
+      return false;
+    }
+  }
+
+  const PropertyType activetype = RNA_property_type(r_input_data->activeprop);
+  if (activetype != PROP_INT) {
+    RNA_warning("Expected an integer active data property");
+    return false;
+  }
+
+  /* Find the uiList type. */
+  if (!(*r_list_type = WM_uilisttype_find(listtype_name, false))) {
+    RNA_warning("List type %s not found", listtype_name);
+    return false;
+  }
+
+  r_input_data->active_item_idx = RNA_property_int_get(r_input_data->active_dataptr,
+                                                       r_input_data->activeprop);
+  r_input_data->item_dyntip_propname = item_dyntip_propname;
+
+  return true;
+}
+
+static void ui_template_list_count_items_cb(TemplateListIterData *iter_data,
+                                            PointerRNA *UNUSED(itemptr))
+{
+  iter_data->dyn_data->items_shown++;
+  iter_data->dyn_data->items_len++;
+}
+
+static void ui_template_list_collect_item_cb(TemplateListIterData *iter_data, PointerRNA *itemptr)
+{
+  uiListDyn *dyn_data = iter_data->dyn_data;
+
+  if (!dyn_data->items_filter_flags ||
+      ((dyn_data->items_filter_flags[iter_data->current_iter_idx] & UILST_FLT_ITEM) ^
+       iter_data->filter_exclude)) {
+    int new_order_idx;
+    if (dyn_data->items_filter_neworder) {
+      new_order_idx = dyn_data->items_filter_neworder[iter_data->reorder_idx++];
+      new_order_idx = iter_data->order_reverse ? dyn_data->items_shown - new_order_idx - 1 :
+                                                 new_order_idx;
+    }
+    else {
+      new_order_idx = iter_data->order_reverse ? dyn_data->items_shown - ++iter_data->reorder_idx :
+                                                 iter_data->reorder_idx++;
+    }
+    // printf("%s: ii: %d\n", __func__, ii);
+    iter_data->items_ptr[new_order_idx].item = *itemptr;
+    iter_data->items_ptr[new_order_idx].org_idx = iter_data->current_iter_idx;
+    iter_data->items_ptr[new_order_idx].flt_flag =
+        dyn_data->items_filter_flags ? dyn_data->items_filter_flags[iter_data->current_iter_idx] :
+                                       0;
+
+    if (iter_data->activei_mapping_pending && iter_data->activei == iter_data->current_iter_idx) {
+      iter_data->activei = new_order_idx;
+      /* So that we do not map again activei! */
+      iter_data->activei_mapping_pending = false;
+    }
+#if 0 /* For now, do not alter active element, even if it will be hidden... */
+          else if (activei < iter_data->current_iter_idx) {
+            /* We do not want an active but invisible item!
+             * Only exception is when all items are filtered out...
+             */
+            if (prev_order_idx >= 0) {
+              activei = prev_order_idx;
+              RNA_property_int_set(active_dataptr, activeprop, prev_i);
+            }
+            else {
+              activei = new_order_idx;
+              RNA_property_int_set(active_dataptr, activeprop, iter_data->current_iter_idx);
+            }
+          }
+          prev_i = iter_data->current_iter_idx;
+          prev_ii = new_order_idx;
+#endif
+  }
+  iter_data->current_iter_idx++;
+}
+
+/**
+ * Create the UI-list representation of the list items, sorted and filtered if needed.
+ */
+static void ui_template_list_collect_display_items(bContext *C,
+                                                   uiList *ui_list,
+                                                   const TemplateListInputData *input_data,
+                                                   const uiTemplateListItemsIterFn iter_items_fn,
+                                                   const uiListFilterItemsFunc filter_items_fn,
+                                        

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list