[Bf-blender-cvs] [7ffe838473a] master: WM: improved area resize snapping

mano-wii noreply at git.blender.org
Thu Jan 18 01:27:40 CET 2018


Commit: 7ffe838473a7f0b4ac4e85b5e004e9e218a3769e
Author: mano-wii
Date:   Thu Jan 18 11:22:58 2018 +1100
Branches: master
https://developer.blender.org/rB7ffe838473a7f0b4ac4e85b5e004e9e218a3769e

WM: improved area resize snapping

Instead of 10px steps, snap to mid-point & adjacent edges.

Not yet implemented for split preview.

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

M	source/blender/editors/screen/screen_ops.c

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

diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 908d218d353..176bdc764a2 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -87,8 +87,8 @@
 
 #define KM_MODAL_CANCEL     1
 #define KM_MODAL_APPLY      2
-#define KM_MODAL_STEP10     3
-#define KM_MODAL_STEP10_OFF 4
+#define KM_MODAL_SNAP_ON    3
+#define KM_MODAL_SNAP_OFF   4
 
 /* ************** Exported Poll tests ********************** */
 
@@ -1077,8 +1077,9 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot)
  */
 
 typedef struct sAreaMoveData {
-	int bigger, smaller, origval, step;
+	int bigger, smaller, origval;
 	char dir;
+	bool do_snap;
 } sAreaMoveData;
 
 /* helper call to move area-edge, sets limits
@@ -1170,55 +1171,101 @@ static int area_move_init(bContext *C, wmOperator *op)
 	return 1;
 }
 
+static int area_snap_calc_location(
+        const bScreen *sc, const int delta,
+        const int origval, const int dir,
+        const int bigger, const int smaller)
+{
+	int final_loc = -1;
+
+	const int m_loc = origval + delta;
+	const int axis = (dir == 'v') ? 0 : 1;
+	int snap_dist = INT_MAX;
+	int dist;
+	{
+		/* Test the snap to middle. */
+		int middle = origval + (bigger - smaller) / 2;
+		middle -= (middle % AREAGRID);
+
+		dist = abs(m_loc - middle);
+		if (dist <= snap_dist) {
+			snap_dist = dist;
+			final_loc = middle;
+		}
+	}
+
+	for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) {
+		if (v1->editflag) {
+			const int v_loc = (&v1->vec.x)[!axis];
+
+			for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) {
+				if (!v2->editflag) {
+					if (v_loc == (&v2->vec.x)[!axis]) {
+						const int v_loc2 = (&v2->vec.x)[axis];
+						/* Do not snap to the vertices at the ends. */
+						if ((origval - smaller) < v_loc2 && v_loc2 < (origval + bigger)) {
+							dist = abs(m_loc - v_loc2);
+							if (dist <= snap_dist) {
+								snap_dist = dist;
+								final_loc = v_loc2;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return final_loc;
+}
+
 /* moves selected screen edge amount of delta, used by split & move */
-static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int bigger, int smaller)
+static void area_move_apply_do(
+        const bContext *C, int delta,
+        const int origval, const int dir,
+        const int bigger, const int smaller,
+        const bool do_snap)
 {
-	wmWindow *win = CTX_wm_window(C);
-	const int winsize_x = WM_window_pixels_x(win);
-	const int winsize_y = WM_window_pixels_y(win);
 	bScreen *sc = CTX_wm_screen(C);
 	ScrVert *v1;
-	ScrArea *sa;
-	int doredraw = 0;
-	int oldval;
-	
-	delta = CLAMPIS(delta, -smaller, bigger);
-	
+	bool doredraw = false;
+	CLAMP(delta, -smaller, bigger);
+
+	short final_loc = -1;
+
+	if (do_snap) {
+		final_loc = area_snap_calc_location(sc, delta, origval, dir, bigger, smaller);
+	}
+	else {
+		final_loc = origval + delta;
+		if (delta != bigger && delta != -smaller) {
+			final_loc -= (final_loc % AREAGRID);
+		}
+	}
+
+	BLI_assert(final_loc != -1);
+	short axis = (dir == 'v') ? 0 : 1;
+
 	for (v1 = sc->vertbase.first; v1; v1 = v1->next) {
 		if (v1->editflag) {
-			/* that way a nice AREAGRID  */
-			if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < winsize_x - 1) {
-				oldval = v1->vec.x;
-				v1->vec.x = origval + delta;
-				
-				if (delta != bigger && delta != -smaller) {
-					v1->vec.x -= (v1->vec.x % AREAGRID);
-					v1->vec.x = CLAMPIS(v1->vec.x, origval - smaller, origval + bigger);
-				}
-				if (oldval != v1->vec.x)
-					doredraw = 1;
-			}
-			if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < winsize_y - 1) {
-				oldval = v1->vec.y;
-				v1->vec.y = origval + delta;
-				
-				if (delta != bigger && delta != smaller) {
-					v1->vec.y -= (v1->vec.y % AREAGRID);
-					v1->vec.y = CLAMPIS(v1->vec.y, origval - smaller, origval + bigger);
-				}
-				if (oldval != v1->vec.y)
-					doredraw = 1;
+			short oldval = (&v1->vec.x)[axis];
+			(&v1->vec.x)[axis] = final_loc;
+
+			if (oldval == final_loc) {
+				/* nothing will change to the other vertices either. */
+				break;
 			}
+			doredraw = true;
 		}
 	}
 
 	/* only redraw if we actually moved a screen vert, for AREAGRID */
 	if (doredraw) {
-		for (sa = sc->areabase.first; sa; sa = sa->next) {
-			if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag)
+		for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
+			if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) {
 				ED_area_tag_redraw(sa);
+			}
 		}
-
 		WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */
 	}
 }
@@ -1226,10 +1273,9 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int
 static void area_move_apply(bContext *C, wmOperator *op)
 {
 	sAreaMoveData *md = op->customdata;
-	int delta;
-	
-	delta = RNA_int_get(op->ptr, "delta");
-	area_move_apply_do(C, md->origval, delta, md->dir, md->bigger, md->smaller);
+	int delta = RNA_int_get(op->ptr, "delta");
+
+	area_move_apply_do(C, delta, md->origval, md->dir, md->bigger, md->smaller, md->do_snap);
 }
 
 static void area_move_exit(bContext *C, wmOperator *op)
@@ -1291,7 +1337,6 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
 			y = RNA_int_get(op->ptr, "y");
 			
 			delta = (md->dir == 'v') ? event->x - x : event->y - y;
-			if (md->step) delta = delta - (delta % md->step);
 			RNA_int_set(op->ptr, "delta", delta);
 			
 			area_move_apply(C, op);
@@ -1307,12 +1352,12 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
 				case KM_MODAL_CANCEL:
 					area_move_cancel(C, op);
 					return OPERATOR_CANCELLED;
-					
-				case KM_MODAL_STEP10:
-					md->step = 10;
+
+				case KM_MODAL_SNAP_ON:
+					md->do_snap = true;
 					break;
-				case KM_MODAL_STEP10_OFF:
-					md->step = 0;
+				case KM_MODAL_SNAP_OFF:
+					md->do_snap = false;
 					break;
 			}
 			break;
@@ -1388,6 +1433,7 @@ typedef struct sAreaSplitData {
 	int delta;              /* delta move edge */
 	int origmin, origsize;  /* to calculate fac, for property storage */
 	int previewmode;        /* draw previewline, then split */
+	bool do_snap;
 
 	ScrEdge *nedge;         /* new edge */
 	ScrArea *sarea;         /* start area */
@@ -1686,8 +1732,9 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
 			
 			sd->delta = (dir == 'v') ? event->x - sd->origval : event->y - sd->origval;
 			if (sd->previewmode == 0)
-				area_move_apply_do(C, sd->origval, sd->delta, dir, sd->bigger, sd->smaller);
+				area_move_apply_do(C, sd->delta, sd->origval, dir, sd->bigger, sd->smaller, sd->do_snap);
 			else {
+				/* TODO: Snap in preview mode too. */
 				if (sd->sarea) {
 					sd->sarea->flag &= ~(AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V);
 					ED_area_tag_redraw(sd->sarea);
@@ -1766,6 +1813,10 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
 		case ESCKEY:
 			area_split_cancel(C, op);
 			return OPERATOR_CANCELLED;
+
+		case LEFTCTRLKEY:
+			sd->do_snap = event->val == KM_PRESS;
+			break;
 	}
 	
 	return OPERATOR_RUNNING_MODAL;
@@ -4298,8 +4349,8 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
 	static const EnumPropertyItem modal_items[] = {
 		{KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
 		{KM_MODAL_APPLY, "APPLY", 0, "Apply", ""},
-		{KM_MODAL_STEP10, "STEP10", 0, "Steps on", ""},
-		{KM_MODAL_STEP10_OFF, "STEP10_OFF", 0, "Steps off", ""},
+		{KM_MODAL_SNAP_ON, "SNAP", 0, "Snap on", ""},
+		{KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""},
 		{0, NULL, 0, NULL, NULL}};
 	wmKeyMap *keymap;
 	
@@ -4311,8 +4362,8 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
 	WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
 	WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
 	
-	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_STEP10);
-	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, KM_MODAL_STEP10_OFF);
+	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_SNAP_ON);
+	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, KM_MODAL_SNAP_OFF);
 	
 	WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");



More information about the Bf-blender-cvs mailing list