WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 351 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
8 changed files with 67 additions and 26 deletions
Showing only changes of commit b5d44d8f5d - Show all commits

View File

@ -8814,7 +8814,7 @@ class VIEW3D_PT_viewport_debug(Panel):
class BrushAssetShelf:
bl_space_type = "VIEW_3D"
bl_options = {'NO_ASSET_DRAG'}
bl_options = {'DEFAULT_VISIBLE', 'NO_ASSET_DRAG'}
bl_activate_operator = "BRUSH_OT_asset_select"
bl_default_preview_size = 40

View File

@ -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
};

View File

@ -45,6 +45,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(void);

View File

@ -13,6 +13,7 @@
#include "AS_asset_catalog_path.hh"
#include "AS_asset_library.hh"
#include "BLI_function_ref.hh"
#include "BLI_string.h"
#include "BKE_context.hh"
@ -134,12 +135,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,
SpaceType &space_type,
RegionAssetShelf &shelf_regiondata)
RegionAssetShelf &shelf_regiondata,
FunctionRef<void(AssetShelf &new_shelf)> on_create)
{
/* Note: Don't access #AssetShelf.type directly, use #asset_shelf_type_ensure(). */
@ -174,6 +178,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;
}
}
@ -267,13 +274,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(&region->v2d, V2D_COMMONVIEW_PANELS_UI, region->winx, region->winy);
@ -417,17 +424,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;
}
@ -479,6 +481,33 @@ void region_draw(const bContext *C, ARegion *region)
UI_view2d_scrollers_draw(&region->v2d, nullptr);
}
void region_on_poll_success(const bContext *C, ARegion *region)
{
ScrArea *area = CTX_wm_area(C);
BLI_assert(region->regiontype == RGN_TYPE_ASSET_SHELF);
if (!region->regiondata) {
region->regiondata = MEM_cnew<RegionAssetShelf>("RegionAssetShelf");
}
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
if (!shelf_regiondata) {
BLI_assert_unreachable();
return;
}
update_active_shelf(*C, *area->type, *shelf_regiondata, [&](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);
@ -493,15 +522,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);
}

View File

@ -2019,6 +2019,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 */

View File

@ -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;

View File

@ -2196,6 +2196,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;

View File

@ -2303,6 +2303,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},
};