2.5/Posemode:
[blender-staging.git] / source / blender / editors / screen / screen_ops.c
index 32f09f489a6fe17e5e5610f4f9d2ea0469d3b328..9453c7ffe098916378dda89adde9e57ffdd1af49 100644 (file)
@@ -40,6 +40,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_meta_types.h"
 
 #include "BKE_blender.h"
 #include "BKE_colortools.h"
 #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"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -168,11 +171,11 @@ int ED_operator_buttons_active(bContext *C)
 
 int ED_operator_node_active(bContext *C)
 {
-       if(ed_spacetype_test(C, SPACE_NODE)) {
-               SpaceNode *snode= (SpaceNode *)CTX_wm_space_data(C);
-               if(snode->edittree)
-                       return 1;
-       }
+       SpaceNode *snode= CTX_wm_space_node(C);
+
+       if(snode && snode->edittree)
+               return 1;
+
        return 0;
 }
 
@@ -229,7 +232,7 @@ int ED_operator_posemode(bContext *C)
        Object *obedit= CTX_data_edit_object(C);
        
        if ((obact != obedit) && (obact) && (obact->type==OB_ARMATURE))
-               return (obact->flag & OB_POSEMODE)!=0;
+               return (obact->mode & OB_MODE_POSE)!=0;
                
        return 0;
 }
@@ -312,6 +315,14 @@ int ED_operator_editlattice(bContext *C)
        return 0;
 }
 
+int ED_operator_editmball(bContext *C)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       if(obedit && obedit->type==OB_MBALL)
+               return NULL != ((MetaBall *)obedit->data)->editelems;
+       return 0;
+}
+
 /* *************************** action zone operator ************************** */
 
 /* operator state vars used:  
@@ -1402,6 +1413,37 @@ static void SCREEN_OT_frame_offset(wmOperatorType *ot)
        RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
 }
 
+
+/* function to be called outside UI context, or for redo */
+static int frame_jump_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       
+       if (RNA_boolean_get(op->ptr, "end"))
+               CFRA= PEFRA;
+       else
+               CFRA= PSFRA;
+
+       WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+static void SCREEN_OT_frame_jump(wmOperatorType *ot)
+{
+       ot->name = "Jump to Endpoint";
+       ot->idname = "SCREEN_OT_frame_jump";
+
+       ot->exec= frame_jump_exec;
+
+       ot->poll= ED_operator_screenactive;
+       ot->flag= 0;
+
+       /* rna */
+       RNA_def_boolean(ot->srna, "end", 0, "Last Frame", "Jump to the last frame of the frame range.");
+}
+
+
 /* ************** jump to keyframe operator ***************************** */
 
 /* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */
@@ -2188,45 +2230,58 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event)
                
                if(scene->audio.flag & AUDIO_SYNC) {
                        int step = floor(wt->duration * FPS);
-                       if (sad->reverse) // XXX does this option work with audio?
+                       if (sad->flag & ANIMPLAY_FLAG_REVERSE) // XXX does this option work with audio?
                                scene->r.cfra -= step;
                        else
                                scene->r.cfra += step;
                        wt->duration -= ((float)step)/FPS;
                }
                else {
-                       if (sad->reverse)
+                       if (sad->flag & ANIMPLAY_FLAG_REVERSE)
                                scene->r.cfra--;
                        else
                                scene->r.cfra++;
                }
                
-               if (sad->reverse) {
-                       /* jump back to end */
+               /* reset 'jumped' flag before checking if we need to jump... */
+               sad->flag &= ~ANIMPLAY_FLAG_JUMPED;
+               
+               if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
+                       /* jump back to end? */
                        if (scene->r.psfra) {
-                               if(scene->r.cfra < scene->r.psfra)
+                               if (scene->r.cfra < scene->r.psfra) {
                                        scene->r.cfra= scene->r.pefra;
+                                       sad->flag |= ANIMPLAY_FLAG_JUMPED;
+                               }
                        }
                        else {
-                               if(scene->r.cfra < scene->r.sfra)
+                               if (scene->r.cfra < scene->r.sfra) {
                                        scene->r.cfra= scene->r.efra;
+                                       sad->flag |= ANIMPLAY_FLAG_JUMPED;
+                               }
                        }
                }
                else {
-                       /* jump back to start */
+                       /* jump back to start? */
                        if (scene->r.psfra) {
-                               if(scene->r.cfra > scene->r.pefra)
+                               if (scene->r.cfra > scene->r.pefra) {
                                        scene->r.cfra= scene->r.psfra;
+                                       sad->flag |= ANIMPLAY_FLAG_JUMPED;
+                               }
                        }
                        else {
-                               if(scene->r.cfra > scene->r.efra)
+                               if (scene->r.cfra > scene->r.efra) {
                                        scene->r.cfra= scene->r.sfra;
+                                       sad->flag |= ANIMPLAY_FLAG_JUMPED;
+                               }
                        }
                }
 
                /* since we follow drawflags, we can't send notifier but tag regions ourselves */
                ED_update_for_newframe(C, 1);
-               
+
+               sound_update_playing(C);
+
                for(sa= screen->areabase.first; sa; sa= sa->next) {
                        ARegion *ar;
                        for(ar= sa->regionbase.first; ar; ar= ar->next) {
@@ -2260,6 +2315,10 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot)
 
 /* ****************** anim player, starts or ends timer ***************** */
 
+/* helper for screen_animation_play() - only to be used for TimeLine */
+// NOTE: defined in time_header.c for now...
+extern ARegion *time_top_left_3dwindow(bScreen *screen);
+
 /* toggle operator */
 static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
 {
@@ -2267,17 +2326,35 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
        
        if(screen->animtimer) {
                ED_screen_animation_timer(C, 0, 0);
+               sound_stop_all(C);
        }
        else {
+               ScrArea *sa= CTX_wm_area(C);
                int mode= (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
                
-               ED_screen_animation_timer(C, TIME_REGION|TIME_ALL_3D_WIN, mode);
-               
-               if(screen->animtimer) {
-                       wmTimer *wt= screen->animtimer;
-                       ScreenAnimData *sad= wt->customdata;
+               /* timeline gets special treatment since it has it's own menu for determining redraws */
+               if ((sa) && (sa->spacetype == SPACE_TIME)) {
+                       SpaceTime *stime= (SpaceTime *)sa->spacedata.first;
+                       
+                       ED_screen_animation_timer(C, stime->redraws, mode);
                        
-                       sad->ar= CTX_wm_region(C);
+                       /* update region if TIME_REGION was set, to leftmost 3d window */
+                       if(screen->animtimer && (stime->redraws & TIME_REGION)) {
+                               wmTimer *wt= screen->animtimer;
+                               ScreenAnimData *sad= wt->customdata;
+                               
+                               sad->ar= time_top_left_3dwindow(screen);
+                       }
+               }
+               else {
+                       ED_screen_animation_timer(C, TIME_REGION|TIME_ALL_3D_WIN, mode);
+                       
+                       if(screen->animtimer) {
+                               wmTimer *wt= screen->animtimer;
+                               ScreenAnimData *sad= wt->customdata;
+                               
+                               sad->ar= CTX_wm_region(C);
+                       }
                }
        }
        
@@ -3011,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 **************** */
 
@@ -3042,6 +3236,7 @@ void ED_operatortypes_screen(void)
        
        /*frame changes*/
        WM_operatortype_append(SCREEN_OT_frame_offset);
+       WM_operatortype_append(SCREEN_OT_frame_jump);
        WM_operatortype_append(SCREEN_OT_keyframe_jump);
        
        WM_operatortype_append(SCREEN_OT_animation_step);
@@ -3052,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);     
@@ -3111,7 +3312,6 @@ void ED_keymap_screen(wmWindowManager *wm)
        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);
        WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", DOWNARROWKEY, KM_PRESS, KM_CTRL, 0);
-       WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0);
 
@@ -3155,6 +3355,9 @@ void ED_keymap_screen(wmWindowManager *wm)
        RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -1);
        RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
        
+       WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0);
+       RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 1);
+       
        WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", PAGEUPKEY, KM_PRESS, KM_CTRL, 0);
        RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", PAGEDOWNKEY, KM_PRESS, KM_CTRL, 0)->ptr, "next", 0);