diff options
author | mano-wii <germano.costa@ig.com.br> | 2018-01-19 09:14:27 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-01-19 09:15:45 +0300 |
commit | ebf01d44ee0e034da169efc0aca81f99966ebde6 (patch) | |
tree | b9b93e24af4c60ec8d296bc0c1590a20e5c08020 /source/blender/editors | |
parent | 7a24e0d175827824d139f7627de2a5af34d687fb (diff) |
WM: window draw callbacks and split preview snap
This moves window overlay from hard coded flags into drawing callbacks.
It also supports snapping (holding Ctrl).
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 4 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 119 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 125 |
3 files changed, 122 insertions, 126 deletions
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 4253e214537..755aedf946d 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -98,7 +98,9 @@ int ED_area_headersize(void); /* screens */ void ED_screens_initialize(struct wmWindowManager *wm); -void ED_screen_draw(struct wmWindow *win); +void ED_screen_draw_edges(struct wmWindow *win); +void ED_screen_draw_join_shape(struct ScrArea *sa1, struct ScrArea *sa2); +void ED_screen_draw_split_preview(struct ScrArea *sa, const int dir, const float fac); void ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win); void ED_screen_do_listen(struct bContext *C, struct wmNotifier *note); bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 8f1132dc1e5..a4ac27f0796 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -582,8 +582,6 @@ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2) /*printf("dir is : %i\n", dir);*/ if (dir == -1) { - if (sa1) sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; - if (sa2) sa2->flag &= ~AREA_FLAG_DRAWJOINTO; return 0; } @@ -614,8 +612,7 @@ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2) screen_delarea(C, scr, sa2); removedouble_scrverts(scr); - sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; - + return 1; } @@ -1105,16 +1102,15 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note) } } -/* only for edge lines between areas, and the blended join arrows */ -void ED_screen_draw(wmWindow *win) +/** + * Only for edge lines between areas, and the blended join arrows. + */ +void ED_screen_draw_edges(wmWindow *win) { const int winsize_x = WM_window_pixels_x(win); const int winsize_y = WM_window_pixels_y(win); ScrArea *sa; - ScrArea *sa1 = NULL; - ScrArea *sa2 = NULL; - ScrArea *sa3 = NULL; wmSubWindowSet(win, win->screen->mainwin); @@ -1134,69 +1130,70 @@ void ED_screen_draw(wmWindow *win) glBegin(GL_LINES); for (sa = win->screen->areabase.first; sa; sa = sa->next) { drawscredge_area(sa, winsize_x, winsize_y); - - /* gather area split/join info */ - if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa; - if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa; - if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa; } glEnd(); - /* blended join arrow */ - if (sa1 && sa2) { - int dir = area_getorientation(sa1, sa2); - int dira = -1; - if (dir != -1) { - switch (dir) { - case 0: /* W */ - dir = 'r'; - dira = 'l'; - break; - case 1: /* N */ - dir = 'd'; - dira = 'u'; - break; - case 2: /* E */ - dir = 'l'; - dira = 'r'; - break; - case 3: /* S */ - dir = 'u'; - dira = 'd'; - break; - } + win->screen->do_draw = false; +} + +void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2) +{ + glLineWidth(1); + + /* blended join arrow */ + int dir = area_getorientation(sa1, sa2); + int dira = -1; + if (dir != -1) { + switch (dir) { + case 0: /* W */ + dir = 'r'; + dira = 'l'; + break; + case 1: /* N */ + dir = 'd'; + dira = 'u'; + break; + case 2: /* E */ + dir = 'l'; + dira = 'r'; + break; + case 3: /* S */ + dir = 'u'; + dira = 'd'; + break; } glEnable(GL_BLEND); scrarea_draw_shape_dark(sa2, dir); scrarea_draw_shape_light(sa1, dira); glDisable(GL_BLEND); } - +} + +void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac) +{ /* splitpoint */ - if (sa3) { - glEnable(GL_BLEND); - glBegin(GL_LINES); - glColor4ub(255, 255, 255, 100); - - if (sa3->flag & AREA_FLAG_DRAWSPLIT_H) { - glVertex2s(sa3->totrct.xmin, win->eventstate->y); - glVertex2s(sa3->totrct.xmax, win->eventstate->y); - glColor4ub(0, 0, 0, 100); - glVertex2s(sa3->totrct.xmin, win->eventstate->y + 1); - glVertex2s(sa3->totrct.xmax, win->eventstate->y + 1); - } - else { - glVertex2s(win->eventstate->x, sa3->totrct.ymin); - glVertex2s(win->eventstate->x, sa3->totrct.ymax); - glColor4ub(0, 0, 0, 100); - glVertex2s(win->eventstate->x + 1, sa3->totrct.ymin); - glVertex2s(win->eventstate->x + 1, sa3->totrct.ymax); - } - glEnd(); - glDisable(GL_BLEND); - } + glEnable(GL_BLEND); + glBegin(GL_LINES); + glColor4ub(255, 255, 255, 100); - win->screen->do_draw = false; + if (dir == 'h') { + const float y = (1 - fac) * sa->totrct.ymin + fac * sa->totrct.ymax; + glVertex2s(sa->totrct.xmin, y); + glVertex2s(sa->totrct.xmax, y); + glColor4ub(0, 0, 0, 100); + glVertex2s(sa->totrct.xmin, y + 1); + glVertex2s(sa->totrct.xmax, y + 1); + } + else { + const float x = (1 - fac) * sa->totrct.xmin + fac * sa->totrct.xmax; + glVertex2s(x, sa->totrct.ymin); + glVertex2s(x, sa->totrct.ymax); + glColor4ub(0, 0, 0, 100); + glVertex2s(x + 1, sa->totrct.ymin); + glVertex2s(x + 1, sa->totrct.ymax); + } + glEnd(); + glDisable(GL_BLEND); } /* helper call for below, dpi changes headers */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 176bdc764a2..c4be0a2259f 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1180,18 +1180,15 @@ static int area_snap_calc_location( const int m_loc = origval + delta; const int axis = (dir == 'v') ? 0 : 1; - int snap_dist = INT_MAX; + int snap_dist; 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; - } + snap_dist = abs(m_loc - middle); + final_loc = middle; } for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) { @@ -1433,6 +1430,7 @@ typedef struct sAreaSplitData { int delta; /* delta move edge */ int origmin, origsize; /* to calculate fac, for property storage */ int previewmode; /* draw previewline, then split */ + void *draw_callback; /* call `ED_screen_draw_split_preview` */ bool do_snap; ScrEdge *nedge; /* new edge */ @@ -1441,6 +1439,19 @@ typedef struct sAreaSplitData { } sAreaSplitData; +static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdata) +{ + const wmOperator *op = userdata; + + sAreaSplitData *sd = op->customdata; + if (sd->sarea) { + int dir = RNA_enum_get(op->ptr, "direction"); + float fac = RNA_float_get(op->ptr, "factor"); + + ED_screen_draw_split_preview(sd->sarea, dir, fac); + } +} + /* generic init, menu case, doesn't need active area */ static int area_split_menu_init(bContext *C, wmOperator *op) { @@ -1451,15 +1462,7 @@ static int area_split_menu_init(bContext *C, wmOperator *op) op->customdata = sd; sd->sarea = CTX_wm_area(C); - - if (sd->sarea) { - int dir = RNA_enum_get(op->ptr, "direction"); - if (dir == 'h') - sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_H; - else - sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_V; - } return 1; } @@ -1568,9 +1571,9 @@ static void area_split_exit(bContext *C, wmOperator *op) if (sd->sarea) ED_area_tag_redraw(sd->sarea); if (sd->narea) ED_area_tag_redraw(sd->narea); - if (sd->sarea) - sd->sarea->flag &= ~(AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V); - + if (sd->draw_callback) + WM_draw_cb_exit(CTX_wm_window(C), sd->draw_callback); + MEM_freeN(op->customdata); op->customdata = NULL; } @@ -1677,6 +1680,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) } else { sd->previewmode = 1; + sd->draw_callback = WM_draw_cb_activate(win, area_split_draw_cb, op); /* add temp handler for edge move or cancel */ WM_event_add_modal_handler(C, op); @@ -1734,9 +1738,7 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) if (sd->previewmode == 0) 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); } /* area context not set */ @@ -1747,22 +1749,31 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) if (dir == 'v') { sd->origsize = sd->sarea->winx; sd->origmin = sd->sarea->totrct.xmin; - sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_V; } else { sd->origsize = sd->sarea->winy; sd->origmin = sd->sarea->totrct.ymin; - sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_H; } + + if (sd->do_snap) { + ScrArea *sa = sd->sarea; + sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 1; + + int snap_loc = area_snap_calc_location( + CTX_wm_screen(C), sd->delta, sd->origval, dir, sd->origmin + sd->origsize, -sd->origmin); + + sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 0; + fac = snap_loc - sd->origmin; + } + else { + fac = (dir == 'v') ? event->x - sd->origmin : event->y - sd->origmin; + } + RNA_float_set(op->ptr, "factor", fac / (float)sd->origsize); } CTX_wm_window(C)->screen->do_draw = true; } - - fac = (dir == 'v') ? event->x - sd->origmin : event->y - sd->origmin; - RNA_float_set(op->ptr, "factor", fac / (float)sd->origsize); - break; case LEFTMOUSE: @@ -1788,19 +1799,14 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->val == KM_PRESS) { if (sd->sarea) { - sd->sarea->flag &= ~(AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V); ED_area_tag_redraw(sd->sarea); if (dir == 'v') { RNA_enum_set(op->ptr, "direction", 'h'); - sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_H; - WM_cursor_set(CTX_wm_window(C), CURSOR_X_MOVE); } else { RNA_enum_set(op->ptr, "direction", 'v'); - sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_V; - WM_cursor_set(CTX_wm_window(C), CURSOR_Y_MOVE); } } @@ -2590,13 +2596,23 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot) */ typedef struct sAreaJoinData { - ScrArea *sa1; /* first area to be considered */ - ScrArea *sa2; /* second area to be considered */ - ScrArea *scr; /* designed for removal */ + ScrArea *sa1; /* first area to be considered */ + ScrArea *sa2; /* second area to be considered */ + void *draw_callback; /* call `ED_screen_draw_join_shape` */ } sAreaJoinData; +static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata) +{ + const wmOperator *op = userdata; + + sAreaJoinData *sd = op->customdata; + if (sd->sa1 && sd->sa2) { + ED_screen_draw_join_shape(sd->sa1, sd->sa2); + } +} + /* validate selection inside screen, set variables OK */ /* return 0: init failed */ /* XXX todo: find edge based on (x,y) and set other area? */ @@ -2630,14 +2646,14 @@ static int area_join_init(bContext *C, wmOperator *op) } jd = (sAreaJoinData *)MEM_callocN(sizeof(sAreaJoinData), "op_area_join"); - + jd->sa1 = sa1; - jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM; jd->sa2 = sa2; - jd->sa2->flag |= AREA_FLAG_DRAWJOINTO; - + op->customdata = jd; - + + jd->draw_callback = WM_draw_cb_activate(CTX_wm_window(C), area_join_draw_cb, op); + return 1; } @@ -2661,8 +2677,13 @@ static int area_join_apply(bContext *C, wmOperator *op) /* finish operation */ static void area_join_exit(bContext *C, wmOperator *op) { - if (op->customdata) { - MEM_freeN(op->customdata); + sAreaJoinData *jd = (sAreaJoinData *)op->customdata; + + if (jd) { + if (jd->draw_callback) + WM_draw_cb_exit(CTX_wm_window(C), jd->draw_callback); + + MEM_freeN(jd); op->customdata = NULL; } @@ -2721,17 +2742,6 @@ static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event) static void area_join_cancel(bContext *C, wmOperator *op) { - sAreaJoinData *jd = (sAreaJoinData *)op->customdata; - - if (jd->sa1) { - jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; - jd->sa1->flag &= ~AREA_FLAG_DRAWJOINTO; - } - if (jd->sa2) { - jd->sa2->flag &= ~AREA_FLAG_DRAWJOINFROM; - jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; - } - WM_event_add_notifier(C, NC_WINDOW, NULL); area_join_exit(C, op); @@ -2755,9 +2765,7 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event) if (jd->sa1 != sa) { dir = area_getorientation(jd->sa1, sa); if (dir != -1) { - if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; jd->sa2 = sa; - jd->sa2->flag |= AREA_FLAG_DRAWJOINTO; } else { /* we are not bordering on the previously selected area @@ -2766,15 +2774,10 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event) */ dir = area_getorientation(sa, jd->sa2); if (dir != -1) { - if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; - if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; jd->sa1 = jd->sa2; jd->sa2 = sa; - if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM; - if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO; } else { - if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; jd->sa2 = NULL; } } @@ -2784,12 +2787,8 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event) /* we are back in the area previously selected for keeping * we swap the areas if possible to allow user to choose */ if (jd->sa2 != NULL) { - if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; - if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; jd->sa1 = jd->sa2; jd->sa2 = sa; - if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM; - if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO; dir = area_getorientation(jd->sa1, jd->sa2); if (dir == -1) { printf("oops, didn't expect that!\n"); @@ -2798,9 +2797,7 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event) else { dir = area_getorientation(jd->sa1, sa); if (dir != -1) { - if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; jd->sa2 = sa; - jd->sa2->flag |= AREA_FLAG_DRAWJOINTO; } } WM_event_add_notifier(C, NC_WINDOW, NULL); |