Fix issues with calling View2D zoom operators in an `EXEC` context

Multiple related issues:
* `view_zoomdrag_exec()` required `view_zoomdrag_init()` to be called first to
  set up data. Can now easily be done in the `_exec()` function as well though.
* Because of that the operators could not be called in an `EXEC_` context (e.g.
  `EXEC_REGION_WIN`).
* With "Zoom to Mouse Position" enabled, zooming from a menu or script would
  zoom to the mouse position. That should only happen if the operators are
  called directly in the editor.
This commit is contained in:
Julian Eisel 2020-10-03 18:24:41 +02:00
parent eacaebea83
commit 3a1cf838ca
Notes: blender-bot 2023-06-07 10:31:13 +02:00
Referenced by commit 2e41db5277, Fix Zoom to Mouse Position ignored when zooming out
Referenced by commit 9668fc582c, Fix compile error when compiling with WITH_INPUT_NDOF after View2D changes
Referenced by pull request #107296, Fix #107294 : Node Editor "Frame All/Selected" ignore Smooth View
Referenced by commit 2f0b166dce, Fix #107294 : Node Editor "Frame All/Selected" ignore Smooth View
2 changed files with 33 additions and 18 deletions

View File

@ -245,8 +245,10 @@ class NODE_MT_view(Menu):
layout.separator()
layout.operator("view2d.zoom_in")
layout.operator("view2d.zoom_out")
sub = layout.column()
sub.operator_context = 'EXEC_REGION_WIN'
sub.operator("view2d.zoom_in")
sub.operator("view2d.zoom_out")
layout.separator()

View File

@ -784,6 +784,7 @@ typedef struct v2dViewZoomData {
int invoke_event; /* event type that invoked, for modal exits */
float dx, dy; /* running tally of previous delta values (for obtaining final zoom) */
float mx_2d, my_2d; /* initial mouse location in v2d coords */
bool zoom_to_mouse_pos;
} v2dViewZoomData;
/**
@ -847,11 +848,15 @@ static void view_zoomdrag_init(bContext *C, wmOperator *op)
/* set pointers to owners */
vzd->region = CTX_wm_region(C);
vzd->v2d = &vzd->region->v2d;
/* False by default. Interactive callbacks (ie invoke()) can set it to true. */
vzd->zoom_to_mouse_pos = false;
}
/* apply transform to view (i.e. adjust 'cur' rect) */
static void view_zoomstep_apply_ex(
bContext *C, v2dViewZoomData *vzd, const bool zoom_to_pos, const float facx, const float facy)
static void view_zoomstep_apply_ex(bContext *C,
v2dViewZoomData *vzd,
const float facx,
const float facy)
{
ARegion *region = CTX_wm_region(C);
View2D *v2d = &region->v2d;
@ -889,7 +894,7 @@ static void view_zoomstep_apply_ex(
v2d->cur.xmin += dx;
v2d->cur.xmax -= dx;
if (zoom_to_pos) {
if (vzd->zoom_to_mouse_pos) {
/* get zoom fac the same way as in
* ui_view2d_curRect_validate_resize - better keep in sync! */
const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
@ -924,7 +929,7 @@ static void view_zoomstep_apply_ex(
v2d->cur.ymin += dy;
v2d->cur.ymax -= dy;
if (zoom_to_pos) {
if (vzd->zoom_to_mouse_pos) {
/* get zoom fac the same way as in
* ui_view2d_curRect_validate_resize - better keep in sync! */
const float zoomy = (float)(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur);
@ -960,9 +965,8 @@ static void view_zoomstep_apply_ex(
static void view_zoomstep_apply(bContext *C, wmOperator *op)
{
v2dViewZoomData *vzd = op->customdata;
const bool zoom_to_pos = U.uiflag & USER_ZOOM_TO_MOUSEPOS;
view_zoomstep_apply_ex(
C, vzd, zoom_to_pos, RNA_float_get(op->ptr, "zoomfacx"), RNA_float_get(op->ptr, "zoomfacy"));
C, vzd, RNA_float_get(op->ptr, "zoomfacx"), RNA_float_get(op->ptr, "zoomfacy"));
}
/** \} */
@ -985,8 +989,11 @@ static void view_zoomstep_exit(wmOperator *op)
/* this operator only needs this single callback, where it calls the view_zoom_*() methods */
static int view_zoomin_exec(bContext *C, wmOperator *op)
{
bool do_zoom_xy[2];
if (op->customdata == NULL) { /* Might have been setup in _invoke() already. */
view_zoomdrag_init(C, op);
}
bool do_zoom_xy[2];
view_zoom_axis_lock_defaults(C, do_zoom_xy);
/* set RNA-Props - zooming in by uniform factor */
@ -1003,11 +1010,9 @@ static int view_zoomin_exec(bContext *C, wmOperator *op)
static int view_zoomin_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd;
view_zoomdrag_init(C, op);
vzd = op->customdata;
v2dViewZoomData *vzd = op->customdata;
if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
ARegion *region = CTX_wm_region(C);
@ -1015,6 +1020,7 @@ static int view_zoomin_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* store initial mouse position (in view space) */
UI_view2d_region_to_view(
&region->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d);
vzd->zoom_to_mouse_pos = true;
}
return view_zoomin_exec(C, op);
@ -1031,7 +1037,7 @@ static void VIEW2D_OT_zoom_in(wmOperatorType *ot)
/* api callbacks */
ot->invoke = view_zoomin_invoke;
ot->exec = view_zoomin_exec; // XXX, needs view_zoomdrag_init called first.
ot->exec = view_zoomin_exec;
ot->poll = view_zoom_poll;
/* rna - must keep these in sync with the other operators */
@ -1048,6 +1054,10 @@ static int view_zoomout_exec(bContext *C, wmOperator *op)
{
bool do_zoom_xy[2];
if (op->customdata == NULL) { /* Might have been setup in _invoke() already. */
view_zoomdrag_init(C, op);
}
view_zoom_axis_lock_defaults(C, do_zoom_xy);
/* set RNA-Props - zooming in by uniform factor */
@ -1064,11 +1074,9 @@ static int view_zoomout_exec(bContext *C, wmOperator *op)
static int view_zoomout_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd;
view_zoomdrag_init(C, op);
vzd = op->customdata;
v2dViewZoomData *vzd = op->customdata;
if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
ARegion *region = CTX_wm_region(C);
@ -1092,7 +1100,8 @@ static void VIEW2D_OT_zoom_out(wmOperatorType *ot)
/* api callbacks */
ot->invoke = view_zoomout_invoke;
// ot->exec = view_zoomout_exec; // XXX, needs view_zoomdrag_init called first.
ot->exec = view_zoomout_exec;
ot->poll = view_zoom_poll;
/* rna - must keep these in sync with the other operators */
@ -1126,7 +1135,7 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
const int snap_test = ED_region_snap_size_test(vzd->region);
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
const bool zoom_to_pos = use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS);
const bool zoom_to_pos = use_cursor_init && vzd->zoom_to_mouse_pos;
/* get amount to move view by */
dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac;
@ -1246,6 +1255,10 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
vzd = op->customdata;
v2d = vzd->v2d;
if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
vzd->zoom_to_mouse_pos = true;
}
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float dx, dy, fac;