diff options
author | Nathan Letwory <nathan@letworyinteractive.com> | 2009-03-11 23:22:06 +0300 |
---|---|---|
committer | Nathan Letwory <nathan@letworyinteractive.com> | 2009-03-11 23:22:06 +0300 |
commit | c8583cac700329659487edd96a1b2f0c6b1af39e (patch) | |
tree | e1aa726106a0cd6262b95d0f148051bc9b038235 /source/blender/editors | |
parent | 64512d3e8e9f950b8249deb506eb243345dc107e (diff) |
2.5 / Area management
* Add Area Swap: hold alt and drag with LMB from either actionzone. Release LMB on area you want to swap with. I added a matching cute cursor for this (and to make it a politically delicate issue, it's white on black).
Note, there are still some error totblocks that I haven't been able to track down properly yet, so that's still a bit WIP.
Diffstat (limited to 'source/blender/editors')
-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 |
3 files changed, 170 insertions, 19 deletions
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); |