[Bf-blender-cvs] [09d18fb] wiggly-widgets: Scale handlers for the rectangle transform working

Antony Riakiotakis noreply at git.blender.org
Mon Dec 8 12:25:50 CET 2014


Commit: 09d18fb74d280ead8c1b395ebef95c67b3ac0bf1
Author: Antony Riakiotakis
Date:   Fri Dec 5 17:44:17 2014 +0100
Branches: wiggly-widgets
https://developer.blender.org/rB09d18fb74d280ead8c1b395ebef95c67b3ac0bf1

Scale handlers for the rectangle transform working

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

M	source/blender/editors/space_node/space_node.c
M	source/blender/windowmanager/intern/wm_generic_widgets.c
M	source/blender/windowmanager/intern/wm_widgets.c

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

diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index e33ebad..aa4de42 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -866,17 +866,14 @@ static void WIDGETGROUP_node_transform_update(const struct bContext *C, struct w
 		SpaceNode *snode = CTX_wm_space_node(C);
 		ARegion *ar = CTX_wm_region(C);
 		float origin[3];
-		float xsize, ysize;
 		PointerRNA nodeptr;
 
-		xsize = snode->backdrop.scalex * ibuf->x;
-		ysize = snode->backdrop.scalex * ibuf->y;
-		
-		origin[0] = (ar->winx - xsize) / 2;
-		origin[1] = (ar->winy - ysize) / 2;
+		/* center is always at the origin */
+		origin[0] = ar->winx / 2;
+		origin[1] = ar->winy / 2;
 
-		snode->backdrop.w = xsize;
-		snode->backdrop.h = ysize;
+		snode->backdrop.w = ibuf->x;
+		snode->backdrop.h = ibuf->y;
 
 		RNA_pointer_create(snode->id, &RNA_SpaceNodeEditor, snode, &nodeptr);
 		
diff --git a/source/blender/windowmanager/intern/wm_generic_widgets.c b/source/blender/windowmanager/intern/wm_generic_widgets.c
index ba6ac93..d88669c 100644
--- a/source/blender/windowmanager/intern/wm_generic_widgets.c
+++ b/source/blender/windowmanager/intern/wm_generic_widgets.c
@@ -622,6 +622,11 @@ void WIDGET_dial_set_direction(struct wmWidget *widget, float direction[3])
 
 /********* Cage widget ************/
 
+#define WIDGET_RECT_TRANSFORM_INTERSECT_TRANSLATE      1
+#define WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT    2
+#define WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT   3
+#define WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_UP      4
+#define WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN    5
 
 typedef struct RectTransformWidget {
 	wmWidget widget;
@@ -654,33 +659,83 @@ static void rect_transform_draw_corners(rctf *r, float offsetx, float offsety)
 	glEnd();	
 }
 
+static void rect_transform_draw_interaction(int highlighted, float half_w, float half_h, float w, float h)
+{
+	rctf r;
+	
+	
+	switch (highlighted) {
+		case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT:
+			r.xmin = -half_w;
+			r.ymin = -half_h;
+			r.xmax = -half_w + w;
+			r.ymax = half_h;
+			break;
+			
+		case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT:
+			r.xmin = half_w - w;
+			r.ymin = -half_h;
+			r.xmax = half_w;
+			r.ymax = half_h;
+			break;
+			
+		case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN:
+			r.xmin = -half_w;
+			r.ymin = -half_h;
+			r.xmax = half_w;
+			r.ymax = -half_h + h;
+			break;
+			
+		case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_UP:
+			r.xmin = -half_w;
+			r.ymin = half_h - h;
+			r.xmax = half_w;
+			r.ymax = half_h;
+			break;
+			
+		default:
+			return;
+	}
+	
+	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+	glRectf(r.xmin, r.ymin, r.xmax, r.ymax);
+	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+}
+
 static void widget_rect_transform_draw(struct wmWidget *widget, const struct bContext *UNUSED(C))
 {
 	RectTransformWidget *cage = (RectTransformWidget *)widget;
 	rctf r;
 	float w = cage->transform.w;
-	float h = cage->transform.h;
+	float h = cage->transform.h;	
+	float half_w = w / 2.0f;
+	float half_h = h / 2.0f;
 	float aspx = 1.0f, aspy = 1.0f;
 	
-	r.xmin = cage->transform.ofx;
-	r.ymin = cage->transform.ofy;
-	r.xmax = cage->transform.ofx + w;
-	r.ymax = cage->transform.ofy + h;
+	r.xmin = -half_w;
+	r.ymin = -half_h;
+	r.xmax = half_w;
+	r.ymax = half_h;
 	
 	glPushMatrix();
-	glTranslatef(widget->origin[0], widget->origin[1], 0.0f);
+	glTranslatef(widget->origin[0] + cage->transform.ofx, widget->origin[1] + cage->transform.ofy, 0.0f);
+	if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)
+		glScalef(cage->transform.scalex, cage->transform.scalex, 1.0);
+	else
+		glScalef(cage->transform.scalex, cage->transform.scaley, 1.0);
 	
 	if (widget->flag & WM_WIDGET_HIGHLIGHT) {
 		glEnable(GL_BLEND);
 		glColor4f(1.0f, 1.0f, 1.0f, 0.1f);
-		glRectf(cage->transform.ofx, cage->transform.ofy, cage->transform.ofx + w, cage->transform.ofy + h);
+		glRectf(r.xmin, r.ymin, r.xmax, r.ymax);
 		glDisable(GL_BLEND);
 	}
 	
 	if (w > h)
 		aspx = h / w;
-	else if (w < h)
+	else
 		aspy = w / h;
+	
 	w = aspx * w / 8.0f;
 	h = aspy * h / 8.0f;
 
@@ -695,6 +750,7 @@ static void widget_rect_transform_draw(struct wmWidget *widget, const struct bCo
 	glLineWidth(1.0);
 	rect_transform_draw_corners(&r, w, h);
 	
+	rect_transform_draw_interaction(widget->highlighted_part, half_w, half_h, w, h);
 	glPopMatrix();
 }
 
@@ -702,30 +758,92 @@ static int widget_rect_tranfrorm_intersect(struct bContext *UNUSED(C), const str
 {
 	RectTransformWidget *cage = (RectTransformWidget *)widget;
 	float mouse[2] = {event->mval[0], event->mval[1]};
-	float pointrot[2];
-	float matrot[2][2];
+	float point_local[2];
+	float w = cage->transform.w;
+	float h = cage->transform.h;
+	float half_w = w / 2.0f;
+	float half_h = h / 2.0f;
+	//float matrot[2][2];
 	bool isect;
 	rctf r;
-
-	r.xmin = cage->transform.ofx;
-	r.ymin = cage->transform.ofy;
-	r.xmax = cage->transform.ofx + cage->transform.w;
-	r.ymax = cage->transform.ofy + cage->transform.h;
+	float aspx = 1.0f, aspy = 1.0f;
 	
 	/* rotate mouse in relation to the center and relocate it */
-	sub_v2_v2v2(pointrot, mouse, widget->origin);
+	sub_v2_v2v2(point_local, mouse, widget->origin);
+	point_local[0] -= cage->transform.ofx;
+	point_local[1] -= cage->transform.ofy;
+	//rotate_m2(matrot, -cage->transform.rotation);
 
-	rotate_m2(matrot, -cage->transform.rotation);
+	if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)
+		mul_v2_fl(point_local, 1.0f/cage->transform.scalex);
+	else {
+		point_local[0] /= cage->transform.scalex;
+		point_local[1] /= cage->transform.scaley;
+	}
+	
+	if (cage->transform.w > cage->transform.h)
+		aspx = h / w;
+	else
+		aspy = w / h;
+	w = aspx * w / 8.0f;
+	h = aspy * h / 8.0f;
 
-	isect = BLI_rctf_isect_pt_v(&r, pointrot);
+	r.xmin = -half_w + w;
+	r.ymin = -half_h + h;
+	r.xmax = half_w - w;
+	r.ymax = half_h - h;
 	
-	return isect;
+	isect = BLI_rctf_isect_pt_v(&r, point_local);
+	
+	if (isect)
+		return WIDGET_RECT_TRANSFORM_INTERSECT_TRANSLATE;
+
+	r.xmin = -half_w;
+	r.ymin = -half_h;
+	r.xmax = -half_w + w;
+	r.ymax = half_h;
+	
+	isect = BLI_rctf_isect_pt_v(&r, point_local);
+
+	if (isect)
+		return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT;
+	
+	r.xmin = half_w - w;
+	r.ymin = -half_h;
+	r.xmax = half_w;
+	r.ymax = half_h;
+	
+	isect = BLI_rctf_isect_pt_v(&r, point_local);
+	
+	if (isect)
+		return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT;
+
+	r.xmin = -half_w;
+	r.ymin = -half_h;
+	r.xmax = half_w;
+	r.ymax = -half_h + h;
+	
+	isect = BLI_rctf_isect_pt_v(&r, point_local);
+
+	if (isect)
+		return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN;
+	
+	r.xmin = -half_w;
+	r.ymin = half_h - h;
+	r.xmax = half_w;
+	r.ymax = half_h;
+
+	isect = BLI_rctf_isect_pt_v(&r, point_local);
+	
+	if (isect)
+		return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_UP;
+	
+	return 0;
 }
 
 typedef struct RectTransformInteraction {
-	float orig_ofx;
-	float orig_ofy;
 	float orig_mouse[2];
+	wmRectTransformWidget orig_tw;
 	wmRectTransformWidget *tw;
 } RectTransformInteraction;
 
@@ -759,8 +877,7 @@ static int widget_rect_transform_activate(struct bContext *UNUSED(C), const stru
 		RectTransformInteraction *data = MEM_callocN(sizeof (RectTransformInteraction), "cage_interaction");
 
 		if (widget->prop) {
-			data->orig_ofx = cage->transform.ofx;
-			data->orig_ofy = cage->transform.ofy;
+			data->orig_tw = cage->transform;
 			
 			data->tw = widget_rect_transform_get_property(widget);
 		}
@@ -785,15 +902,44 @@ static int widget_rect_transform_handler(struct bContext *C, const struct wmEven
 	ARegion *ar = CTX_wm_region(C);
 	float valuex, valuey;
 	
-	valuex = data->orig_ofx + (event->mval[0] - data->orig_mouse[0]);
-	valuey = data->orig_ofy + (event->mval[1] - data->orig_mouse[1]);
+	valuex = (event->mval[0] - data->orig_mouse[0]);
+	valuey = (event->mval[1] - data->orig_mouse[1]);
 	
-	cage->transform.ofx = valuex;
-	cage->transform.ofy = valuey;
+	if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_TRANSLATE) {
+		cage->transform.ofx = data->orig_tw.ofx + valuex;
+		cage->transform.ofy = data->orig_tw.ofy + valuey;
+	}
+	else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT) {
+		cage->transform.ofx = data->orig_tw.ofx + valuex / 2.0;
+		cage->transform.scalex = (data->orig_tw.w * data->orig_tw.scalex - valuex) / data->orig_tw.w;
+	}
+	else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT) {
+		cage->transform.ofx = data->orig_tw.ofx + valuex / 2.0;
+		cage->transform.scalex = (data->orig_tw.w * data->orig_tw.scalex + valuex) / data->orig_tw.w;
+	}
+	else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN) {
+		cage->transform.ofy = data->orig_tw.ofy + valuey / 2.0;
+		
+		if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+			cage->transform.scalex = (data->orig_tw.h * data->orig_tw.scalex - valuey) / data->orig_tw.h;
+		}
+		else {
+			cage->transform.scaley = (data->orig_tw.h * data->orig_tw.scaley - valuey) / data->orig_tw.h;
+		}
+	}
+	else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_UP) {
+		cage->transform.ofy = data->orig_tw.ofy + valuey / 2.0;
+		
+		if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
+			cage->transform.scalex = (data->orig_tw.h * data->orig_tw.scalex + valuey) / data->orig_tw.h;
+		}
+		else {
+			cage->transform.scaley = (data->orig_tw.h * data->orig_tw.scaley + valuey) / data->orig_tw.h;
+		}
+	}
 	
 	if (widget->prop) {
-		data->tw->ofx = valuex;
-		data->tw->ofy = valuey;
+		*data->tw = cage->transform;
 		RNA_property_update(C, &widget->ptr, widget->prop);
 	}
 	
diff --git a/source/blender/windowmanager/intern/wm_widgets.c b/source/blender/windowmanager/intern/wm_widgets.c
index 7f95e25..70f5900 100644
--- a/source/blender/windowmanager/intern/wm_widgets.c
+++ b/source/blender/windowmanager/intern/wm_widgets.c
@@ -276,6 +276,7 @@ void WM_widgets_draw(const bContext *C, struct ARegion *ar)
 						{
 							widget_iter->flag |= WM_WIDGET_HIGHLIGHT;
 							wmap->highlighted_widget = widget_iter;
+							widget_iter->highlighted_part = highlighted->highli

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list