Fix inaccuracy of SCREEN_OT_area_split when snap to midpoint and adjacent.

By default when moving a edge of the screen it always snaps to an invisible grid with unit of 4 pixels.
This was also affecting the snap to the midpoint and adjacent.
The solution was to make the snap to areagrid optional and use values of `origmin` and `origsize` that match the transformations in screen_edit.c.
This commit is contained in:
Germano Cavalcante 2018-06-02 03:17:51 -03:00
parent 0de0cee9a2
commit 58efa7d686
2 changed files with 64 additions and 44 deletions

View File

@ -226,25 +226,25 @@ static short testsplitpoint(ScrArea *sa, char dir, float fac)
CLAMP(fac, 0.0f, 1.0f);
if (dir == 'h') {
y = sa->v1->vec.y + fac * (sa->v2->vec.y - sa->v1->vec.y);
y = sa->v1->vec.y +
round_fl_to_short(fac * (float)(sa->v2->vec.y - sa->v1->vec.y));
if (y - sa->v1->vec.y < area_min_y)
y = sa->v1->vec.y + area_min_y;
else if (sa->v2->vec.y - y < area_min_y)
y = sa->v2->vec.y - area_min_y;
else y -= (y % AREAGRID);
return y;
}
else {
x = sa->v1->vec.x + fac * (sa->v4->vec.x - sa->v1->vec.x);
x = sa->v1->vec.x +
round_fl_to_short(fac * (float)(sa->v4->vec.x - sa->v1->vec.x));
if (x - sa->v1->vec.x < area_min_x)
x = sa->v1->vec.x + area_min_x;
else if (sa->v4->vec.x - x < area_min_x)
x = sa->v4->vec.x - area_min_x;
else x -= (x % AREAGRID);
return x;
}
}
@ -609,7 +609,7 @@ static void screen_vertices_scale(
if (screen_size_x_prev != screen_size_x || screen_size_y_prev != screen_size_y) {
const float facx = ((float)screen_size_x - 1) / ((float)screen_size_x_prev - 1);
const float facy = ((float)screen_size_y) / ((float)screen_size_y_prev);
const float facy = ((float)screen_size_y - 1) / ((float)screen_size_y_prev - 1);
/* make sure it fits! */
for (sv = sc->vertbase.first; sv; sv = sv->next) {
@ -617,7 +617,7 @@ static void screen_vertices_scale(
CLAMP(sv->vec.x, screen_rect->xmin, screen_rect->xmax - 1);
sv->vec.y = screen_rect->ymin + round_fl_to_short((sv->vec.y - min[1]) * facy);
CLAMP(sv->vec.y, screen_rect->ymin, screen_rect->ymax);
CLAMP(sv->vec.y, screen_rect->ymin, screen_rect->ymax - 1);
}
}

View File

@ -1185,6 +1185,8 @@ typedef struct sAreaMoveData {
enum AreaMoveSnapType {
/* Snapping disabled */
SNAP_NONE = 0,
/* Snap to an invisible grid with a unit defined in AREAGRID */
SNAP_AREAGRID,
/* Snap to mid-point and adjacent edges. */
SNAP_MIDPOINT_AND_ADJACENT,
/* Snap to either bigger or smaller, nothing in-between (used for
@ -1323,7 +1325,7 @@ static int area_move_init(bContext *C, wmOperator *op)
&md->bigger, &md->smaller,
&use_bigger_smaller_snap);
md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_NONE;
md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_AREAGRID;
return 1;
}
@ -1334,30 +1336,43 @@ static int area_snap_calc_location(
const int bigger, const int smaller)
{
BLI_assert(snap_type != SNAP_NONE);
if (snap_type == SNAP_BIGGER_SMALLER_ONLY) {
return ((origval + delta) >= bigger) ? bigger : smaller;
}
int final_loc = -1;
const int m_loc = origval + delta;
const int axis = (dir == 'v') ? 0 : 1;
int snap_dist;
int dist;
{
/* Test the snap to middle. */
int middle = origval + (bigger - smaller) / 2;
middle -= (middle % AREAGRID);
snap_dist = abs(m_loc - middle);
final_loc = middle;
}
switch (snap_type) {
case SNAP_AREAGRID:
final_loc = m_loc;
if (delta != bigger && delta != -smaller) {
final_loc -= (m_loc % AREAGRID);
}
break;
for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) {
if (v1->editflag) {
const int v_loc = (&v1->vec.x)[!axis];
case SNAP_BIGGER_SMALLER_ONLY:
final_loc = (m_loc >= bigger) ? bigger : smaller;
break;
for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) {
if (!v2->editflag) {
case SNAP_MIDPOINT_AND_ADJACENT:
{
const int axis = (dir == 'v') ? 0 : 1;
int snap_dist;
int dist;
{
/* Test the snap to middle. */
int middle = origval + (bigger - smaller) / 2;
snap_dist = abs(m_loc - middle);
final_loc = middle;
}
for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) {
if (!v1->editflag) {
continue;
}
const int v_loc = (&v1->vec.x)[!axis];
for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) {
if (v2->editflag) {
continue;
}
if (v_loc == (&v2->vec.x)[!axis]) {
const int v_loc2 = (&v2->vec.x)[axis];
/* Do not snap to the vertices at the ends. */
@ -1371,6 +1386,7 @@ static int area_snap_calc_location(
}
}
}
break;
}
}
@ -1393,9 +1409,6 @@ static void area_move_apply_do(
if (snap_type == SNAP_NONE) {
final_loc = origval + delta;
if (delta != bigger && delta != -smaller) {
final_loc -= (final_loc % AREAGRID);
}
}
else {
final_loc = area_snap_calc_location(sc, snap_type, delta, origval, dir, bigger, smaller);
@ -1526,13 +1539,14 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
case KM_MODAL_SNAP_ON:
if (md->snap_type == SNAP_NONE) {
if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) {
md->snap_type = SNAP_MIDPOINT_AND_ADJACENT;
}
break;
case KM_MODAL_SNAP_OFF:
if (md->snap_type == SNAP_MIDPOINT_AND_ADJACENT) {
md->snap_type = SNAP_NONE;
if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) {
md->snap_type = SNAP_AREAGRID;
}
break;
}
@ -1652,7 +1666,7 @@ static int area_split_init(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
sAreaSplitData *sd;
int areaminy = ED_area_headersize() + 1;
int areaminy = ED_area_headersize();
int dir;
/* required context */
@ -1670,9 +1684,15 @@ static int area_split_init(bContext *C, wmOperator *op)
op->customdata = sd;
sd->sarea = sa;
sd->origsize = dir == 'v' ? sa->winx : sa->winy;
sd->origmin = dir == 'v' ? sa->totrct.xmin : sa->totrct.ymin;
if (dir == 'v') {
sd->origmin = sa->v1->vec.x;
sd->origsize = sa->v4->vec.x - sd->origmin;
}
else {
sd->origmin = sa->v1->vec.y;
sd->origsize = sa->v2->vec.y - sd->origmin;
}
return 1;
}
@ -1991,12 +2011,12 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (sd->sarea) {
ScrArea *sa = sd->sarea;
if (dir == 'v') {
sd->origsize = sa->winx;
sd->origmin = sa->totrct.xmin;
sd->origmin = sa->v1->vec.x;
sd->origsize = sa->v4->vec.x - sd->origmin;
}
else {
sd->origsize = sa->winy;
sd->origmin = sa->totrct.ymin;
sd->origmin = sa->v1->vec.y;
sd->origsize = sa->v2->vec.y - sd->origmin;
}
if (sd->do_snap) {