Asset Shelf: Add region poll mechanism for initialization
Allows running some action when the context changes to make the asset shelf region visible. Also add an option for when whether the shelf should be visible by default when the poll succeeds. Pull Request: https://projects.blender.org/blender/blender/pulls/121315
This commit is contained in:
committed by
Hans Goudey
parent
471378c666
commit
d4fc167db1
@@ -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},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user