diff options
-rw-r--r-- | source/blender/blenkernel/BKE_screen.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/screen.c | 21 | ||||
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 1 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 47 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 141 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_cursors.c | 32 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_cursors.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_window.h | 2 |
8 files changed, 225 insertions, 21 deletions
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 250aaf7245a..302f7b4fdd9 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -139,6 +139,7 @@ void BKE_spacetypes_free(void); /* only for quitting blender */ /* spacedata */ void BKE_spacedata_freelist(ListBase *lb); void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2); +void BKE_spacedata_copyfirst(ListBase *lb1, ListBase *lb2); /* area/regions */ struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 063c617e6bb..4232d1f7e52 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -214,6 +214,27 @@ void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2) } } +/* lb1 should be empty */ +void BKE_spacedata_copyfirst(ListBase *lb1, ListBase *lb2) +{ + SpaceLink *sl; + + lb1->first= lb2->last= NULL; /* to be sure */ + + sl= lb2->first; + if(sl) { + SpaceType *st= BKE_spacetype_from_id(sl->spacetype); + + if(st && st->duplicate) { + SpaceLink *slnew= st->duplicate(sl); + + BLI_addtail(lb1, slnew); + + region_copylist(st, &slnew->regionbase, &sl->regionbase); + } + } +} + /* not region itself */ void BKE_area_region_free(SpaceType *st, ARegion *ar) { diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 0433bf3f235..847120a5804 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -73,6 +73,7 @@ void ED_area_do_refresh(struct bContext *C, ScrArea *sa); void ED_area_headerprint(ScrArea *sa, const char *str); void ED_area_newspace(struct bContext *C, ScrArea *sa, int type); void ED_area_prevspace(struct bContext *C); +void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2); /* screens */ void ED_screens_initialize(struct wmWindowManager *wm); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index be9c76111db..6dde367ff1b 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -660,12 +660,15 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) sa1->spacetype= sa2->spacetype; sa1->butspacetype= sa2->butspacetype; - if(swap_space) { + if(swap_space == 1) { SWAP(ListBase, sa1->spacedata, sa2->spacedata); /* exception: ensure preview is reset */ // if(sa1->spacetype==SPACE_VIEW3D) // XXX BIF_view3d_previewrender_free(sa1->spacedata.first); } + else if (swap_space == 2) { + BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata); + } else { BKE_spacedata_freelist(&sa1->spacedata); BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata); @@ -674,10 +677,12 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) /* Note; SPACE_EMPTY is possible on new screens */ /* regions */ - st= BKE_spacetype_from_id(sa1->spacetype); - for(ar= sa1->regionbase.first; ar; ar= ar->next) - BKE_area_region_free(st, ar); - BLI_freelistN(&sa1->regionbase); + if(swap_space<2) { + st= BKE_spacetype_from_id(sa1->spacetype); + for(ar= sa1->regionbase.first; ar; ar= ar->next) + BKE_area_region_free(st, ar); + BLI_freelistN(&sa1->regionbase); + } st= BKE_spacetype_from_id(sa2->spacetype); for(ar= sa2->regionbase.first; ar; ar= ar->next) { @@ -695,6 +700,38 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) /* *********** Space switching code *********** */ +void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) +{ + SpaceType *st; + SpaceLink *sl; + SpaceLink *slold; + ScrArea *tmp= MEM_callocN(sizeof(ScrArea), "addscrarea"); + + ED_area_exit(C, sa1); + ED_area_exit(C, sa2); + + tmp->spacetype= sa1->spacetype; + tmp->butspacetype= sa1->butspacetype; + BKE_spacedata_copyfirst(&tmp->spacedata, &sa1->spacedata); + + area_copy_data(tmp, sa1, 2); + area_copy_data(sa1, sa2, 0); + area_copy_data(sa2, tmp, 0); + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa1); + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa2); + + BKE_screen_area_free(tmp); + MEM_freeN(tmp); + + /* tell WM to refresh, cursor types etc */ + WM_event_add_mousemove(C); + + ED_area_tag_redraw(sa1); + ED_area_tag_refresh(sa1); + ED_area_tag_redraw(sa2); + ED_area_tag_refresh(sa2); +} + void ED_area_newspace(bContext *C, ScrArea *sa, int type) { if(sa->spacetype != type) { diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 8bc6cb6e567..49bbf6506a7 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -438,14 +438,122 @@ void SCREEN_OT_actionzone(wmOperatorType *ot) RNA_def_int(ot->srna, "modifier", 0, 0, 2, "modifier", "modifier state", 0, 2); } +/* ************** swap area operator *********************************** */ -/* *********** Duplicate area as new window operator ****************** */ +/* operator state vars used: + sa1 start area + sa2 area to swap with + + functions: + + init() set custom data for operator, based on actionzone event custom data + + cancel() cancel the operator + + exit() cleanup, send notifier + + callbacks: + + invoke() gets called on shift+lmb drag in actionzone + call init(), add handler + + modal() accept modal events while doing it + +*/ + +typedef struct sAreaSwapData { + ScrArea *sa1, *sa2; +} sAreaSwapData; + +static int area_swap_init(bContext *C, wmOperator *op, wmEvent *event) +{ + sAreaSwapData *sd= NULL; + sActionzoneData *sad= event->customdata; + if(sad==NULL || sad->sa1==NULL) + return 0; + + sd= MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData"); + sd->sa1= sad->sa1; + sd->sa2= sad->sa2; + op->customdata= sd; + + return 1; +} + + +static void area_swap_exit(bContext *C, wmOperator *op) +{ + if(op->customdata) + MEM_freeN(op->customdata); + op->customdata= NULL; +} + +static int area_swap_cancel(bContext *C, wmOperator *op) +{ + area_swap_exit(C, op); + return OPERATOR_CANCELLED; +} + +static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + + if(!area_swap_init(C, op, event)) + return OPERATOR_PASS_THROUGH; + + /* add modal handler */ + WM_cursor_modal(CTX_wm_window(C), BC_SWAPAREA_CURSOR); + WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + + return OPERATOR_RUNNING_MODAL; + +} + +static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + sActionzoneData *sad= op->customdata; + + switch(event->type) { + case MOUSEMOVE: + /* second area, for join */ + sad->sa2= screen_areahascursor(CTX_wm_screen(C), event->x, event->y); + break; + case LEFTMOUSE: /* release LMB */ + if(event->val==0) { + if(sad->sa1 == sad->sa2) { + + return area_swap_cancel(C, op); + } + ED_area_swapspace(C, sad->sa1, sad->sa2); + + area_swap_exit(C, op); + + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); + + return OPERATOR_FINISHED; + } + break; + + case ESCKEY: + return area_swap_cancel(C, op); + } + return OPERATOR_RUNNING_MODAL; +} + +void SCREEN_OT_area_swap(wmOperatorType *ot) +{ + ot->name= "Swap areas"; + ot->idname= "SCREEN_OT_area_swap"; + + ot->invoke= area_swap_invoke; + ot->modal= area_swap_modal; + ot->poll= ED_operator_areaactive; +} + +/* *********** Duplicate area as new window operator ****************** */ /* operator callback */ -/* (ton) removed attempt to merge ripped area with another, don't think this is desired functionality. -conventions: 'atomic' and 'dont think for user' :) */ -static int screen_area_dupli_new_op(bContext *C, wmOperator *op, wmEvent *event) +static int area_dupli_invoke(bContext *C, wmOperator *op, wmEvent *event) { wmWindow *newwin, *win; bScreen *newsc, *sc; @@ -454,15 +562,17 @@ static int screen_area_dupli_new_op(bContext *C, wmOperator *op, wmEvent *event) sActionzoneData *sad= event->customdata; if(sad==NULL) - return OPERATOR_CANCELLED; + return OPERATOR_PASS_THROUGH; win= CTX_wm_window(C); sc= CTX_wm_screen(C); sa= sad->sa1; /* poll() checks area context, but we don't accept full-area windows */ - if(sc->full != SCREENNORMAL) + if(sc->full != SCREENNORMAL) { + actionzone_exit(C, op); return OPERATOR_CANCELLED; + } /* adds window to WM */ rect= sa->totrct; @@ -478,16 +588,18 @@ static int screen_area_dupli_new_op(bContext *C, wmOperator *op, wmEvent *event) /* screen, areas init */ WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); + + actionzone_exit(C, op); return OPERATOR_FINISHED; } -void SCREEN_OT_area_dupli_new(wmOperatorType *ot) +void SCREEN_OT_area_dupli(wmOperatorType *ot) { ot->name= "Duplicate Area into New Window"; - ot->idname= "SCREEN_OT_area_dupli_new"; + ot->idname= "SCREEN_OT_area_dupli"; - ot->invoke= screen_area_dupli_new_op; + ot->invoke= area_dupli_invoke; ot->poll= ED_operator_areaactive; } @@ -2308,7 +2420,8 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_area_move); WM_operatortype_append(SCREEN_OT_area_split); WM_operatortype_append(SCREEN_OT_area_join); - WM_operatortype_append(SCREEN_OT_area_dupli_new); + WM_operatortype_append(SCREEN_OT_area_dupli); + WM_operatortype_append(SCREEN_OT_area_swap); WM_operatortype_append(SCREEN_OT_region_split); WM_operatortype_append(SCREEN_OT_region_foursplit); WM_operatortype_append(SCREEN_OT_region_flip); @@ -2339,16 +2452,16 @@ void ED_keymap_screen(wmWindowManager *wm) /* standard timers */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", TIMER0, KM_ANY, KM_ANY, 0); - /*WM_keymap_verify_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0);*/ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "modifier", 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "modifier", 1); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "modifier", 2); /* screen tools */ WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE, 0, KM_ANY, 0); - WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE, 0, KM_ANY, 0); - WM_keymap_verify_item(keymap, "SCREEN_OT_area_dupli_new", EVT_ACTIONZONE, 0, KM_ANY, 0); + WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE, 0, 0, 0); + WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE, 0, 0, 0); + WM_keymap_verify_item(keymap, "SCREEN_OT_area_dupli", EVT_ACTIONZONE, 0, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "SCREEN_OT_area_swap", EVT_ACTIONZONE, 0, KM_ALT, 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1); WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", UPARROWKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index d1c268a1189..2c7493a51ab 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -935,6 +935,38 @@ BlenderCursor[BC_EYEDROPPER_CURSOR]=&EyedropperCursor; END_CURSOR_BLOCK +/********************** Swap Area Cursor ***********************/ +BEGIN_CURSOR_BLOCK +static char swap_sbm[]={ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0xff, 0x07, + 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, + 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, +}; + +static char swap_smsk[]={ + 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff, + 0xc0, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x07, + 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, +}; + +static BCursor SwapCursor = { + /*small*/ + swap_sbm, swap_smsk, + 16, 16, + 8, 8, + /*big*/ + NULL, NULL, + 32,32, + 15, 15, + /*color*/ + BC_YELLOW, BC_BLUE +}; + +BlenderCursor[BC_SWAPAREA_CURSOR]=&SwapCursor; + +END_CURSOR_BLOCK /********************** Put the cursors in the array ***********************/ diff --git a/source/blender/windowmanager/wm_cursors.h b/source/blender/windowmanager/wm_cursors.h index 096e1916fa9..1a1a0d0b71d 100644 --- a/source/blender/windowmanager/wm_cursors.h +++ b/source/blender/windowmanager/wm_cursors.h @@ -92,6 +92,7 @@ enum { BC_NS_SCROLLCURSOR, BC_EW_SCROLLCURSOR, BC_EYEDROPPER_CURSOR, + BC_SWAPAREA_CURSOR, /* --- ALWAYS LAST ----- */ BC_NUMCURSORS, }; diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index f386510a2eb..7bf08617fb6 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -52,13 +52,11 @@ void wm_window_set_title (wmWindow *win, char *title); void wm_window_swap_buffers (wmWindow *win); wmWindow *wm_window_copy (bContext *C, wmWindow *winorig); -wmWindow *wm_window_rip (bContext *C, wmWindow *winorig); void wm_window_testbreak (void); /* *************** window operators ************** */ int wm_window_duplicate_op (bContext *C, wmOperator *op); -int wm_window_rip_op (bContext *C, wmOperator *op, struct wmEvent *event); int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op); |