diff options
author | Matt Ebb <matt@mke3.net> | 2010-01-29 11:13:31 +0300 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2010-01-29 11:13:31 +0300 |
commit | a368d5269ac3748e05aefb258a14b1210b6d69c4 (patch) | |
tree | f2f07bc4a8f681dd44f1d808d847d8e9e02c19d7 /source/blender/editors/interface | |
parent | 88ae9b121e2899779fb8e52161778f99b44402b5 (diff) |
Fix [#20874] zoom to mouse only in 3d view
Zoom to mouse was working in 2D Views for modal zoom (ctrl MMB) but not for mouse wheel.
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r-- | source/blender/editors/interface/view2d_ops.c | 156 |
1 files changed, 111 insertions, 45 deletions
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index bd325eb79eb..b25922cab5a 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -505,7 +505,43 @@ void VIEW2D_OT_scroll_up(wmOperatorType *ot) */ /* ------------------ 'Shared' stuff ------------------------ */ - + +/* temp customdata for operator */ +typedef struct v2dViewZoomData { + View2D *v2d; /* view2d we're operating in */ + + int lastx, lasty; /* previous x/y values of mouse in window */ + float dx, dy; /* running tally of previous delta values (for obtaining final zoom) */ + float mx_2d, my_2d; /* initial mouse location in v2d coords */ +} v2dViewZoomData; + + +/* initialise panning customdata */ +static int view_zoomdrag_init(bContext *C, wmOperator *op) +{ + ARegion *ar= CTX_wm_region(C); + v2dViewZoomData *vzd; + View2D *v2d; + + /* regions now have v2d-data by default, so check for region */ + if (ar == NULL) + return 0; + v2d= &ar->v2d; + + /* check that 2d-view is zoomable */ + if ((v2d->keepzoom & V2D_LOCKZOOM_X) && (v2d->keepzoom & V2D_LOCKZOOM_Y)) + return 0; + + /* set custom-data for operator */ + vzd= MEM_callocN(sizeof(v2dViewZoomData), "v2dViewZoomData"); + op->customdata= vzd; + + /* set pointers to owners */ + vzd->v2d= v2d; + + return 1; +} + /* check if step-zoom can be applied */ static int view_zoom_poll(bContext *C) { @@ -528,6 +564,7 @@ static int view_zoom_poll(bContext *C) /* apply transform to view (i.e. adjust 'cur' rect) */ static void view_zoomstep_apply(bContext *C, wmOperator *op) { + v2dViewZoomData *vzd= op->customdata; ARegion *ar= CTX_wm_region(C); View2D *v2d= &ar->v2d; float dx, dy, facx, facy; @@ -558,8 +595,17 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op) v2d->cur.xmax -= 2*dx; } else { - v2d->cur.xmin += dx; - v2d->cur.xmax -= dx; + if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) { + float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / (v2d->cur.xmax-v2d->cur.xmin); + float mval_faci = 1.0 - mval_fac; + float ofs= (mval_fac * dx) - (mval_faci * dx); + v2d->cur.xmin += ofs + dx; + v2d->cur.xmax += ofs - dx; + } + else { + v2d->cur.xmin += dx; + v2d->cur.xmax -= dx; + } } } if ((v2d->keepzoom & V2D_LOCKZOOM_Y)==0) { @@ -573,8 +619,16 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op) v2d->cur.ymax -= 2*dy; } else { - v2d->cur.ymin += dy; - v2d->cur.ymax -= dy; + if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) { + float mval_fac = (vzd->my_2d - v2d->cur.ymin) / (v2d->cur.ymax-v2d->cur.ymin); + float mval_faci = 1.0 - mval_fac; + float ofs= (mval_fac * dy) - (mval_faci * dy); + v2d->cur.ymin += ofs + dy; + v2d->cur.ymax += ofs - dy; + } else { + v2d->cur.ymin += dy; + v2d->cur.ymax -= dy; + } } } @@ -589,6 +643,15 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op) /* --------------- Individual Operators ------------------- */ +/* cleanup temp customdata */ +static void view_zoomstep_exit(bContext *C, wmOperator *op) +{ + if (op->customdata) { + MEM_freeN(op->customdata); + op->customdata= NULL; + } +} + /* this operator only needs this single callback, where it calls the view_zoom_*() methods */ static int view_zoomin_exec(bContext *C, wmOperator *op) { @@ -603,9 +666,28 @@ static int view_zoomin_exec(bContext *C, wmOperator *op) /* apply movement, then we're done */ view_zoomstep_apply(C, op); + view_zoomstep_exit(C, op); + return OPERATOR_FINISHED; } +static int view_zoomin_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + v2dViewZoomData *vzd; + + if (!view_zoomdrag_init(C, op)) + return OPERATOR_PASS_THROUGH; + + vzd= op->customdata; + + if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) { + ARegion *ar= CTX_wm_region(C); + UI_view2d_region_to_view(&ar->v2d, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin, &vzd->mx_2d, &vzd->my_2d); + } + + return view_zoomin_exec(C, op); +} + void VIEW2D_OT_zoom_in(wmOperatorType *ot) { /* identifiers */ @@ -614,7 +696,9 @@ void VIEW2D_OT_zoom_in(wmOperatorType *ot) ot->idname= "VIEW2D_OT_zoom_in"; /* api callbacks */ + ot->invoke= view_zoomin_invoke; ot->exec= view_zoomin_exec; + ot->poll= view_zoom_poll; /* operator is repeatable */ // ot->flag= OPTYPE_REGISTER; @@ -623,9 +707,7 @@ void VIEW2D_OT_zoom_in(wmOperatorType *ot) RNA_def_float(ot->srna, "zoomfacx", 0, -FLT_MAX, FLT_MAX, "Zoom Factor X", "", -FLT_MAX, FLT_MAX); RNA_def_float(ot->srna, "zoomfacy", 0, -FLT_MAX, FLT_MAX, "Zoom Factor Y", "", -FLT_MAX, FLT_MAX); } - - - + /* this operator only needs this single callback, where it callsthe view_zoom_*() methods */ static int view_zoomout_exec(bContext *C, wmOperator *op) { @@ -639,10 +721,29 @@ static int view_zoomout_exec(bContext *C, wmOperator *op) /* apply movement, then we're done */ view_zoomstep_apply(C, op); + + view_zoomstep_exit(C, op); return OPERATOR_FINISHED; } +static int view_zoomout_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + v2dViewZoomData *vzd; + + if (!view_zoomdrag_init(C, op)) + return OPERATOR_PASS_THROUGH; + + vzd= op->customdata; + + if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) { + ARegion *ar= CTX_wm_region(C); + UI_view2d_region_to_view(&ar->v2d, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin, &vzd->mx_2d, &vzd->my_2d); + } + + return view_zoomout_exec(C, op); +} + void VIEW2D_OT_zoom_out(wmOperatorType *ot) { /* identifiers */ @@ -651,7 +752,9 @@ void VIEW2D_OT_zoom_out(wmOperatorType *ot) ot->idname= "VIEW2D_OT_zoom_out"; /* api callbacks */ + ot->invoke= view_zoomout_invoke; ot->exec= view_zoomout_exec; + ot->poll= view_zoom_poll; /* operator is repeatable */ // ot->flag= OPTYPE_REGISTER; @@ -669,43 +772,6 @@ void VIEW2D_OT_zoom_out(wmOperatorType *ot) * In order to make sure this works, each operator must define the following RNA-Operator Props: * deltax, deltay - amounts to add to each side of the 'cur' rect */ - -/* ------------------ Shared 'core' stuff ---------------------- */ - -/* temp customdata for operator */ -typedef struct v2dViewZoomData { - View2D *v2d; /* view2d we're operating in */ - - int lastx, lasty; /* previous x/y values of mouse in window */ - float dx, dy; /* running tally of previous delta values (for obtaining final zoom) */ - float mx_2d, my_2d; /* initial mouse location in v2d coords */ -} v2dViewZoomData; - -/* initialise panning customdata */ -static int view_zoomdrag_init(bContext *C, wmOperator *op) -{ - ARegion *ar= CTX_wm_region(C); - v2dViewZoomData *vzd; - View2D *v2d; - - /* regions now have v2d-data by default, so check for region */ - if (ar == NULL) - return 0; - v2d= &ar->v2d; - - /* check that 2d-view is zoomable */ - if ((v2d->keepzoom & V2D_LOCKZOOM_X) && (v2d->keepzoom & V2D_LOCKZOOM_Y)) - return 0; - - /* set custom-data for operator */ - vzd= MEM_callocN(sizeof(v2dViewZoomData), "v2dViewZoomData"); - op->customdata= vzd; - - /* set pointers to owners */ - vzd->v2d= v2d; - - return 1; -} /* apply transform to view (i.e. adjust 'cur' rect) */ static void view_zoomdrag_apply(bContext *C, wmOperator *op) |