diff options
author | Julian Eisel <julian@blender.org> | 2021-07-13 18:42:25 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2021-07-15 17:12:36 +0300 |
commit | 26b098c04fbeb7f4d7c320b6c2066d2b448ae136 (patch) | |
tree | 22c7adddd6b60b583085ff429fdb29c53d1b21f7 /source/blender/windowmanager/intern/wm_uilist_type.c | |
parent | bc4f99aa86809d564905a8e55786e04aa5bd16b4 (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/intern/wm_uilist_type.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_uilist_type.c | 60 |
1 files changed, 59 insertions, 1 deletions
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, ®ion->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); |