UI: Asset Shelf (Experimental Feature) #104831

Closed
Julian Eisel wants to merge 399 commits from asset-shelf into main

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

View File

@ -103,8 +103,16 @@ void ED_asset_shelf_region_listen(const wmRegionListenerParams *params)
void ED_asset_shelf_region_init(wmWindowManager *wm, ARegion *region)
{
ED_region_panels_init(wm, region);
region->v2d.scroll = V2D_SCROLL_RIGHT;
region->v2d.keepofs |= V2D_KEEPOFS_Y;
region->v2d.keeptot |= V2D_KEEPTOT_STRICT;
region->v2d.flag |= V2D_SNAP_TO_PAGESIZE_Y;
region->v2d.page_size_y = ED_asset_shelf_default_tile_height();
/* Ensure the view is snapped to a page still, especially for DPI changes. */
UI_view2d_offset_y_snap_to_closest_page(&region->v2d);
}
static int main_region_padding_y()
@ -182,17 +190,16 @@ void ED_asset_shelf_region_draw(const bContext *C,
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
const uiStyle *style = UI_style_get();
const uiStyle *style = UI_style_get_dpi();
const float padding_y = main_region_padding_y();
const float padding_x = main_region_padding_x();
const float scale_x = UI_view2d_scale_get_x(&region->v2d);
uiLayout *layout = UI_block_layout(block,
UI_LAYOUT_VERTICAL,
UI_LAYOUT_PANEL,
padding_x,
-padding_y,
(region->winx - 2 * padding_x) / scale_x,
1,
region->winx - 2 * padding_x,
0,
0,
style);
@ -200,7 +207,8 @@ void ED_asset_shelf_region_draw(const bContext *C,
int layout_height;
UI_block_layout_resolve(block, nullptr, &layout_height);
UI_view2d_totRect_set(&region->v2d, region->winx, layout_height);
BLI_assert(layout_height <= 0);
UI_view2d_totRect_set(&region->v2d, region->winx - 1, layout_height - padding_y);
UI_view2d_curRect_validate(&region->v2d);
UI_block_end(C, block);

View File

@ -414,6 +414,11 @@ void UI_view2d_center_set(struct View2D *v2d, float x, float y);
*/
void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac);
/**
* Scrolls the view so that the upper edge is at a multiple of the page size.
*/
void UI_view2d_offset_y_snap_to_closest_page(struct View2D *v2d);
/**
* Check if mouse is within scrollers
*

View File

@ -78,6 +78,11 @@ BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src)
dst->ymax = clamp_float_to_int(src->ymax);
}
float view2d_page_size_y(const View2D &v2d)
{
return v2d.page_size_y ? v2d.page_size_y : BLI_rcti_size_y(&v2d.mask);
}
/* XXX still unresolved: scrolls hide/unhide vs region mask handling */
/* XXX there's V2D_SCROLL_HORIZONTAL_HIDE and V2D_SCROLL_HORIZONTAL_FULLR ... */
@ -1957,6 +1962,17 @@ void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac)
UI_view2d_curRect_validate(v2d);
}
void UI_view2d_offset_y_snap_to_closest_page(struct View2D *v2d)
{
const float cur_size_y = BLI_rctf_size_y(&v2d->cur);
const float page_size_y = view2d_page_size_y(*v2d);
v2d->cur.ymax = roundf(v2d->cur.ymax / page_size_y) * page_size_y;
v2d->cur.ymin = v2d->cur.ymax - cur_size_y;
UI_view2d_curRect_validate(v2d);
}
char UI_view2d_mouse_in_scrollers_ex(const ARegion *region,
const View2D *v2d,
const int xy[2],

View File

@ -33,3 +33,9 @@ void view2d_scrollers_calc(View2D *v2d, const rcti *mask_custom, View2DScrollers
void view2d_totRect_set_resize(View2D *v2d, int width, int height, bool resize);
bool view2d_edge_pan_poll(bContext *C);
/**
* For paginated scrolling, get the page height to scroll. This may be a custom height
* (#View2D.page_size_y) but defaults to the #View2D.mask height.
*/
float view2d_page_size_y(const View2D &v2d);

View File

@ -45,6 +45,25 @@ static bool view2d_poll(bContext *C)
return (region != nullptr) && (region->v2d.flag & V2D_IS_INIT);
}
/**
* Calculate a scrolling delta that is the closest to a multiple of the page size (as returned by
* #view2d_page_size_y). So when scrolling for more than half a page size, a delta to the next page
* is returned. No scrolling change should be applied when this returns 0.
*/
static float view2d_scroll_delta_y_snap_page_size(const View2D &v2d, const float delta_y)
{
const float page_size = view2d_page_size_y(v2d);
const int delta_pages = int((delta_y - page_size * 0.5f) / page_size);
/* Apply no change, don't update last coordinates. */
if (abs(delta_pages) < 1) {
return 0.0f;
}
/* Snap the delta to a multiple of a page size. */
return delta_pages * page_size;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -259,18 +278,32 @@ static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewPanData *vpd = static_cast<v2dViewPanData *>(op->customdata);
View2D *v2d = vpd->v2d;
/* execute the events */
switch (event->type) {
case MOUSEMOVE: {
/* calculate new delta transform, then store mouse-coordinates for next-time */
RNA_int_set(op->ptr, "deltax", (vpd->lastx - event->xy[0]));
RNA_int_set(op->ptr, "deltay", (vpd->lasty - event->xy[1]));
int deltax = vpd->lastx - event->xy[0];
int deltay = vpd->lasty - event->xy[1];
vpd->lastx = event->xy[0];
vpd->lasty = event->xy[1];
/* Page snapping: When panning for more than half a page size, snap to the next page. */
if (v2d->flag & V2D_SNAP_TO_PAGESIZE_Y) {
deltay = view2d_scroll_delta_y_snap_page_size(*v2d, deltay);
}
view_pan_apply(C, op);
if (deltax != 0) {
RNA_int_set(op->ptr, "deltax", deltax);
vpd->lastx = event->xy[0];
}
if (deltay != 0) {
RNA_int_set(op->ptr, "deltay", deltay);
vpd->lasty = event->xy[1];
}
if (deltax || deltay) {
view_pan_apply(C, op);
}
break;
}
/* XXX: Mode switching isn't implemented. See comments in 36818.
@ -505,11 +538,13 @@ static int view_scrolldown_exec(bContext *C, wmOperator *op)
RNA_int_set(op->ptr, "deltay", -40);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
if (RNA_property_is_set(op->ptr, prop) && RNA_property_boolean_get(op->ptr, prop)) {
const bool use_page_size = (vpd->v2d->flag & V2D_SNAP_TO_PAGESIZE_Y) ||
(RNA_property_is_set(op->ptr, prop) &&
RNA_property_boolean_get(op->ptr, prop));
if (use_page_size) {
const ARegion *region = CTX_wm_region(C);
const int page_size = vpd->v2d->page_size_y ? -region->v2d.page_size_y :
region->v2d.mask.ymin - region->v2d.mask.ymax;
RNA_int_set(op->ptr, "deltay", page_size);
const int page_size = view2d_page_size_y(region->v2d);
RNA_int_set(op->ptr, "deltay", -page_size);
}
/* apply movement, then we're done */
@ -558,10 +593,12 @@ static int view_scrollup_exec(bContext *C, wmOperator *op)
RNA_int_set(op->ptr, "deltay", 40);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
if (RNA_property_is_set(op->ptr, prop) && RNA_property_boolean_get(op->ptr, prop)) {
const bool use_page_size = (vpd->v2d->flag & V2D_SNAP_TO_PAGESIZE_Y) ||
(RNA_property_is_set(op->ptr, prop) &&
RNA_property_boolean_get(op->ptr, prop));
if (use_page_size) {
const ARegion *region = CTX_wm_region(C);
const int page_size = vpd->v2d->page_size_y ? region->v2d.page_size_y :
BLI_rcti_size_y(&region->v2d.mask);
const int page_size = view2d_page_size_y(region->v2d);
RNA_int_set(op->ptr, "deltay", page_size);
}
@ -2003,21 +2040,24 @@ static void scroller_activate_apply(bContext *C, wmOperator *op)
static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dScrollerMove *vsm = static_cast<v2dScrollerMove *>(op->customdata);
const bool use_page_size_y = vsm->v2d->flag & V2D_SNAP_TO_PAGESIZE_Y;
/* execute the events */
switch (event->type) {
case MOUSEMOVE: {
float delta = 0.0f;
/* calculate new delta transform, then store mouse-coordinates for next-time */
if (ELEM(vsm->zone, SCROLLHANDLE_BAR, SCROLLHANDLE_MAX)) {
/* if using bar (i.e. 'panning') or 'max' zoom widget */
switch (vsm->scroller) {
case 'h': /* horizontal scroller - so only horizontal movement
* ('cur' moves opposite to mouse) */
vsm->delta = float(event->xy[0] - vsm->lastx);
delta = float(event->xy[0] - vsm->lastx);
break;
case 'v': /* vertical scroller - so only vertical movement
* ('cur' moves opposite to mouse) */
vsm->delta = float(event->xy[1] - vsm->lasty);
delta = float(event->xy[1] - vsm->lasty);
break;
}
}
@ -2026,15 +2066,25 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *e
switch (vsm->scroller) {
case 'h': /* horizontal scroller - so only horizontal movement
* ('cur' moves with mouse) */
vsm->delta = float(vsm->lastx - event->xy[0]);
delta = float(vsm->lastx - event->xy[0]);
break;
case 'v': /* vertical scroller - so only vertical movement
* ('cur' moves with to mouse) */
vsm->delta = float(vsm->lasty - event->xy[1]);
delta = float(vsm->lasty - event->xy[1]);
break;
}
}
/* Page snapping: When panning for more than half a page size, snap to the next page. */
if (use_page_size_y && (vsm->scroller == 'v')) {
delta = view2d_scroll_delta_y_snap_page_size(*vsm->v2d, delta * vsm->fac) / vsm->fac;
}
if (IS_EQF(delta, 0.0f)) {
break;
}
vsm->delta = delta;
/* store previous coordinates */
vsm->lastx = event->xy[0];
vsm->lasty = event->xy[1];

View File

@ -124,6 +124,9 @@ enum {
V2D_IS_NAVIGATING = (1 << 9),
/* view settings need to be set still... */
V2D_IS_INIT = (1 << 10),
/* Ensure scrolling always snaps to multiples of #View2D.page_size_y or the #View2D.mask height
* if this is 0. Zooming doesn't respect this. */
V2D_SNAP_TO_PAGESIZE_Y = (1 << 11),
};
/** Scroller flags for View2D (#View2D.scroll). */