[Bf-blender-cvs] [d2a5a9d77a4] temp-asset-browser-poselib-merge: UI: Support defining UI lists in C

Julian Eisel noreply at git.blender.org
Wed Jul 14 22:53:11 CEST 2021


Commit: d2a5a9d77a451bd2b008e9ca5bf23465043fe71c
Author: Julian Eisel
Date:   Tue Jul 13 17:42:25 2021 +0200
Branches: temp-asset-browser-poselib-merge
https://developer.blender.org/rBd2a5a9d77a451bd2b008e9ca5bf23465043fe71c

UI: Support defining UI lists in C

So far all UI lists had to be defined in Python, this makes it possible
to define them in C as well. Note that there is a whole bunch of special
handling for the Python API that isn't there for C. I think most
importantly custom properties support, which currently can't be added
for C defined UI lists.

The upcoming asset view UI template will use this, which needs to be
defined in C.

Adds a new file `interface_template_list.cc`, which at this point is
mostly a dummy to have a place for the `ED_uilisttypes_ui()` definition.
I plan a separate cleanup to move the UI-list template to that file.

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/CMakeLists.txt
A	source/blender/editors/interface/interface_template_list.cc
M	source/blender/editors/space_api/spacetypes.c
M	source/blender/makesrna/intern/rna_ui.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_init_exit.c
M	source/blender/windowmanager/intern/wm_uilist_type.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 747ec776d80..020ca1f8f55 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2558,6 +2558,7 @@ typedef struct uiDragColorHandle {
 
 void ED_operatortypes_ui(void);
 void ED_keymap_ui(struct wmKeyConfig *keyconf);
+void ED_uilisttypes_ui(void);
 
 void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
 bool UI_drop_color_poll(struct bContext *C,
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 2cc3830042c..29f868eebb0 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -66,6 +66,7 @@ set(SRC
   interface_region_tooltip.c
   interface_regions.c
   interface_style.c
+  interface_template_list.cc
   interface_template_search_menu.c
   interface_template_search_operator.c
   interface_templates.c
diff --git a/source/blender/editors/interface/interface_template_list.cc b/source/blender/editors/interface/interface_template_list.cc
new file mode 100644
index 00000000000..90980b3c963
--- /dev/null
+++ b/source/blender/editors/interface/interface_template_list.cc
@@ -0,0 +1,27 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edinterface
+ *
+ * TODO: The UI list template implementation should be moved here.
+ */
+
+#include "UI_interface.h"
+
+void ED_uilisttypes_ui(void)
+{
+}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index adb824b8934..b3b3eafb6e7 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -129,6 +129,8 @@ void ED_spacetypes_init(void)
 
   ED_screen_user_menu_register();
 
+  ED_uilisttypes_ui();
+
   /* Gizmo types. */
   ED_gizmotypes_button_2d();
   ED_gizmotypes_dial_3d();
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 1a2c3acc9ae..0bd2f578222 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -654,7 +654,7 @@ static void uilist_filter_items(uiList *ui_list,
   RNA_parameter_list_free(&list);
 }
 
-static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
+static void rna_UIList_unregister(Main *bmain, StructRNA *type)
 {
   uiListType *ult = RNA_struct_blender_type_get(type);
 
@@ -665,7 +665,7 @@ static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
   RNA_struct_free_extension(type, &ult->rna_ext);
   RNA_struct_free(&BLENDER_RNA, type);
 
-  WM_uilisttype_freelink(ult);
+  WM_uilisttype_remove_ptr(bmain, ult);
 
   /* update while blender is running */
   WM_main_add_notifier(NC_WINDOW, NULL);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index c529fef73ef..66e91526009 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -618,7 +618,7 @@ void WM_operator_type_modal_from_exec_for_object_edit_coords(struct wmOperatorTy
 void WM_uilisttype_init(void);
 struct uiListType *WM_uilisttype_find(const char *idname, bool quiet);
 bool WM_uilisttype_add(struct uiListType *ult);
-void WM_uilisttype_freelink(struct uiListType *ult);
+void WM_uilisttype_remove_ptr(struct Main *bmain, struct uiListType *ult);
 void WM_uilisttype_free(void);
 
 void WM_uilisttype_to_full_list_id(const struct uiListType *ult,
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index fa087f5e226..d7ea47fc625 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -553,7 +553,6 @@ void WM_exit_ex(bContext *C, const bool do_python)
   wm_surfaces_free();
   wm_dropbox_free();
   WM_menutype_free();
-  WM_uilisttype_free();
 
   /* all non-screen and non-space stuff editors did, like editmode */
   if (C) {
@@ -609,6 +608,8 @@ void WM_exit_ex(bContext *C, const bool do_python)
   wm_gizmomaptypes_free();
   wm_gizmogrouptype_free();
   wm_gizmotype_free();
+  /* Same for UI-list types. */
+  WM_uilisttype_free();
 
   BLF_exit();
 
diff --git a/source/blender/windowmanager/intern/wm_uilist_type.c b/source/blender/windowmanager/intern/wm_uilist_type.c
index 6d298ee63f1..468ea7e4d5b 100644
--- a/source/blender/windowmanager/intern/wm_uilist_type.c
+++ b/source/blender/windowmanager/intern/wm_uilist_type.c
@@ -23,8 +23,10 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "BLI_listbase.h"
 #include "BLI_sys_types.h"
 
+#include "DNA_space_types.h"
 #include "DNA_windowmanager_types.h"
 
 #include "MEM_guardedalloc.h"
@@ -32,9 +34,11 @@
 #include "UI_interface.h"
 
 #include "BLI_ghash.h"
+#include "BLI_listbase.h"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_main.h"
 #include "BKE_screen.h"
 
 #include "WM_api.h"
@@ -64,8 +68,62 @@ bool WM_uilisttype_add(uiListType *ult)
   return 1;
 }
 
-void WM_uilisttype_freelink(uiListType *ult)
+static void wm_uilisttype_unlink_from_region(const uiListType *ult, ARegion *region)
 {
+  LISTBASE_FOREACH (uiList *, list, &region->ui_lists) {
+    if (list->type == ult) {
+      /* Don't delete the list, it's not just runtime data but stored in files. Freeing would make
+       * that data get lost. */
+      list->type = NULL;
+    }
+  }
+}
+
+static void wm_uilisttype_unlink_from_area(const uiListType *ult, ScrArea *area)
+{
+  LISTBASE_FOREACH (SpaceLink *, space_link, &area->spacedata) {
+    ListBase *regionbase = (space_link == area->spacedata.first) ? &area->regionbase :
+                                                                   &space_link->regionbase;
+    LISTBASE_FOREACH (ARegion *, region, regionbase) {
+      wm_uilisttype_unlink_from_region(ult, region);
+    }
+  }
+}
+
+/**
+ * For all lists representing \a ult, clear their `uiListType` pointer. Use when a list-type is
+ * deleted, so that the UI doesn't keep references to it.
+ *
+ * This is a common pattern for unregistering (usually .py defined) types at runtime, e.g. see
+ * #WM_gizmomaptype_group_unlink().
+ * Note that unlike in some other cases using this pattern, we don't actually free the lists with
+ * type \a ult, we just clear the reference to the type. That's because UI-Lists are written to
+ * files and we don't want them to get lost together with their (user visible) settings.
+ */
+static void wm_uilisttype_unlink(Main *bmain, const uiListType *ult)
+{
+  for (wmWindowManager *wm = bmain->wm.first; wm != NULL; wm = wm->id.next) {
+    LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+      LISTBASE_FOREACH (ScrArea *, global_area, &win->global_areas.areabase) {
+        wm_uilisttype_unlink_from_area(ult, global_area);
+      }
+    }
+  }
+
+  for (bScreen *screen = bmain->screens.first; screen != NULL; screen = screen->id.next) {
+    LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+      wm_uilisttype_unlink_from_area(ult, area);
+    }
+
+    LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
+      wm_uilisttype_unlink_from_region(ult, region);
+    }
+  }
+}
+
+void WM_uilisttype_remove_ptr(Main *bmain, uiListType *ult)
+{
+  wm_uilisttype_unlink(bmain, ult);
 
   bool ok = BLI_ghash_remove(uilisttypes_hash, ult->idname, NULL, MEM_freeN);



More information about the Bf-blender-cvs mailing list