WM: improved area resize snapping
Instead of 10px steps, snap to mid-point & adjacent edges. Not yet implemented for split preview.
This commit is contained in:
parent
e6df02861e
commit
7ffe838473
|
@ -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;
|
||||
}
|
||||
|
||||
/* 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 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(
|
||||
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");
|
||||
|
||||
|
|
Loading…
Reference in New Issue