diff options
author | Ton Roosendaal <ton@blender.org> | 2009-05-21 17:33:04 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-05-21 17:33:04 +0400 |
commit | 99cb9a26b0b217d2e36938983809337abce67835 (patch) | |
tree | 950abb5dc5390ce6127e1bfa0a828680fbdafcc0 /source | |
parent | 8013f6522e6b3d19d92bc14a50d18db3dd99b6d6 (diff) |
2.5
Animation playback back in control. And non-blocking still!
- Play follows the "Playback" options in TimeLine menu.
Only the region 'windows' are drawn, not headers, toolbars,
channel views, etc.
The option "Buttons Window" also redraws property regions.
- The Timeline header always redraws, this to denote at least
progressing frame numbers
- For now: if you choose to play 3D views, it also redraws
the TimeLine. Seems to be good convention, but probably
better to add menu option for it?
- Fun test: while playback, change Playback options, works OK!
- New: top header button shows animation play status, and allows
to stop playback
- New: Animation stop/start operator. Assigned to ALT+A. It has
no options yet; just plays active region + all 3D windows now.
Options will follow, based on reviews.
Also ESC won't work for now, just press ALT+A again.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 2 | ||||
-rw-r--r-- | source/blender/editors/include/ED_screen_types.h | 7 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 14 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 115 | ||||
-rw-r--r-- | source/blender/editors/space_info/info_header.c | 12 | ||||
-rw-r--r-- | source/blender/editors/space_info/space_info.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_time/space_time.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_time/time_header.c | 58 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 8 |
11 files changed, 206 insertions, 24 deletions
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 2484b558b04..c2beb34e7b5 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -89,7 +89,7 @@ void ED_screen_set(struct bContext *C, struct bScreen *sc); void ED_screen_set_scene(struct bContext *C, struct Scene *scene); void ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event); void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen); -void ED_screen_animation_timer(struct bContext *C, int enable); +void ED_screen_animation_timer(struct bContext *C, int redraws, int enable); int ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type); void ED_screen_full_prevspace(struct bContext *C); diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index 7910351f318..5a13e944d5c 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -29,6 +29,13 @@ #ifndef ED_SCREEN_TYPES_H__ #define ED_SCREEN_TYPES_H__ +/* for animplayer */ +typedef struct ScreenAnimData { + ARegion *ar; /* do not read from this, only for comparing if region exists */ + int redraws; +} ScreenAnimData; + + typedef struct AZone { struct AZone *next, *prev; int type; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 51515f18623..a5950b97f61 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1430,7 +1430,8 @@ void ED_screen_full_prevspace(bContext *C) ed_screen_fullarea(C, sa); } -void ED_screen_animation_timer(bContext *C, int enable) +/* redraws: uses defines from stime->redraws */ +void ED_screen_animation_timer(bContext *C, int redraws, int enable) { bScreen *screen= CTX_wm_screen(C); wmWindow *win= CTX_wm_window(C); @@ -1440,8 +1441,17 @@ void ED_screen_animation_timer(bContext *C, int enable) WM_event_remove_window_timer(win, screen->animtimer); screen->animtimer= NULL; - if(enable) + if(enable) { + struct ScreenAnimData *sad= MEM_mallocN(sizeof(ScreenAnimData), "ScreenAnimData"); + screen->animtimer= WM_event_add_window_timer(win, TIMER0, (1.0/FPS)); + sad->ar= CTX_wm_region(C); + sad->redraws= redraws; + screen->animtimer->customdata= sad; + + } + /* notifier catched by top header, for button */ + WM_event_add_notifier(C, NC_SCREEN|ND_ANIMPLAY, screen); } unsigned int ED_screen_view3d_layers(bScreen *screen) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7ada548927f..c991a63e762 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1859,17 +1859,65 @@ void SCREEN_OT_region_flip(wmOperatorType *ot) } -/* ****************** anim player, typically with timer ***************** */ +/* ****************** anim player, with timer ***************** */ -static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event) +static int match_region_with_redraws(int spacetype, int regiontype, int redraws) +{ + if(regiontype==RGN_TYPE_WINDOW) { + + switch (spacetype) { + case SPACE_VIEW3D: + if(redraws & TIME_ALL_3D_WIN) + return 1; + break; + case SPACE_IPO: + case SPACE_ACTION: + case SPACE_NLA: + if(redraws & TIME_ALL_ANIM_WIN) + return 1; + break; + case SPACE_TIME: + /* if only 1 window or 3d windows, we do timeline too */ + if(redraws & (TIME_ALL_ANIM_WIN|TIME_REGION|TIME_ALL_3D_WIN)) + return 1; + break; + case SPACE_BUTS: + if(redraws & TIME_ALL_BUTS_WIN) + return 1; + break; + case SPACE_SEQ: + if(redraws & (TIME_SEQ|TIME_ALL_ANIM_WIN)) + return 1; + break; + case SPACE_IMAGE: + if(redraws & TIME_ALL_IMAGE_WIN) + return 1; + break; + + } + } + else if(regiontype==RGN_TYPE_UI) { + if(redraws & TIME_ALL_BUTS_WIN) + return 1; + } + else if(regiontype==RGN_TYPE_HEADER) { + if(spacetype==SPACE_TIME) + return 1; + } + return 0; +} + +static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) { bScreen *screen= CTX_wm_screen(C); if(screen->animtimer==event->customdata) { Scene *scene= CTX_data_scene(C); + wmTimer *wt= screen->animtimer; + ScreenAnimData *sad= wt->customdata; + ScrArea *sa; if(scene->audio.flag & AUDIO_SYNC) { - wmTimer *wt= screen->animtimer; int step = floor(wt->duration * FPS); scene->r.cfra += step; wt->duration -= ((float)step)/FPS; @@ -1886,13 +1934,65 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event) scene->r.cfra= scene->r.sfra; } - WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); + /* since we follow drawflags, we can't send notifier but tag regions ourselves */ + ED_update_for_newframe(C, 1); + + for(sa= screen->areabase.first; sa; sa= sa->next) { + ARegion *ar; + for(ar= sa->regionbase.first; ar; ar= ar->next) { + if(ar==sad->ar) + ED_region_tag_redraw(ar); + else + if(match_region_with_redraws(sa->spacetype, ar->regiontype, sad->redraws)) + ED_region_tag_redraw(ar); + } + } + + //WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); return OPERATOR_FINISHED; } return OPERATOR_PASS_THROUGH; } +static void SCREEN_OT_animation_step(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Animation Step"; + ot->idname= "SCREEN_OT_animation_step"; + + /* api callbacks */ + ot->invoke= screen_animation_step; + + ot->poll= ED_operator_screenactive; + +} + +/* ****************** anim player, starts or ends timer ***************** */ + +/* toggle operator */ +static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event) +{ + bScreen *screen= CTX_wm_screen(C); + + if(screen->animtimer) { + ED_screen_animation_timer(C, 0, 0); + } + else { + /* todo: RNA properties to define play types */ + ED_screen_animation_timer(C, TIME_REGION|TIME_ALL_3D_WIN, 1); + + if(screen->animtimer) { + wmTimer *wt= screen->animtimer; + ScreenAnimData *sad= wt->customdata; + + sad->ar= CTX_wm_region(C); + } + } + + return OPERATOR_FINISHED; +} + void SCREEN_OT_animation_play(wmOperatorType *ot) { /* identifiers */ @@ -1904,6 +2004,7 @@ void SCREEN_OT_animation_play(wmOperatorType *ot) ot->poll= ED_operator_screenactive; + } /* ************** border select operator (template) ***************************** */ @@ -2400,6 +2501,7 @@ void ED_operatortypes_screen(void) /*frame changes*/ WM_operatortype_append(SCREEN_OT_frame_offset); + WM_operatortype_append(SCREEN_OT_animation_step); WM_operatortype_append(SCREEN_OT_animation_play); /* render */ @@ -2418,7 +2520,7 @@ void ED_keymap_screen(wmWindowManager *wm) ListBase *keymap= WM_keymap_listbase(wm, "Screen", 0, 0); /* standard timers */ - WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", TIMER0, KM_ANY, KM_ANY, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 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); @@ -2464,12 +2566,13 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCREEN_OT_render", F12KEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "SCREEN_OT_render_view_cancel", ESCKEY, KM_PRESS, 0, 0); - /* frame offsets */ + /* frame offsets & play */ keymap= WM_keymap_listbase(wm, "Frames", 0, 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 10); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -10); 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_animation_play", AKEY, KM_PRESS, KM_ALT, 0); } diff --git a/source/blender/editors/space_info/info_header.c b/source/blender/editors/space_info/info_header.c index af792d0b22c..aa6aadd00bc 100644 --- a/source/blender/editors/space_info/info_header.c +++ b/source/blender/editors/space_info/info_header.c @@ -72,8 +72,9 @@ static int error() {return 0;} /* ************************ header area region *********************** */ -#define B_STOPRENDER 1 -#define B_STOPCAST 2 +#define B_STOPRENDER 1 +#define B_STOPCAST 2 +#define B_STOPANIM 3 static void do_viewmenu(bContext *C, void *arg, int event) { @@ -328,6 +329,9 @@ static void do_info_buttons(bContext *C, void *arg, int event) case B_STOPCAST: WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C)); break; + case B_STOPANIM: + ED_screen_animation_timer(C, 0, 0); + break; } } @@ -444,6 +448,10 @@ void info_header_buttons(const bContext *C, ARegion *ar) uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_REC, "Capture", xco+5,yco,85,19, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast"); xco+= 90; } + if(screen->animtimer) { + uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", xco+5,yco,85,19, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); + xco+= 90; + } /* always as last */ UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin); diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 12f23f03e66..d72ecd60da9 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -43,6 +43,7 @@ #include "BKE_context.h" #include "BKE_colortools.h" #include "BKE_screen.h" +#include "BKE_utildefines.h" #include "ED_space_api.h" #include "ED_screen.h" @@ -196,7 +197,7 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn) /* context changes */ switch(wmn->category) { case NC_SCREEN: - if(wmn->data==ND_SCREENCAST) + if(ELEM(wmn->data, ND_SCREENCAST, ND_ANIMPLAY)) ED_region_tag_redraw(ar); break; case NC_SCENE: diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 3df57208bbd..c4ca4d8522f 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -207,6 +207,10 @@ static void time_header_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { + case NC_SCREEN: + if(wmn->data==ND_ANIMPLAY) + ED_region_tag_redraw(ar); + break; case NC_SCENE: switch (wmn->data) { case ND_FRAME: diff --git a/source/blender/editors/space_time/time_header.c b/source/blender/editors/space_time/time_header.c index f26e632eb87..cf9c12f3dff 100644 --- a/source/blender/editors/space_time/time_header.c +++ b/source/blender/editors/space_time/time_header.c @@ -46,6 +46,7 @@ #include "ED_keyframing.h" #include "ED_screen.h" +#include "ED_screen_types.h" #include "ED_types.h" #include "ED_util.h" @@ -66,17 +67,46 @@ /* ************************ header time area region *********************** */ +static ARegion *time_top_left_3dwindow(bScreen *screen) +{ + ARegion *aret= NULL; + ScrArea *sa; + int min= 10000; + + for(sa= screen->areabase.first; sa; sa= sa->next) { + if(sa->spacetype==SPACE_VIEW3D) { + ARegion *ar; + for(ar= sa->regionbase.first; ar; ar= ar->next) { + if(ar->regiontype==RGN_TYPE_WINDOW) { + if(ar->winrct.xmin - ar->winrct.ymin < min) { + aret= ar; + min= ar->winrct.xmin - ar->winrct.ymin; + } + } + } + } + } + return aret; +} static void do_time_redrawmenu(bContext *C, void *arg, int event) { - SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); if(event < 1001) { + bScreen *screen= CTX_wm_screen(C); + SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); stime->redraws ^= event; - /* update handler when it's running */ -// if(has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM)) -// start_animated_screen(stime); + + if(screen->animtimer) { + wmTimer *wt= screen->animtimer; + ScreenAnimData *sad= wt->customdata; + + sad->redraws= stime->redraws; + sad->ar= NULL; + if(stime->redraws & TIME_REGION) + sad->ar= time_top_left_3dwindow(screen); + } } else { if(event==1001) { @@ -98,9 +128,9 @@ static uiBlock *time_redrawmenu(bContext *C, ARegion *ar, void *arg_unused) block= uiBeginBlock(C, ar, "header time_redrawmenu", UI_EMBOSSP); uiBlockSetButmFunc(block, do_time_redrawmenu, NULL); - if(stime->redraws & TIME_LEFTMOST_3D_WIN) icon= ICON_CHECKBOX_HLT; + if(stime->redraws & TIME_REGION) icon= ICON_CHECKBOX_HLT; else icon= ICON_CHECKBOX_DEHLT; - uiDefIconTextBut(block, BUTM, 1, icon, "Top-Left 3D Window", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_LEFTMOST_3D_WIN, ""); + uiDefIconTextBut(block, BUTM, 1, icon, "Top-Left 3D Window", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_REGION, ""); if(stime->redraws & TIME_ALL_3D_WIN) icon= ICON_CHECKBOX_HLT; else icon= ICON_CHECKBOX_DEHLT; @@ -358,7 +388,8 @@ static uiBlock *time_framemenu(bContext *C, ARegion *ar, void *arg_unused) void do_time_buttons(bContext *C, void *arg, int event) { -// SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); + bScreen *screen= CTX_wm_screen(C); + SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); Scene *scene= CTX_data_scene(C); switch(event) { @@ -374,10 +405,19 @@ void do_time_buttons(bContext *C, void *arg, int event) //update_for_newframe(); break; case B_TL_PLAY: - ED_screen_animation_timer(C, 1); + ED_screen_animation_timer(C, stime->redraws, 1); + + /* 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); + } + break; case B_TL_STOP: - ED_screen_animation_timer(C, 0); + ED_screen_animation_timer(C, 0, 0); break; case B_TL_FF: /* end frame */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 0d88e3eb6e8..8cdb51bcab0 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -684,7 +684,7 @@ enum { #define TIME_ONLYACTSEL 4 /* time->redraws */ -#define TIME_LEFTMOST_3D_WIN 1 +#define TIME_REGION 1 #define TIME_ALL_3D_WIN 2 #define TIME_ALL_ANIM_WIN 4 #define TIME_ALL_BUTS_WIN 8 diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index d3cb60d90fe..b96089a05f1 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -169,7 +169,7 @@ typedef struct wmNotifier { /* NC_SCREEN screen */ #define ND_SCREENBROWSE (1<<16) #define ND_SCREENCAST (2<<16) - +#define ND_ANIMPLAY (3<<16) /* NC_SCENE Scene */ #define ND_SCENEBROWSE (1<<16) @@ -276,7 +276,8 @@ typedef struct wmTabletData { typedef struct wmTimer { struct wmTimer *next, *prev; double timestep; /* set by timer user */ - int event_type; /* set by timer user */ + int event_type; /* set by timer user, goes to event system */ + void *customdata; /* set by timer user, to allow custom values */ double duration; /* total running time in seconds */ double delta; /* time since previous step in seconds */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 2675fba729a..cb6bcb41366 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -93,6 +93,8 @@ static void wm_ghostwindow_destroy(wmWindow *win) ED_screen_exit should have been called */ void wm_window_free(bContext *C, wmWindow *win) { + wmTimer *wt; + /* update context */ if(C) { wmWindowManager *wm= CTX_wm_manager(C); @@ -108,6 +110,10 @@ void wm_window_free(bContext *C, wmWindow *win) } if(win->eventstate) MEM_freeN(win->eventstate); + + for(wt= win->timers.first; wt; wt= wt->next) + if(wt->customdata) + MEM_freeN(wt->customdata); BLI_freelistN(&win->timers); wm_event_free_all(win); @@ -657,6 +663,8 @@ void WM_event_remove_window_timer(wmWindow *win, wmTimer *timer) break; if(wt) { BLI_remlink(&win->timers, wt); + if(wt->customdata) + MEM_freeN(wt->customdata); MEM_freeN(wt); } } |