UI: toolbar single column size snapping
Once a region is set to it's snapped size, zooming keeps the size.
This commit is contained in:
parent
e0c088f8fb
commit
6a0264896b
Notes:
blender-bot
2023-02-14 09:48:23 +01:00
Referenced by issue #54808, UI: Basic toolbar improvements (done)
|
@ -140,6 +140,8 @@ typedef struct ARegionType {
|
|||
void (*exit)(struct wmWindowManager *, struct ARegion *);
|
||||
/* draw entirely, view changes should be handled here */
|
||||
void (*draw)(const struct bContext *, struct ARegion *);
|
||||
/* snap the size of the region (can be NULL for no snapping). */
|
||||
int (*snap_size)(const struct ARegion *ar, int size, int axis);
|
||||
/* contextual changes should be handled here */
|
||||
void (*listener)(struct bScreen *, struct ScrArea *, struct ARegion *,
|
||||
struct wmNotifier *, const struct Scene *scene);
|
||||
|
|
|
@ -91,6 +91,9 @@ void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
|
|||
float ED_region_blend_factor(struct ARegion *ar);
|
||||
void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
|
||||
|
||||
int ED_region_snap_size_test(const struct ARegion *ar);
|
||||
bool ED_region_snap_size_apply(struct ARegion *ar, int snap_flag);
|
||||
|
||||
/* message_bus callbacks */
|
||||
void ED_region_do_msg_notify_tag_redraw(
|
||||
struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val);
|
||||
|
|
|
@ -641,6 +641,7 @@ static void view_zoomstep_apply_ex(
|
|||
View2D *v2d = &ar->v2d;
|
||||
const rctf cur_old = v2d->cur;
|
||||
float dx, dy;
|
||||
const int snap_test = ED_region_snap_size_test(ar);
|
||||
|
||||
/* calculate amount to move view by, ensuring symmetry so the
|
||||
* old zoom level is restored after zooming back the same amount
|
||||
|
@ -725,6 +726,12 @@ static void view_zoomstep_apply_ex(
|
|||
/* validate that view is in valid configuration after this operation */
|
||||
UI_view2d_curRect_validate(v2d);
|
||||
|
||||
if (ED_region_snap_size_apply(ar, snap_test)) {
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ED_area_tag_redraw(sa);
|
||||
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
/* request updates to be done... */
|
||||
ED_region_tag_redraw(vzd->ar);
|
||||
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
|
||||
|
@ -898,7 +905,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
|
|||
v2dViewZoomData *vzd = op->customdata;
|
||||
View2D *v2d = vzd->v2d;
|
||||
float dx, dy;
|
||||
|
||||
const int snap_test = ED_region_snap_size_test(vzd->ar);
|
||||
|
||||
/* get amount to move view by */
|
||||
dx = RNA_float_get(op->ptr, "deltax");
|
||||
dy = RNA_float_get(op->ptr, "deltay");
|
||||
|
@ -961,7 +969,13 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
|
|||
|
||||
/* validate that view is in valid configuration after this operation */
|
||||
UI_view2d_curRect_validate(v2d);
|
||||
|
||||
|
||||
if (ED_region_snap_size_apply(vzd->ar, snap_test)) {
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ED_area_tag_redraw(sa);
|
||||
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
/* request updates to be done... */
|
||||
ED_region_tag_redraw(vzd->ar);
|
||||
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
|
||||
|
@ -2000,6 +2014,7 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
ARegion *ar = CTX_wm_region(C);
|
||||
View2D *v2d = &ar->v2d;
|
||||
int winx, winy;
|
||||
const int snap_test = ED_region_snap_size_test(ar);
|
||||
|
||||
/* zoom 1.0 */
|
||||
winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
|
||||
|
@ -2033,7 +2048,13 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
/* validate that view is in valid configuration after this operation */
|
||||
UI_view2d_curRect_validate(v2d);
|
||||
|
||||
|
||||
if (ED_region_snap_size_apply(ar, snap_test)) {
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ED_area_tag_redraw(sa);
|
||||
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
/* request updates to be done... */
|
||||
ED_region_tag_redraw(ar);
|
||||
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
|
||||
|
|
|
@ -2741,3 +2741,36 @@ void ED_region_message_subscribe(
|
|||
ar->type->message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
|
||||
}
|
||||
}
|
||||
|
||||
int ED_region_snap_size_test(const ARegion *ar)
|
||||
{
|
||||
/* Use a larger value because toggling scrollbars can jump in size. */
|
||||
const int snap_match_threshold = 16;
|
||||
if (ar->type->snap_size != NULL) {
|
||||
return ((((ar->sizex - ar->type->snap_size(ar, ar->sizex, 0)) <= snap_match_threshold) << 0) |
|
||||
(((ar->sizey - ar->type->snap_size(ar, ar->sizey, 1)) <= snap_match_threshold) << 1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ED_region_snap_size_apply(ARegion *ar, int snap_flag)
|
||||
{
|
||||
bool changed = false;
|
||||
if (ar->type->snap_size != NULL) {
|
||||
if (snap_flag & (1 << 0)) {
|
||||
short snap_size = ar->type->snap_size(ar, ar->sizex, 0);
|
||||
if (snap_size != ar->sizex) {
|
||||
ar->sizex = snap_size;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (snap_flag & (1 << 1)) {
|
||||
short snap_size = ar->type->snap_size(ar, ar->sizey, 1);
|
||||
if (snap_size != ar->sizey) {
|
||||
ar->sizey = snap_size;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
|
|
@ -2156,7 +2156,8 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
/* execute the events */
|
||||
switch (event->type) {
|
||||
case MOUSEMOVE:
|
||||
|
||||
{
|
||||
const int snap_size_threshold = U.widget_unit * 3;
|
||||
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
|
||||
delta = event->x - rmd->origx;
|
||||
if (rmd->edge == AE_LEFT_TO_TOPRIGHT) delta = -delta;
|
||||
|
@ -2165,8 +2166,15 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
delta /= UI_DPI_FAC;
|
||||
|
||||
rmd->ar->sizex = rmd->origval + delta;
|
||||
|
||||
if (rmd->ar->type->snap_size) {
|
||||
short sizex_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizex, 0);
|
||||
if (ABS(rmd->ar->sizex - sizex_test) < snap_size_threshold) {
|
||||
rmd->ar->sizex = sizex_test;
|
||||
}
|
||||
}
|
||||
CLAMP(rmd->ar->sizex, 0, rmd->maxsize);
|
||||
|
||||
|
||||
if (rmd->ar->sizex < UI_UNIT_X) {
|
||||
rmd->ar->sizex = rmd->origval;
|
||||
if (!(rmd->ar->flag & RGN_FLAG_HIDDEN))
|
||||
|
@ -2184,6 +2192,13 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
delta /= UI_DPI_FAC;
|
||||
|
||||
rmd->ar->sizey = rmd->origval + delta;
|
||||
|
||||
if (rmd->ar->type->snap_size) {
|
||||
short sizey_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizey, 1);
|
||||
if (ABS(rmd->ar->sizey - sizey_test) < snap_size_threshold) {
|
||||
rmd->ar->sizey = sizey_test;
|
||||
}
|
||||
}
|
||||
CLAMP(rmd->ar->sizey, 0, rmd->maxsize);
|
||||
|
||||
/* note, 'UI_UNIT_Y/4' means you need to drag the header almost
|
||||
|
@ -2203,7 +2218,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
case LEFTMOUSE:
|
||||
if (event->val == KM_RELEASE) {
|
||||
|
||||
|
|
|
@ -1277,6 +1277,18 @@ static void view3d_buttons_region_listener(
|
|||
}
|
||||
}
|
||||
|
||||
static int view3d_tools_region_snap_size(const ARegion *ar, int size, int axis)
|
||||
{
|
||||
if (axis == 0) {
|
||||
/* Note, this depends on the icon size: see #ICON_DEFAULT_HEIGHT_TOOLBAR. */
|
||||
const float snap_units = 3.25f;
|
||||
const float aspect = BLI_rctf_size_x(&ar->v2d.cur) / (BLI_rcti_size_x(&ar->v2d.mask) + 1);
|
||||
const int snap_size = (snap_units * U.widget_unit) / aspect;
|
||||
return snap_size;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void view3d_tools_region_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
|
@ -1474,6 +1486,7 @@ void ED_spacetype_view3d(void)
|
|||
art->prefsizey = 50; /* XXX */
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
|
||||
art->listener = view3d_buttons_region_listener;
|
||||
art->snap_size = view3d_tools_region_snap_size;
|
||||
art->init = view3d_tools_region_init;
|
||||
art->draw = view3d_tools_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
|
Loading…
Reference in New Issue