Asset shelf: Better region height snapping behavior, "Show Names" changes size #112637

Merged
Julian Eisel merged 4 commits from JulianEisel/blender:temp-asset-shelf-region-resize into main 2023-09-21 15:08:34 +02:00
7 changed files with 113 additions and 32 deletions

View File

@ -234,6 +234,11 @@ typedef struct ARegionType {
/* return context data */
bContextDataCallback context;
/**
* 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.
*/
void (*on_user_resize)(const struct ARegion *region);
/* Is called whenever the current visible View2D's region changes.
*
* Used from user code such as view navigation/zoom operators to inform region about changes.

View File

@ -1210,5 +1210,27 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
FOREACH_NODETREE_END;
{
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
const ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
&sl->regionbase;
LISTBASE_FOREACH (ARegion *, region, regionbase) {
if (region->regiontype != RGN_TYPE_ASSET_SHELF) {
continue;
}
RegionAssetShelf *shelf_data = static_cast<RegionAssetShelf *>(region->regiondata);
if (shelf_data && shelf_data->active_shelf &&
(shelf_data->active_shelf->preferred_row_count == 0)) {
shelf_data->active_shelf->preferred_row_count = 1;
}
}
}
}
}
}
}
}

View File

@ -43,6 +43,7 @@ void *ED_asset_shelf_region_duplicate(void *regiondata);
void ED_asset_shelf_region_free(struct ARegion *region);
void ED_asset_shelf_region_init(struct wmWindowManager *wm, struct ARegion *region);
int ED_asset_shelf_region_snap(const struct ARegion *region, int size, int axis);
void ED_asset_shelf_region_on_user_resize(const struct ARegion *region);
void ED_asset_shelf_region_listen(const struct wmRegionListenerParams *params);
void ED_asset_shelf_region_layout(const bContext *C, struct ARegion *region);
void ED_asset_shelf_region_draw(const bContext *C, struct ARegion *region);

View File

@ -92,6 +92,7 @@ static AssetShelf *create_shelf_from_type(AssetShelfType &type)
*shelf = dna::shallow_zero_initialize();
shelf->settings.preview_size = shelf::DEFAULT_TILE_SIZE;
shelf->type = &type;
shelf->preferred_row_count = 1;
STRNCPY(shelf->idname, type.idname);
return shelf;
}
@ -300,6 +301,35 @@ static int main_region_padding_x()
return main_region_padding_y();
}
static int current_tile_draw_height(const ARegion *region)
{
const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
*region);
const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
const float aspect = BLI_rctf_size_y(&region->v2d.cur) /
(BLI_rcti_size_y(&region->v2d.mask) + 1);
return (active_shelf ? ED_asset_shelf_tile_height(active_shelf->settings) :
asset_shelf_default_tile_height()) /
(IS_EQF(aspect, 0) ? 1.0f : aspect);
}
/**
* How many rows fit into the region (accounting for padding).
*/
static int calculate_row_count_from_tile_draw_height(const int region_height_scaled,
const int tile_draw_height)
{
return std::max(1, int((region_height_scaled - 2 * main_region_padding_y()) / tile_draw_height));
}
static int calculate_scaled_region_height_from_row_count(const int row_count,
const int tile_draw_height)
{
return (row_count * tile_draw_height + 2 * main_region_padding_y());
}
int ED_asset_shelf_region_snap(const ARegion *region, const int size, const int axis)
{
/* Only on Y axis. */
@ -307,26 +337,51 @@ int ED_asset_shelf_region_snap(const ARegion *region, const int size, const int
return size;
}
/* Using scaled values only simplifies things. Simply divide the result by the scale again. */
const int tile_height = current_tile_draw_height(region);
const int row_count = calculate_row_count_from_tile_draw_height(size * UI_SCALE_FAC,
tile_height);
const int new_size_scaled = calculate_scaled_region_height_from_row_count(row_count,
tile_height);
return new_size_scaled / UI_SCALE_FAC;
}
/**
* Ensure the region height matches the preferred row count (see #AssetShelf.preferred_row_count).
* In any case, this will ensure the region height is snapped to a multiple of the row count (plus
* region padding).
*/
static void region_resize_to_preferred(ScrArea *area, ARegion *region)
{
const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
*region);
const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
/* Using scaled values only simplifies things. Simply divide the result by the scale again. */
const int size_scaled = size * UI_SCALE_FAC;
BLI_assert(active_shelf->preferred_row_count > 0);
const float aspect = BLI_rctf_size_y(&region->v2d.cur) /
(BLI_rcti_size_y(&region->v2d.mask) + 1);
const float tile_height = (active_shelf ? ED_asset_shelf_tile_height(active_shelf->settings) :
asset_shelf_default_tile_height()) /
(IS_EQF(aspect, 0) ? 1.0f : aspect);
const int tile_height = current_tile_draw_height(region);
const int new_size_y = calculate_scaled_region_height_from_row_count(
active_shelf->preferred_row_count, tile_height) /
UI_SCALE_FAC;
const int region_padding = main_region_padding_y();
if (region->sizey != new_size_y) {
region->sizey = new_size_y;
ED_area_tag_region_size_update(area, region);
}
}
/* How many rows fit into the region (accounting for padding). */
const int rows = std::max(1, int((size_scaled - 2 * region_padding) / tile_height));
void ED_asset_shelf_region_on_user_resize(const ARegion *region)
{
const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
*region);
AssetShelf *active_shelf = shelf_regiondata->active_shelf;
const int new_size_scaled = (rows * tile_height + 2 * region_padding);
return new_size_scaled / UI_SCALE_FAC;
const int tile_height = current_tile_draw_height(region);
active_shelf->preferred_row_count = calculate_row_count_from_tile_draw_height(
region->sizey * UI_SCALE_FAC, tile_height);
}
int ED_asset_shelf_tile_width(const AssetShelfSettings &settings)
@ -352,25 +407,6 @@ int ED_asset_shelf_region_prefsizey()
return asset_shelf_default_tile_height() + 2 * main_region_padding_y();
}
/**
* Ensure the region height is snapped to the closest multiple of the row height.
*/
static void asset_shelf_region_snap_height_to_closest(ScrArea *area,
ARegion *region,
const AssetShelf &shelf)
{
const int tile_height = ED_asset_shelf_tile_height(shelf.settings);
/* Increase the size by half a row, the snapping below shrinks it to a multiple of the row (plus
* paddings), effectively rounding it. */
const int ceiled_size_y = region->sizey + ((tile_height / UI_SCALE_FAC) * 0.5);
const int new_size_y = ED_asset_shelf_region_snap(region, ceiled_size_y, 1);
if (region->sizey != new_size_y) {
region->sizey = new_size_y;
ED_area_tag_region_size_update(area, region);
}
}
/**
* The asset shelf always uses the "All" library for now.
*/
@ -424,7 +460,7 @@ void ED_asset_shelf_region_layout(const bContext *C, ARegion *region)
UI_view2d_totRect_set(&region->v2d, region->winx - 1, layout_height - padding_y);
UI_view2d_curRect_validate(&region->v2d);
asset_shelf_region_snap_height_to_closest(CTX_wm_area(C), region, *active_shelf);
region_resize_to_preferred(CTX_wm_area(C), region);
UI_block_end(C, block);
}

View File

@ -2851,6 +2851,8 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
const float aspect = BLI_rctf_size_x(&rmd->region->v2d.cur) /
(BLI_rcti_size_x(&rmd->region->v2d.mask) + 1);
const int snap_size_threshold = (U.widget_unit * 2) / aspect;
bool size_changed = false;
if (ELEM(rmd->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) {
delta = event->xy[0] - rmd->orig_xy[0];
if (rmd->edge == AE_LEFT_TO_TOPRIGHT) {
@ -2891,6 +2893,10 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (rmd->region->flag & RGN_FLAG_NO_USER_RESIZE) {
rmd->region->sizex = rmd->origval;
}
if (rmd->region->sizex != rmd->origval) {
size_changed = true;
}
}
else {
delta = event->xy[1] - rmd->orig_xy[1];
@ -2935,6 +2941,13 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (rmd->region->flag & RGN_FLAG_NO_USER_RESIZE) {
rmd->region->sizey = rmd->origval;
}
if (rmd->region->sizey != rmd->origval) {
size_changed = true;
}
}
if (size_changed && rmd->region->type->on_user_resize) {
rmd->region->type->on_user_resize(rmd->region);
}
ED_area_tag_redraw(rmd->area);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, nullptr);

View File

@ -2286,6 +2286,7 @@ void ED_spacetype_view3d()
art->listener = ED_asset_shelf_region_listen;
art->poll = ED_asset_shelf_regions_poll;
art->snap_size = ED_asset_shelf_region_snap;
art->on_user_resize = ED_asset_shelf_region_on_user_resize;
art->context = ED_asset_shelf_context;
art->init = view3d_asset_shelf_region_init;
art->layout = ED_asset_shelf_region_layout;

View File

@ -803,6 +803,9 @@ typedef struct AssetShelf {
struct AssetShelfType *type;
AssetShelfSettings settings;
short preferred_row_count;
char _pad[6];
} AssetShelf;
/**