Asset Shelf: Add region poll mechanism for initialization #121315
@ -233,6 +233,12 @@ struct ARegionType {
|
||||
/* return context data */
|
||||
bContextDataCallback context;
|
||||
|
||||
/**
|
||||
* Called on every frame in which the region's poll succeeds, regardless of visibility, before
|
||||
* drawing, visibility evaluation and initialization. Allows the region to override visibility.
|
||||
*/
|
||||
void (*on_poll_success)(const bContext *C, ARegion *region);
|
||||
|
||||
/**
|
||||
* Called whenever the user changes the region's size. Not called when the size is changed
|
||||
* through other means, like to adjust for a scaled down window.
|
||||
@ -516,6 +522,7 @@ enum AssetShelfTypeFlag {
|
||||
/** Do not trigger asset dragging on drag events. Drag events can be overridden with custom
|
||||
* keymap items then. */
|
||||
ASSET_SHELF_TYPE_FLAG_NO_ASSET_DRAG = (1 << 0),
|
||||
ASSET_SHELF_TYPE_FLAG_DEFAULT_VISIBLE = (1 << 1),
|
||||
|
||||
ASSET_SHELF_TYPE_FLAG_MAX
|
||||
};
|
||||
|
@ -47,6 +47,7 @@ void region_on_user_resize(const ARegion *region);
|
||||
void region_listen(const wmRegionListenerParams *params);
|
||||
void region_layout(const bContext *C, ARegion *region);
|
||||
void region_draw(const bContext *C, ARegion *region);
|
||||
void region_on_poll_success(const bContext *C, ARegion *region);
|
||||
void region_blend_read_data(BlendDataReader *reader, ARegion *region);
|
||||
void region_blend_write(BlendWriter *writer, ARegion *region);
|
||||
int region_prefsizey();
|
||||
|
@ -131,12 +131,15 @@ static void activate_shelf(RegionAssetShelf &shelf_regiondata, AssetShelf &shelf
|
||||
*
|
||||
* The returned shelf is guaranteed to have its #AssetShelf.type pointer set.
|
||||
*
|
||||
* \param on_create: Function called when a new asset shelf is created (case 3).
|
||||
*
|
||||
* \return A non-owning pointer to the now active shelf. Might be null if no shelf is valid in
|
||||
* current context (all polls failed).
|
||||
*/
|
||||
static AssetShelf *update_active_shelf(const bContext &C,
|
||||
const SpaceType &space_type,
|
||||
RegionAssetShelf &shelf_regiondata)
|
||||
RegionAssetShelf &shelf_regiondata,
|
||||
FunctionRef<void(AssetShelf &new_shelf)> on_create)
|
||||
{
|
||||
/* Note: Don't access #AssetShelf.type directly, use #type_ensure(). */
|
||||
|
||||
@ -170,6 +173,9 @@ static AssetShelf *update_active_shelf(const bContext &C,
|
||||
BLI_addhead(&shelf_regiondata.shelves, new_shelf);
|
||||
/* Moves ownership to the regiondata. */
|
||||
activate_shelf(shelf_regiondata, *new_shelf);
|
||||
if (on_create) {
|
||||
on_create(*new_shelf);
|
||||
}
|
||||
return new_shelf;
|
||||
}
|
||||
}
|
||||
@ -260,13 +266,13 @@ void region_listen(const wmRegionListenerParams *params)
|
||||
|
||||
void region_init(wmWindowManager *wm, ARegion *region)
|
||||
{
|
||||
if (!region->regiondata) {
|
||||
region->regiondata = MEM_cnew<RegionAssetShelf>("RegionAssetShelf");
|
||||
}
|
||||
RegionAssetShelf &shelf_regiondata = *RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
/* Region-data should've been created by a previously called #region_before_redraw(). */
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
BLI_assert_msg(
|
||||
shelf_regiondata,
|
||||
"Region-data should've been created by a previously called `region_before_redraw()`.");
|
||||
|
||||
/* Active shelf is only set on draw, so this may be null! */
|
||||
AssetShelf *active_shelf = shelf_regiondata.active_shelf;
|
||||
AssetShelf *active_shelf = shelf_regiondata->active_shelf;
|
||||
|
||||
UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_PANELS_UI, region->winx, region->winy);
|
||||
|
||||
@ -410,17 +416,12 @@ int region_prefsizey()
|
||||
|
||||
void region_layout(const bContext *C, ARegion *region)
|
||||
{
|
||||
const SpaceLink *space = CTX_wm_space_data(C);
|
||||
SpaceType *space_type = BKE_spacetype_from_id(space->spacetype);
|
||||
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
if (!shelf_regiondata) {
|
||||
/* Region-data should've been created by a previously called #region_init(). */
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
BLI_assert_msg(
|
||||
shelf_regiondata,
|
||||
"Region-data should've been created by a previously called `region_before_redraw()`.");
|
||||
|
||||
AssetShelf *active_shelf = update_active_shelf(*C, *space_type, *shelf_regiondata);
|
||||
const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
|
||||
if (!active_shelf) {
|
||||
return;
|
||||
}
|
||||
@ -472,6 +473,28 @@ void region_draw(const bContext *C, ARegion *region)
|
||||
UI_view2d_scrollers_draw(®ion->v2d, nullptr);
|
||||
}
|
||||
|
||||
void region_on_poll_success(const bContext *C, ARegion *region)
|
||||
{
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::ensure_from_asset_shelf_region(*region);
|
||||
if (!shelf_regiondata) {
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
update_active_shelf(
|
||||
*C, *area->type, *shelf_regiondata, /*on_create=*/[&](AssetShelf &new_shelf) {
|
||||
/* Update region visibility (`'DEFAULT_VISIBLE'` option). */
|
||||
const int old_flag = region->flag;
|
||||
SET_FLAG_FROM_TEST(region->flag,
|
||||
(new_shelf.type->flag & ASSET_SHELF_TYPE_FLAG_DEFAULT_VISIBLE) == 0,
|
||||
RGN_FLAG_HIDDEN);
|
||||
if (old_flag != region->flag) {
|
||||
ED_region_visibility_change_update(const_cast<bContext *>(C), area, region);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void header_region_listen(const wmRegionListenerParams *params)
|
||||
{
|
||||
asset_shelf_region_listen(params);
|
||||
@ -486,15 +509,6 @@ void header_region_init(wmWindowManager * /*wm*/, ARegion *region)
|
||||
|
||||
void header_region(const bContext *C, ARegion *region)
|
||||
{
|
||||
const SpaceLink *space = CTX_wm_space_data(C);
|
||||
SpaceType *space_type = BKE_spacetype_from_id(space->spacetype);
|
||||
const ARegion *main_shelf_region = BKE_area_find_region_type(CTX_wm_area(C),
|
||||
RGN_TYPE_ASSET_SHELF);
|
||||
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
|
||||
*main_shelf_region);
|
||||
update_active_shelf(*C, *space_type, *shelf_regiondata);
|
||||
|
||||
ED_region_header_with_button_sections(C, region, uiButtonSectionsAlign::Bottom);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,19 @@ RegionAssetShelf *RegionAssetShelf::get_from_asset_shelf_region(const ARegion &r
|
||||
return static_cast<RegionAssetShelf *>(region.regiondata);
|
||||
}
|
||||
|
||||
RegionAssetShelf *RegionAssetShelf::ensure_from_asset_shelf_region(ARegion ®ion)
|
||||
{
|
||||
if (region.regiontype != RGN_TYPE_ASSET_SHELF) {
|
||||
/* Should only be called on main asset shelf region. */
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
if (!region.regiondata) {
|
||||
region.regiondata = MEM_cnew<RegionAssetShelf>("RegionAssetShelf");
|
||||
}
|
||||
return static_cast<RegionAssetShelf *>(region.regiondata);
|
||||
}
|
||||
|
||||
namespace blender::ed::asset::shelf {
|
||||
|
||||
RegionAssetShelf *regiondata_duplicate(const RegionAssetShelf *shelf_regiondata)
|
||||
|
@ -2021,6 +2021,9 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
|
||||
area_azone_init(win, screen, area);
|
||||
|
||||
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
|
||||
if (region->flag & RGN_FLAG_POLL_FAILED) {
|
||||
continue;
|
||||
}
|
||||
region_evaulate_visibility(region);
|
||||
|
||||
/* region size may have changed, init does necessary adjustments */
|
||||
|
@ -755,6 +755,9 @@ static void screen_regions_poll(bContext *C, const wmWindow *win, bScreen *scree
|
||||
if (region_poll(C, screen, area, region) == false) {
|
||||
region->flag |= RGN_FLAG_POLL_FAILED;
|
||||
}
|
||||
else if (region->type && region->type->on_poll_success) {
|
||||
region->type->on_poll_success(C, region);
|
||||
}
|
||||
|
||||
if (old_region_flag != region->flag) {
|
||||
any_changed = true;
|
||||
|
@ -1200,6 +1200,7 @@ void ED_spacetype_image()
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_ASSET_SHELF | ED_KEYMAP_FRAMES;
|
||||
art->duplicate = asset::shelf::region_duplicate;
|
||||
art->free = asset::shelf::region_free;
|
||||
art->on_poll_success = asset::shelf::region_on_poll_success;
|
||||
art->listener = asset::shelf::region_listen;
|
||||
art->poll = asset::shelf::regions_poll;
|
||||
art->snap_size = asset::shelf::region_snap;
|
||||
|
@ -2209,6 +2209,7 @@ void ED_spacetype_view3d()
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_ASSET_SHELF | ED_KEYMAP_FRAMES;
|
||||
art->duplicate = asset::shelf::region_duplicate;
|
||||
art->free = asset::shelf::region_free;
|
||||
art->on_poll_success = asset::shelf::region_on_poll_success;
|
||||
art->listener = asset::shelf::region_listen;
|
||||
art->poll = asset::shelf::regions_poll;
|
||||
art->snap_size = asset::shelf::region_snap;
|
||||
|
@ -855,6 +855,8 @@ typedef struct RegionAssetShelf {
|
||||
AssetShelf *active_shelf; /* Non-owning. */
|
||||
#ifdef __cplusplus
|
||||
static RegionAssetShelf *get_from_asset_shelf_region(const ARegion ®ion);
|
||||
/** Creates the asset shelf region data if necessary, and returns it. */
|
||||
static RegionAssetShelf *ensure_from_asset_shelf_region(ARegion ®ion);
|
||||
#endif
|
||||
} RegionAssetShelf;
|
||||
|
||||
|
@ -2261,6 +2261,12 @@ static void rna_def_asset_shelf(BlenderRNA *brna)
|
||||
"No Asset Dragging",
|
||||
"Disable the default asset dragging on drag events. Useful for implementing custom "
|
||||
"dragging via custom key-map items"},
|
||||
{ASSET_SHELF_TYPE_FLAG_DEFAULT_VISIBLE,
|
||||
"DEFAULT_VISIBLE",
|
||||
0,
|
||||
"Visible by Default",
|
||||
"Unhide the asset shelf when it's available for the first time, otherwise it will be "
|
||||
"hidden"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user