UI: Allow popover panels to register own notifier listeners

This is necessary to let popovers redraw when asynchronously loading
data. For example to display assets or asset catalogs as they get
loaded. Needed for the asset shelf catalog selector popover. Menus
already do the same to allow populating the menu with assets as they get
loaded.
This commit is contained in:
Julian Eisel 2023-09-26 18:37:28 +02:00
parent c8cc169d6f
commit e3d4cf9b3d
4 changed files with 23 additions and 4 deletions

View File

@ -293,6 +293,11 @@ struct PanelType {
void (*draw_header_preset)(const bContext *C, Panel *panel);
/* draw entirely, view changes should be handled here */
void (*draw)(const bContext *C, Panel *panel);
/**
* Listener to redraw the region this is contained in on changes. Only used for panels displayed
* in popover regions.
*/
void (*listener)(const wmRegionListenerParams *params);
/* For instanced panels corresponding to a list: */

View File

@ -3682,6 +3682,15 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eU
return block;
}
void ui_block_add_dynamic_listener(uiBlock *block,
void (*listener_func)(const wmRegionListenerParams *params))
{
uiBlockDynamicListener *listener = static_cast<uiBlockDynamicListener *>(
MEM_mallocN(sizeof(*listener), __func__));
listener->listener_func = listener_func;
BLI_addtail(&block->dynamic_listeners, listener);
}
eUIEmbossType UI_block_emboss_get(uiBlock *block)
{
return block->emboss;

View File

@ -664,6 +664,10 @@ void ui_region_to_window(const ARegion *region, int *x, int *y);
*/
void ui_region_winrct_get_no_margin(const ARegion *region, rcti *r_rect);
/** Register a listener callback to this block to tag the area/region for redraw. */
void ui_block_add_dynamic_listener(uiBlock *block,
void (*listener_func)(const wmRegionListenerParams *params));
/**
* Reallocate the button (new address is returned) for a new button type.
* This should generally be avoided and instead the correct type be created right away.

View File

@ -5928,10 +5928,7 @@ void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout)
}
if (mt->listener) {
/* Forward the menu type listener to the block we're drawing in. */
uiBlockDynamicListener *listener = static_cast<uiBlockDynamicListener *>(
MEM_mallocN(sizeof(*listener), __func__));
listener->listener_func = mt->listener;
BLI_addtail(&block->dynamic_listeners, listener);
ui_block_add_dynamic_listener(block, mt->listener);
}
if (layout->context) {
@ -5973,6 +5970,10 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout,
panel->type = pt;
panel->flag = PNL_POPOVER;
if (pt->listener) {
ui_block_add_dynamic_listener(uiLayoutGetBlock(layout), pt->listener);
}
uiLayout *last_item = static_cast<uiLayout *>(layout->items.last);
/* Draw main panel. */