[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26390] trunk/blender/source/blender/ editors/interface/view2d_ops.c: Fix [#20874] zoom to mouse only in 3d view

Matt Ebb matt at mke3.net
Fri Jan 29 09:13:31 CET 2010


Revision: 26390
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26390
Author:   broken
Date:     2010-01-29 09:13:31 +0100 (Fri, 29 Jan 2010)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/interface/view2d_ops.c

Modified: trunk/blender/source/blender/editors/interface/view2d_ops.c
===================================================================
--- trunk/blender/source/blender/editors/interface/view2d_ops.c	2010-01-29 06:43:13 UTC (rev 26389)
+++ trunk/blender/source/blender/editors/interface/view2d_ops.c	2010-01-29 08:13:31 UTC (rev 26390)
@@ -505,7 +505,43 @@
  */
 
 /* ------------------ '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 @@
 /* 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 @@
 				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 @@
 				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 @@
 
 /* --------------- 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 @@
 	/* 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 @@
 	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 @@
 	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 @@
 	
 	/* 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 @@
 	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 @@
  *	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)





More information about the Bf-blender-cvs mailing list