Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2018-01-18 03:22:58 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-01-18 03:33:51 +0300
commit7ffe838473a7f0b4ac4e85b5e004e9e218a3769e (patch)
treee6d6e86929b6bc13d5c4edaf4545545a853dbebe /source/blender/editors/screen
parente6df02861e17f75d4dd243776f35208681b78465 (diff)
WM: improved area resize snapping
Instead of 10px steps, snap to mid-point & adjacent edges. Not yet implemented for split preview.
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r--source/blender/editors/screen/screen_ops.c157
1 files changed, 104 insertions, 53 deletions
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");