diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index dcdc9e417e4..d933e2cfdaa 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -32,8 +32,9 @@ /* for animplayer */ typedef struct ScreenAnimData { ARegion *ar; /* do not read from this, only for comparing if region exists */ - int redraws; - int flag; /* flags for playback */ + short redraws; + short flag; /* flags for playback */ + int sfra; /* frame that playback was started from */ } ScreenAnimData; /* for animplayer */ diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index acf5bcd739e..c158901c15d 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1556,10 +1556,11 @@ void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable) screen->animtimer= NULL; if(enable) { - struct ScreenAnimData *sad= MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData"); + ScreenAnimData *sad= MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData"); screen->animtimer= WM_event_add_timer(wm, win, TIMER0, (1.0/FPS)); sad->ar= CTX_wm_region(C); + sad->sfra = scene->r.cfra; sad->redraws= redraws; sad->flag |= (enable < 0)? ANIMPLAY_FLAG_REVERSE: 0; sad->flag |= (sync == 0)? ANIMPLAY_FLAG_NO_SYNC: (sync == 1)? ANIMPLAY_FLAG_SYNC: 0; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 4712d1c5533..73ad07453c5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2263,8 +2263,6 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) // TODO: this may make evaluation a bit slower if the value doesn't change... any way to avoid this? wt->timestep= (1.0/FPS); - //WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); - return OPERATOR_FINISHED; } return OPERATOR_PASS_THROUGH; @@ -2292,6 +2290,7 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event) bScreen *screen= CTX_wm_screen(C); if(screen->animtimer) { + /* stop playback now */ ED_screen_animation_timer(C, 0, 0, 0); sound_stop_all(C); } @@ -2354,8 +2353,19 @@ static int screen_animation_cancel(bContext *C, wmOperator *op, wmEvent *event) { bScreen *screen= CTX_wm_screen(C); - if(screen->animtimer) + if(screen->animtimer) { + ScreenAnimData *sad= screen->animtimer->customdata; + Scene *scene= CTX_data_scene(C); + + /* reset current frame before stopping, and just send a notifier to deal with the rest + * (since playback still needs to be stopped) + */ + scene->r.cfra= sad->sfra; + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); + + /* call the other "toggling" operator to clean up now */ return screen_animation_play(C, op, event); + } return OPERATOR_PASS_THROUGH; } @@ -2364,7 +2374,7 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot) { /* identifiers */ ot->name= "Cancel Animation"; - ot->description= "Cancel animation."; + ot->description= "Cancel animation, returning to the original frame."; ot->idname= "SCREEN_OT_animation_cancel"; /* api callbacks */