Asset shelf: Better region height snapping behavior, "Show Names" changes size #112637
|
@ -234,6 +234,11 @@ typedef struct ARegionType {
|
||||||
/* return context data */
|
/* return context data */
|
||||||
bContextDataCallback context;
|
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.
|
/* 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.
|
* Used from user code such as view navigation/zoom operators to inform region about changes.
|
||||||
|
|
|
@ -1210,5 +1210,27 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FOREACH_NODETREE_END;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_free(struct ARegion *region);
|
||||||
void ED_asset_shelf_region_init(struct wmWindowManager *wm, 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);
|
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_listen(const struct wmRegionListenerParams *params);
|
||||||
void ED_asset_shelf_region_layout(const bContext *C, struct ARegion *region);
|
void ED_asset_shelf_region_layout(const bContext *C, struct ARegion *region);
|
||||||
void ED_asset_shelf_region_draw(const bContext *C, struct ARegion *region);
|
void ED_asset_shelf_region_draw(const bContext *C, struct ARegion *region);
|
||||||
|
|
|
@ -92,6 +92,7 @@ static AssetShelf *create_shelf_from_type(AssetShelfType &type)
|
||||||
*shelf = dna::shallow_zero_initialize();
|
*shelf = dna::shallow_zero_initialize();
|
||||||
shelf->settings.preview_size = shelf::DEFAULT_TILE_SIZE;
|
shelf->settings.preview_size = shelf::DEFAULT_TILE_SIZE;
|
||||||
shelf->type = &type;
|
shelf->type = &type;
|
||||||
|
shelf->preferred_row_count = 1;
|
||||||
STRNCPY(shelf->idname, type.idname);
|
STRNCPY(shelf->idname, type.idname);
|
||||||
return shelf;
|
return shelf;
|
||||||
}
|
}
|
||||||
|
@ -300,6 +301,35 @@ static int main_region_padding_x()
|
||||||
return main_region_padding_y();
|
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(®ion->v2d.cur) /
|
||||||
|
(BLI_rcti_size_y(®ion->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)
|
int ED_asset_shelf_region_snap(const ARegion *region, const int size, const int axis)
|
||||||
{
|
{
|
||||||
/* Only on Y 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;
|
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(
|
const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
|
||||||
*region);
|
*region);
|
||||||
const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
|
const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
|
||||||
|
|
||||||
/* Using scaled values only simplifies things. Simply divide the result by the scale again. */
|
BLI_assert(active_shelf->preferred_row_count > 0);
|
||||||
const int size_scaled = size * UI_SCALE_FAC;
|
|
||||||
|
|
||||||
const float aspect = BLI_rctf_size_y(®ion->v2d.cur) /
|
const int tile_height = current_tile_draw_height(region);
|
||||||
(BLI_rcti_size_y(®ion->v2d.mask) + 1);
|
const int new_size_y = calculate_scaled_region_height_from_row_count(
|
||||||
const float tile_height = (active_shelf ? ED_asset_shelf_tile_height(active_shelf->settings) :
|
active_shelf->preferred_row_count, tile_height) /
|
||||||
asset_shelf_default_tile_height()) /
|
UI_SCALE_FAC;
|
||||||
(IS_EQF(aspect, 0) ? 1.0f : aspect);
|
|
||||||
|
|
||||||
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). */
|
void ED_asset_shelf_region_on_user_resize(const ARegion *region)
|
||||||
const int rows = std::max(1, int((size_scaled - 2 * region_padding) / tile_height));
|
{
|
||||||
|
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);
|
const int tile_height = current_tile_draw_height(region);
|
||||||
return new_size_scaled / UI_SCALE_FAC;
|
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)
|
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();
|
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.
|
* 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(®ion->v2d, region->winx - 1, layout_height - padding_y);
|
UI_view2d_totRect_set(®ion->v2d, region->winx - 1, layout_height - padding_y);
|
||||||
UI_view2d_curRect_validate(®ion->v2d);
|
UI_view2d_curRect_validate(®ion->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);
|
UI_block_end(C, block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) /
|
const float aspect = BLI_rctf_size_x(&rmd->region->v2d.cur) /
|
||||||
(BLI_rcti_size_x(&rmd->region->v2d.mask) + 1);
|
(BLI_rcti_size_x(&rmd->region->v2d.mask) + 1);
|
||||||
const int snap_size_threshold = (U.widget_unit * 2) / aspect;
|
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)) {
|
if (ELEM(rmd->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) {
|
||||||
delta = event->xy[0] - rmd->orig_xy[0];
|
delta = event->xy[0] - rmd->orig_xy[0];
|
||||||
if (rmd->edge == AE_LEFT_TO_TOPRIGHT) {
|
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) {
|
if (rmd->region->flag & RGN_FLAG_NO_USER_RESIZE) {
|
||||||
rmd->region->sizex = rmd->origval;
|
rmd->region->sizex = rmd->origval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rmd->region->sizex != rmd->origval) {
|
||||||
|
size_changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
delta = event->xy[1] - rmd->orig_xy[1];
|
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) {
|
if (rmd->region->flag & RGN_FLAG_NO_USER_RESIZE) {
|
||||||
rmd->region->sizey = rmd->origval;
|
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);
|
ED_area_tag_redraw(rmd->area);
|
||||||
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, nullptr);
|
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, nullptr);
|
||||||
|
|
|
@ -2286,6 +2286,7 @@ void ED_spacetype_view3d()
|
||||||
art->listener = ED_asset_shelf_region_listen;
|
art->listener = ED_asset_shelf_region_listen;
|
||||||
art->poll = ED_asset_shelf_regions_poll;
|
art->poll = ED_asset_shelf_regions_poll;
|
||||||
art->snap_size = ED_asset_shelf_region_snap;
|
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->context = ED_asset_shelf_context;
|
||||||
art->init = view3d_asset_shelf_region_init;
|
art->init = view3d_asset_shelf_region_init;
|
||||||
art->layout = ED_asset_shelf_region_layout;
|
art->layout = ED_asset_shelf_region_layout;
|
||||||
|
|
|
@ -803,6 +803,9 @@ typedef struct AssetShelf {
|
||||||
struct AssetShelfType *type;
|
struct AssetShelfType *type;
|
||||||
|
|
||||||
AssetShelfSettings settings;
|
AssetShelfSettings settings;
|
||||||
|
|
||||||
|
short preferred_row_count;
|
||||||
|
char _pad[6];
|
||||||
} AssetShelf;
|
} AssetShelf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue