diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-08-15 20:43:03 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-08-15 20:43:03 +0400 |
commit | 9059639df40f2aed918d0005e3e96cc13a8d3d4f (patch) | |
tree | b74f9a1115573307aeb14c81baa9d4be14c8f506 /source/blender/editors/screen | |
parent | 314b14301fd565b93bbb75697c29b109eacf813d (diff) |
2.5: Screen/Scene New/Delete operators.
Implementation Note:
* Moved the scene copy/unlink code back into blenkernel, with
the exception of the copy single user stuff which is still in
object_edit.c.
* Uses SCREENDELETE notifier like SCREENBROWSE, seems only clean
way to do this now.
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 67 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 124 |
2 files changed, 185 insertions, 6 deletions
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 5519b2609a1..b6c2ece1a02 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -923,12 +923,6 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc) newsc= ED_screen_add(win, sc->scene, sc->id.name+2); /* copy all data */ screen_copy(newsc, sc); - /* set in window */ - win->screen= newsc; - - /* store identifier */ - win->screen->winid= win->winid; - BLI_strncpy(win->screenname, win->screen->id.name+2, 21); return newsc; } @@ -1289,6 +1283,49 @@ void ED_screen_set(bContext *C, bScreen *sc) } } +static int ed_screen_used(wmWindowManager *wm, bScreen *sc) +{ + wmWindow *win; + + for(win=wm->windows.first; win; win=win->next) + if(win->screen == sc) + return 1; + + return 0; +} + +/* only call outside of area/region loops */ +void ED_screen_delete(bContext *C, bScreen *sc) +{ + Main *bmain= CTX_data_main(C); + wmWindowManager *wm= CTX_wm_manager(C); + wmWindow *win= CTX_wm_window(C); + bScreen *newsc; + int delete= 1; + + /* screen can only be in use by one window at a time, so as + long as we are able to find a screen that is unused, we + can safely assume ours is not in use anywhere an delete it */ + + for(newsc= sc->id.prev; newsc; newsc=newsc->id.prev) + if(!ed_screen_used(wm, newsc)) + break; + + if(!newsc) { + for(newsc= sc->id.next; newsc; newsc=newsc->id.next) + if(!ed_screen_used(wm, newsc)) + break; + } + + if(!newsc) + return; + + ED_screen_set(C, newsc); + + if(delete && win->screen != sc) + free_libblock(&bmain->screen, sc); +} + /* only call outside of area/region loops */ void ED_screen_set_scene(bContext *C, Scene *scene) { @@ -1346,6 +1383,24 @@ void ED_screen_set_scene(bContext *C, Scene *scene) } +/* only call outside of area/region loops */ +void ED_screen_delete_scene(bContext *C, Scene *scene) +{ + Main *bmain= CTX_data_main(C); + Scene *newscene; + + if(scene->id.prev) + newscene= scene->id.prev; + else if(scene->id.next) + newscene= scene->id.next; + else + return; + + ED_screen_set_scene(C, newscene); + + unlink_scene(bmain, scene, newscene); +} + /* this function toggles: if area is full then the parent will be restored */ void ed_screen_fullarea(bContext *C, ScrArea *sa) { diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index f882a25c363..b8980d86fdc 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -54,6 +54,7 @@ #include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_report.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_utildefines.h" #include "BKE_sound.h" @@ -3087,7 +3088,124 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot) ot->poll= ED_operator_screenactive; } +/********************* new screen operator *********************/ +static int screen_new_exec(bContext *C, wmOperator *op) +{ + wmWindow *win= CTX_wm_window(C); + bScreen *sc= CTX_wm_screen(C); + + sc= ED_screen_duplicate(win, sc); + WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, sc); + + return OPERATOR_FINISHED; +} + +void SCREEN_OT_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New Screen"; + ot->idname= "SCREEN_OT_new"; + + /* api callbacks */ + ot->exec= screen_new_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************* delete screen operator *********************/ + +static int screen_delete_exec(bContext *C, wmOperator *op) +{ + bScreen *sc= CTX_wm_screen(C); + + WM_event_add_notifier(C, NC_SCREEN|ND_SCREENDELETE, sc); + + return OPERATOR_FINISHED; +} + +void SCREEN_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Scene"; + ot->idname= "SCREEN_OT_delete"; + + /* api callbacks */ + ot->exec= screen_delete_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************* new scene operator *********************/ + +static int scene_new_exec(bContext *C, wmOperator *op) +{ + Scene *newscene, *scene= CTX_data_scene(C); + Main *bmain= CTX_data_main(C); + int type= RNA_enum_get(op->ptr, "type"); + + newscene= copy_scene(bmain, scene, type); + + /* these can't be handled in blenkernel curently, so do them here */ + if(type == SCE_COPY_LINK_DATA) + ED_object_single_users(newscene, 0); + else if(type == SCE_COPY_FULL) + ED_object_single_users(newscene, 1); + + WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_new(wmOperatorType *ot) +{ + static EnumPropertyItem type_items[]= { + {SCE_COPY_EMPTY, "EMPTY", 0, "Empty", "Add empty scene."}, + {SCE_COPY_LINK_OB, "LINK_OBJECTS", 0, "Link Objects", "Link to the objects from the current scene."}, + {SCE_COPY_LINK_DATA, "LINK_OBJECT_DATA", 0, "Link Object Data", "Copy objects linked to data from the current scene."}, + {SCE_COPY_FULL, "FULL_COPY", 0, "Full Copy", "Make a full copy of the current scene."}, + {0, NULL, 0, NULL, NULL}}; + + /* identifiers */ + ot->name= "New Scene"; + ot->idname= "SCENE_OT_new"; + + /* api callbacks */ + ot->exec= scene_new_exec; + ot->invoke= WM_menu_invoke; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", type_items, 0, "Type", ""); +} + +/********************* delete scene operator *********************/ + +static int scene_delete_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + WM_event_add_notifier(C, NC_SCENE|ND_SCENEDELETE, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Scene"; + ot->idname= "SCENE_OT_delete"; + + /* api callbacks */ + ot->exec= scene_delete_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} /* **************** Assigning operatortypes to global list, adding handlers **************** */ @@ -3129,6 +3247,12 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_render_view_cancel); WM_operatortype_append(SCREEN_OT_render_view_show); + /* new/delete */ + WM_operatortype_append(SCREEN_OT_new); + WM_operatortype_append(SCREEN_OT_delete); + WM_operatortype_append(SCENE_OT_new); + WM_operatortype_append(SCENE_OT_delete); + /* tools shared by more space types */ WM_operatortype_append(ED_OT_undo); WM_operatortype_append(ED_OT_redo); |