Add active region for operator execution.

This means you can for example, uv unwrap in quad-view and change settings in the toolbar without defaulting back to the first quad-view region available. 

This may be displayed to the user later, for now this is set on executing registrable operators.
This commit is contained in:
Campbell Barton
2013-01-30 12:22:02 +00:00
parent c8015a2788
commit 54223ed05b
9 changed files with 65 additions and 19 deletions

View File

@@ -261,6 +261,7 @@ void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
void BKE_screen_area_free(struct ScrArea *sa);
struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type);
struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa);
struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype, const short min);
void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene);

View File

@@ -355,6 +355,20 @@ ARegion *BKE_area_find_region_type(ScrArea *sa, int type)
return NULL;
}
ARegion *BKE_area_find_region_active_win(ScrArea *sa)
{
if (sa) {
ARegion *ar = BLI_findlink(&sa->regionbase, sa->region_active_win);
if (ar && (ar->regiontype == RGN_TYPE_WINDOW)) {
return ar;
}
/* fallback to any */
return BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
}
return NULL;
}
/* note, using this function is generally a last resort, you really want to be
* using the context when you can - campbell
* -1 for any type */

View File

@@ -6005,6 +6005,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sa->handlers.first = sa->handlers.last = NULL;
sa->type = NULL; /* spacetype callbacks */
sa->region_active_win = -1;
for (ar = sa->regionbase.first; ar; ar = ar->next)
direct_link_region(fd, ar, sa->spacetype);

View File

@@ -146,7 +146,7 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C)
if (rv3d == NULL) {
ScrArea *sa = CTX_wm_area(C);
if (sa && sa->spacetype == SPACE_VIEW3D) {
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
ARegion *ar = BKE_area_find_region_active_win(sa);
if (ar) {
rv3d = ar->regiondata;
}

View File

@@ -110,7 +110,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
/* keep in sync with logic in ED_undo_operator_repeat() */
ar = CTX_wm_region(C);
ar1 = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW);
ar1 = BKE_area_find_region_active_win(CTX_wm_area(C));
if (ar1)
CTX_wm_region_set((bContext *)C, ar1);

View File

@@ -341,7 +341,7 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
/* keep in sync with logic in view3d_panel_operator_redo() */
ARegion *ar = CTX_wm_region(C);
ARegion *ar1 = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW);
ARegion *ar1 = BKE_area_find_region_active_win(CTX_wm_area(C));
if (ar1)
CTX_wm_region_set(C, ar1);

View File

@@ -142,9 +142,10 @@ typedef struct ScrArea {
short winx, winy; /* size */
short headertype; /* OLD! 0=no header, 1= down, 2= up */
short pad;
short do_refresh; /* private, for spacetype refresh callback */
short cursor, flag;
short region_active_win; /* index of last used region of 'RGN_TYPE_WINDOW'
* runtuime variable, updated by executing operators */
struct SpaceType *type; /* callbacks for this space type */

View File

@@ -311,6 +311,8 @@ void WM_event_fileselect_event(struct bContext *C, void *ophandle, int eventval
void WM_event_print(struct wmEvent *event);
#endif
void WM_operator_region_active_win_set(struct bContext *C);
/* drag and drop */
struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value);
void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy);

View File

@@ -453,6 +453,22 @@ static void wm_operator_print(bContext *C, wmOperator *op)
MEM_freeN(buf);
}
/**
* Sets the active region for this space from the context.
*
* \see #BKE_area_find_region_active_win
*/
void WM_operator_region_active_win_set(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
if (sa) {
ARegion *ar = CTX_wm_region(C);
if (ar && ar->regiontype == RGN_TYPE_WINDOW) {
sa->region_active_win = BLI_findindex(&sa->regionbase, ar);
}
}
}
/* for debugging only, getting inspecting events manually is tedious */
#ifndef NDEBUG
@@ -573,10 +589,13 @@ static void wm_operator_finished(bContext *C, wmOperator *op, int repeat)
MEM_freeN(buf);
}
if (wm_operator_register_check(wm, op->type))
if (wm_operator_register_check(wm, op->type)) {
wm_operator_register(C, op);
else
WM_operator_region_active_win_set(C);
}
else {
WM_operator_free(op);
}
}
}
@@ -1045,7 +1064,14 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA
}
if (!(ar && ar->regiontype == type) && area) {
ARegion *ar1 = BKE_area_find_region_type(area, type);
ARegion *ar1;
if (type == RGN_TYPE_WINDOW) {
ar1 = BKE_area_find_region_active_win(area);
}
else {
ar1 = BKE_area_find_region_type(area, type);
}
if (ar1)
CTX_wm_region_set(C, ar1);
}
@@ -1417,6 +1443,19 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
if (ot->flag & OPTYPE_UNDO)
wm->op_undo_depth--;
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED))
wm_operator_reports(C, op, retval, FALSE);
/* important to run 'wm_operator_finished' before NULLing the context members */
if (retval & OPERATOR_FINISHED) {
wm_operator_finished(C, op, 0);
handler->op = NULL;
}
else if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
WM_operator_free(op);
handler->op = NULL;
}
/* putting back screen context, reval can pass trough after modal failures! */
if ((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
CTX_wm_area_set(C, area);
@@ -1428,18 +1467,6 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
CTX_wm_region_set(C, NULL);
}
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED))
wm_operator_reports(C, op, retval, FALSE);
if (retval & OPERATOR_FINISHED) {
wm_operator_finished(C, op, 0);
handler->op = NULL;
}
else if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
WM_operator_free(op);
handler->op = NULL;
}
/* remove modal handler, operator itself should have been canceled and freed */
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
WM_cursor_grab_disable(CTX_wm_window(C), NULL);