UI: Asset Shelf (Experimental Feature) #104831
|
@ -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(®ion->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(®ion->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(®ion->v2d, region->winx, layout_height);
|
||||
BLI_assert(layout_height <= 0);
|
||||
UI_view2d_totRect_set(®ion->v2d, region->winx - 1, layout_height - padding_y);
|
||||
UI_view2d_curRect_validate(®ion->v2d);
|
||||
|
||||
UI_block_end(C, block);
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(®ion->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];
|
||||
|
|
|
@ -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). */
|
||||
|
|
Loading…
Reference in New Issue