[Bf-blender-cvs] [5fb2d21] master: NDOF: support pan/zoom for view2d (nodes, graph editor, sequencer... etc)

Campbell Barton noreply at git.blender.org
Tue Feb 18 01:58:39 CET 2014


Commit: 5fb2d213905abcb92b79092db6645c5a3a13cd10
Author: Campbell Barton
Date:   Tue Feb 18 11:44:26 2014 +1100
https://developer.blender.org/rB5fb2d213905abcb92b79092db6645c5a3a13cd10

NDOF: support pan/zoom for view2d (nodes, graph editor, sequencer... etc)

===================================================================

M	source/blender/editors/interface/view2d_ops.c

===================================================================

diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index a332e5b..95859be 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -126,16 +126,32 @@ static int view_pan_init(bContext *C, wmOperator *op)
 	return 1;
 }
 
+static int view_pan_poll(bContext *C)
+{
+	ARegion *ar = CTX_wm_region(C);
+	View2D *v2d;
+
+	/* check if there's a region in context to work with */
+	if (ar == NULL)
+		return 0;
+	v2d = &ar->v2d;
+
+	/* check that 2d-view can pan */
+	if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y))
+		return 0;
+
+	/* view can pan */
+	return 1;
+}
+
 /* apply transform to view (i.e. adjust 'cur' rect) */
-static void view_pan_apply(bContext *C, wmOperator *op)
+static void view_pan_apply_ex(bContext *C, v2dViewPanData *vpd, float dx, float dy)
 {
-	v2dViewPanData *vpd = op->customdata;
 	View2D *v2d = vpd->v2d;
-	float dx, dy;
 	
 	/* calculate amount to move view by */
-	dx = vpd->facx * (float)RNA_int_get(op->ptr, "deltax");
-	dy = vpd->facy * (float)RNA_int_get(op->ptr, "deltay");
+	dx *= vpd->facx;
+	dy *= vpd->facy;
 	
 	/* only move view on an axis if change is allowed */
 	if ((v2d->keepofs & V2D_LOCKOFS_X) == 0) {
@@ -164,6 +180,16 @@ static void view_pan_apply(bContext *C, wmOperator *op)
 	}
 }
 
+static void view_pan_apply(bContext *C, wmOperator *op)
+{
+	v2dViewPanData *vpd = op->customdata;
+
+	view_pan_apply_ex(C, vpd,
+	                  RNA_int_get(op->ptr, "deltax"),
+	                  RNA_int_get(op->ptr, "deltay"));
+
+}
+
 /* cleanup temp customdata  */
 static void view_pan_exit(wmOperator *op)
 {
@@ -527,6 +553,25 @@ typedef struct v2dViewZoomData {
 	float mx_2d, my_2d;     /* initial mouse location in v2d coords */
 } v2dViewZoomData;
 
+/**
+ * Clamp by convention rather then locking flags,
+ * for ndof and +/- keys
+ */
+static void view_zoom_axis_lock_defaults(bContext *C, bool r_do_zoom_xy[2])
+{
+	ScrArea *sa = CTX_wm_area(C);
+
+	r_do_zoom_xy[0] = true;
+	r_do_zoom_xy[1] = true;
+
+	/* default not to zoom the sequencer vertically */
+	if (sa && sa->spacetype == SPACE_SEQ) {
+		ARegion *ar = CTX_wm_region(C);
+
+		if (ar && ar->regiontype != RGN_TYPE_PREVIEW)
+			r_do_zoom_xy = false;
+	}
+}
 
 /* initialize panning customdata */
 static int view_zoomdrag_init(bContext *C, wmOperator *op)
@@ -575,19 +620,16 @@ 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)
+static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool use_mousepos,
+                                   const float facx, const float facy)
 {
-	v2dViewZoomData *vzd = op->customdata;
 	ARegion *ar = CTX_wm_region(C);
 	View2D *v2d = &ar->v2d;
-	float dx, dy, facx, facy;
-	
+	float dx, dy;
+
 	/* calculate amount to move view by, ensuring symmetry so the
 	 * old zoom level is restored after zooming back the same amount 
 	 */
-	facx = RNA_float_get(op->ptr, "zoomfacx");
-	facy = RNA_float_get(op->ptr, "zoomfacy");
-
 	if (facx >= 0.0f) {
 		dx = BLI_rctf_size_x(&v2d->cur) * facx;
 		dy = BLI_rctf_size_y(&v2d->cur) * facy;
@@ -609,7 +651,7 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
 				v2d->cur.xmax -= 2 * dx;
 		}
 		else {
-			if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+			if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
 				float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
 				float mval_faci = 1.0f - mval_fac;
 				float ofs = (mval_fac * dx) - (mval_faci * dx);
@@ -634,7 +676,7 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
 				v2d->cur.ymax -= 2 * dy;
 		}
 		else {
-			if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+			if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
 				float mval_fac = (vzd->my_2d - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
 				float mval_faci = 1.0f - mval_fac;
 				float ofs = (mval_fac * dy) - (mval_faci * dy);
@@ -657,6 +699,14 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
 	UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
 }
 
+static void view_zoomstep_apply(bContext *C, wmOperator *op)
+{
+	v2dViewZoomData *vzd = op->customdata;
+	view_zoomstep_apply_ex(C, vzd, true,
+	                       RNA_float_get(op->ptr, "zoomfacx"),
+	                       RNA_float_get(op->ptr, "zoomfacy"));
+}
+
 /* --------------- Individual Operators ------------------- */
 
 /* cleanup temp customdata  */
@@ -673,25 +723,18 @@ 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)
 {
-	ScrArea *sa = CTX_wm_area(C);
-	bool do_zoom_x = true;
-	bool do_zoom_y = true;
+	bool do_zoom_xy[2];
 
 	/* check that there's an active region, as View2D data resides there */
 	if (!view_zoom_poll(C))
 		return OPERATOR_PASS_THROUGH;
 	
-	/* default not to zoom the sequencer vertically */
-	if (sa && sa->spacetype == SPACE_SEQ) {
-		ARegion *ar = CTX_wm_region(C);
 
-		if (ar && ar->regiontype != RGN_TYPE_PREVIEW)
-			do_zoom_y = false;
-	}
+	view_zoom_axis_lock_defaults(C, do_zoom_xy);
 
 	/* set RNA-Props - zooming in by uniform factor */
-	RNA_float_set(op->ptr, "zoomfacx", do_zoom_x ? 0.0375f : 0.0f);
-	RNA_float_set(op->ptr, "zoomfacy", do_zoom_y ? 0.0375f : 0.0f);
+	RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? 0.0375f : 0.0f);
+	RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? 0.0375f : 0.0f);
 	
 	/* apply movement, then we're done */
 	view_zoomstep_apply(C, op);
@@ -742,25 +785,17 @@ static void VIEW2D_OT_zoom_in(wmOperatorType *ot)
 /* this operator only needs this single callback, where it calls the view_zoom_*() methods */
 static int view_zoomout_exec(bContext *C, wmOperator *op)
 {
-	ScrArea *sa = CTX_wm_area(C);
-	bool do_zoom_x = true;
-	bool do_zoom_y = true;
+	bool do_zoom_xy[2];
 
 	/* check that there's an active region, as View2D data resides there */
 	if (!view_zoom_poll(C))
 		return OPERATOR_PASS_THROUGH;
 	
-	/* default not to zoom the sequencer vertically */
-	if (sa && sa->spacetype == SPACE_SEQ) {
-		ARegion *ar = CTX_wm_region(C);
-
-		if (ar && ar->regiontype != RGN_TYPE_PREVIEW)
-			do_zoom_y = false;
-	}
+	view_zoom_axis_lock_defaults(C, do_zoom_xy);
 
 	/* set RNA-Props - zooming in by uniform factor */
-	RNA_float_set(op->ptr, "zoomfacx", do_zoom_x ? -0.0375f : 0.0f);
-	RNA_float_set(op->ptr, "zoomfacy", do_zoom_y ? -0.0375f : 0.0f);
+	RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? -0.0375f : 0.0f);
+	RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? -0.0375f : 0.0f);
 	
 	/* apply movement, then we're done */
 	view_zoomstep_apply(C, op);
@@ -1220,6 +1255,81 @@ static void VIEW2D_OT_zoom_border(wmOperatorType *ot)
 	WM_operator_properties_gesture_border(ot, false);
 }
 
+
+static int view2d_ndof_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+	if (event->type != NDOF_MOTION) {
+		return OPERATOR_CANCELLED;
+	}
+	else {
+		wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+
+		float dt = ndof->dt;
+		/* tune these until it feels right */
+		const float zoom_sensitivity = 0.5f;
+		const float pan_sensitivity = 10.0f; /* match view3d ortho */
+		const bool has_translate = (ndof->tvec[0] && ndof->tvec[1]) && view_pan_poll(C);
+		const bool has_zoom = (ndof->tvec[2] != 0.0f) && view_zoom_poll(C);
+
+		if (has_translate) {
+			if (view_pan_init(C, op)) {
+				v2dViewPanData *vpd;
+				float pan_vec[2];
+
+				pan_vec[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
+				pan_vec[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
+
+				pan_vec[0] *= pan_sensitivity;
+				pan_vec[1] *= pan_sensitivity;
+
+				vpd = op->customdata;
+
+				view_pan_apply_ex(C, vpd, pan_vec[0], pan_vec[1]);
+
+				view_pan_exit(op);
+			}
+		}
+
+		if (has_zoom) {
+			if (view_zoomdrag_init(C, op)) {
+				v2dViewZoomData *vzd;
+				float zoom_factor = zoom_sensitivity * dt * -ndof->tvec[2];
+
+				bool do_zoom_xy[2];
+
+				if (U.ndof_flag & NDOF_ZOOM_INVERT)
+					zoom_factor = -zoom_factor;
+
+				view_zoom_axis_lock_defaults(C, do_zoom_xy);
+
+				vzd = op->customdata;
+
+				view_zoomstep_apply_ex(C, vzd, false,
+				                       do_zoom_xy[0] ? zoom_factor : 0.0f,
+				                       do_zoom_xy[1] ? zoom_factor : 0.0f);
+
+				view_zoomstep_exit(op);
+			}
+		}
+
+		return OPERATOR_FINISHED;
+	}
+}
+
+static void VIEW2D_OT_ndof(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "NDOF Pan/Zoom";
+	ot->idname = "VIEW2D_OT_ndof";
+	ot->description = "Use a 3D mouse device to pan/zoom the view";
+
+	/* api callbacks */
+	ot->invoke = view2d_ndof_invoke;
+
+	/* flags */
+	ot->flag = OPTYPE_LOCK_BYPASS;
+}
+
 /* ********************************************************* */
 /* SMOOTH VIEW */
 
@@ -1898,6 +2008,8 @@ void UI_view2d_operatortypes(void)
 	WM_operatortype_append(VIEW2D_OT_zoom);
 	WM_operatortype_append(VIEW2D_OT_zoom_border);
 
+	WM_operatortype_append(VIEW2D_OT_ndof);
+
 	WM_operatortype_append(VIEW2D_OT_smoothview);
 	
 	WM_operatortype_append(VIEW2D_OT_scroller_activate);
@@ -1926,6 +2038,8 @@ void UI_view2d_keymap(wmKeyConfig *keyconf)
 	WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0);
 	WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, KM_SHIFT, 0);
 	
+	WM_keymap_add_item(keymap, "VIEW2D_OT_ndof", NDOF_MOTION, 0, 0, 0);
+
 	/* zoom - single step */
 	WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);




More information about the Bf-blender-cvs mailing list