Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2021-07-13 18:42:25 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-07-15 17:12:36 +0300
commit26b098c04fbeb7f4d7c320b6c2066d2b448ae136 (patch)
tree22c7adddd6b60b583085ff429fdb29c53d1b21f7 /source/blender/windowmanager
parentbc4f99aa86809d564905a8e55786e04aa5bd16b4 (diff)
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.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c3
-rw-r--r--source/blender/windowmanager/intern/wm_uilist_type.c60
3 files changed, 62 insertions, 3 deletions
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);