Animated UI for TimeLine "Play"

Using the Play button in timeline, now uses an event-driven system to
update the animation system and signal windows to redraw. Meaning the
full UI remains responsive!

Check the new Pulldown "Playback" to set which windows you like to see
updated. Same settings is used for LMB 'dragging' frames in Timeline.

Implementation notes;

- the Icon for 'Pause' (or stop) has to be made yet, I commit this from
  my laptop... all was coded during a 2 x 5 hour train ride to germany
- the anim playback system (ALT+A too) now uses correct "frames per
  second" as maximum speed. Buttons can be found in 3 places in the UI,
  also added it as pulldown item
- The system works with 'screen handlers', which has been coded with
  using Python (networked) events or verse in mind too. A doc on that
  will follow.
- the buttons code has been made 'resistant' to animated UIs too,
  preventing flashing of hilites.
- All subloops (like transform) stop playback, with exception of MMB
  view manipulations.

As extra; found tweak to make Textured AA fonts draw without distortion.
Looks perfect here on laptop now (like Pixmap fonts) and is 20x faster.
This commit is contained in:
Ton Roosendaal 2005-05-11 20:01:42 +00:00
parent 57f9553b3a
commit 0574768f88
18 changed files with 373 additions and 132 deletions

@ -4682,6 +4682,7 @@ static void do_versions(Main *main)
}
/* set manipulator type */
/* force oops draw if depgraph was set*/
/* set time line var */
for (sc= main->screen.first; sc; sc= sc->id.next) {
ScrArea *sa;
for (sa= sc->areabase.first; sa; sa= sa->next) {
@ -4696,7 +4697,11 @@ static void do_versions(Main *main)
if ( ((SpaceOops *)sl)->type==SO_DEPSGRAPH)
((SpaceOops *)sl)->type=SO_OOPS;
}
#endif
#endif
if(sl->spacetype==SPACE_TIME) {
SpaceTime *stime= (SpaceTime *)sl;
stime->redraws= TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN;
}
}
}
}

@ -119,6 +119,19 @@ void draw_area_emboss(struct ScrArea *sa);
void headerprint(char *str);
/* ******* handlers ****** */
#define SCREEN_MAXHANDLER 8
#define SCREEN_HANDLER_ANIM 1
#define SCREEN_HANDLER_PYTHON 2
#define SCREEN_HANDLER_VERSE 3
void add_screenhandler(struct bScreen *sc, short eventcode, short val);
void rem_screenhandler(struct bScreen *sc, short eventcode);
int do_screenhandlers(struct bScreen *sc);
int has_screenhandler(struct bScreen *sc, short eventcode);
/***/
/**

@ -53,8 +53,6 @@ int update_time(void);
void calc_viewborder(struct View3D *v3d, struct rcti *viewborder_r);
void view3d_set_1_to_1_viewborder(struct View3D *v3d);
void timestr(double time, char *str);
double speed_to_swaptime(int speed);
double key_to_swaptime(int key);
void sumo_callback(void *obp);
void init_anim_sumo(void);

@ -56,6 +56,7 @@ void load_sound_buttons(char *str);
/* end of declarations moved from old headerbuttons.c */
void update_for_newframe_muted(void);
void update_for_newframe_nodraw(void);
void free_matcopybuf(void);
void clear_matcopybuf(void);
void write_videoscape_fs(void);

@ -366,6 +366,7 @@
#define B_TL_FF 753
#define B_TL_PREVKEY 754
#define B_TL_NEXTKEY 755
#define B_TL_STOP 756
/* NLA: 801-900 */
#define B_NLAHOME 801

@ -246,8 +246,9 @@
#define REDRAWSCRIPT 0x4032
#define REDRAWTIME 0x4033
#define REDRAWBUTSCONSTRAINT 0x4034
#define ONLOAD_SCRIPT 0x4035
#define ONLOAD_SCRIPT 0x4035
#define SCREEN_HANDLER 0x4036
#define REDRAWANIM 0x4037
#endif /* !__MYDEVICE_H__ */

@ -49,11 +49,11 @@ typedef struct bScreen {
short startx, endx, starty, endy; /* framebuffer coords */
short sizex, sizey;
short scenenr, screennr; /* only for pupmenu */
short full, rt;
short full, pad;
short mainwin, winakt;
short handler[8]; /* similar to space handler now */
} bScreen;
typedef struct ScrVert {
struct ScrVert *next, *prev, *newv;
vec2s vec;
@ -147,6 +147,9 @@ typedef struct ScrArea {
#define B_SCROLL 8
#define HOR_SCROLL 12
/* screen->flag */
/* dunno who thought this below is nice code, but be warned, the values are written in
a file, and cannot be switched or altered. enum here is out of focus (ton) */
enum {

@ -284,7 +284,7 @@ typedef struct SpaceTime {
View2D v2d;
int flag, pad;
int flag, redraws;
} SpaceTime;
@ -534,9 +534,14 @@ typedef struct SpaceImaSel {
#define IMS_INFILESLI 4
/* time->flag */
#define TIME_DRAWFRAMES 1
#define TIME_CFRA_NUM 2
/* time->redraws */
#define TIME_LEFTMOST_3D_WIN 1
#define TIME_ALL_3D_WIN 2
#define TIME_ALL_ANIM_WIN 4
#define TIME_ALL_BUTS_WIN 8
#endif

@ -1214,7 +1214,7 @@ static void render_panel_format(void)
} else {
uiDefButS(block, NUM,B_DIFF, "Quality:", 892,yofs,112,20, &G.scene->r.quality, 10.0, 100.0, 0, 0, "Quality setting for JPEG images, AVI Jpeg and SGI movies");
}
uiDefButS(block, NUM,B_RTCHANGED,"Frs/sec:", 1006,yofs,113,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
uiDefButS(block, NUM,B_FRAMEMAP,"Frs/sec:", 1006,yofs,113,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
uiBlockBeginAlign(block);
@ -1399,15 +1399,18 @@ void anim_panels()
block= uiNewBlock(&curarea->uiblocks, "anim_panel", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Anim", "Anim", 0, 0, 318, 204)==0) return;
uiDefButS(block, NUM,REDRAWSEQ,"Sta:", 320,17,93,27,&G.scene->r.sfra,1.0,MAXFRAMEF, 0, 0, "Specify the start frame of the animation");
uiDefButS(block, NUM,REDRAWSEQ,"End:", 416,17,95,27,&G.scene->r.efra,1.0,MAXFRAMEF, 0, 0, "Specify the end frame of the animation");
uiBlockBeginAlign(block);
uiDefButS(block, NUM,B_FRAMEMAP,"Map Old:", 10,160,150,20,&G.scene->r.framapto,1.0,900.0, 0, 0, "Specify old mapping value in frames");
uiDefButS(block, NUM,B_FRAMEMAP,"Map New:", 160,160,150,20,&G.scene->r.images,1.0,900.0, 0, 0, "Specify how many frames the Map Old will last");
uiDefButS(block, NUM,B_FRAMEMAP,"Map Old:", 320,69,93,22,&G.scene->r.framapto,1.0,900.0, 0, 0, "Specify old mapping value in frames");
uiDefButS(block, NUM,B_FRAMEMAP,"Map New:", 416,69,95,22,&G.scene->r.images,1.0,900.0, 0, 0, "Specify how many frames the Map Old will last");
uiBlockBeginAlign(block);
uiDefButS(block, NUM,B_FRAMEMAP,"Frs/sec:", 10,130,150,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
uiDefButS(block, TOG|BIT|1, B_SOUND_CHANGED, "Sync",160,130,150,20, &G.scene->audio.flag, 0, 0, 0, 0, "Use sample clock for syncing animation to audio");
uiBlockBeginAlign(block);
uiDefButS(block, NUM,REDRAWSEQ,"Sta:", 10,100,150,20,&G.scene->r.sfra,1.0,MAXFRAMEF, 0, 0, "Specify the start frame of the animation");
uiDefButS(block, NUM,REDRAWSEQ,"End:", 160,100,150,20,&G.scene->r.efra,1.0,MAXFRAMEF, 0, 0, "Specify the end frame of the animation");
uiDefButS(block, NUM,B_RTCHANGED,"Frs/sec:", 320,47,93,19, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
uiDefButS(block, TOG|BIT|1, B_SOUND_CHANGED, "Sync", 416,47,95,19, &G.scene->audio.flag, 0, 0, 0, 0, "Use sample clock for syncing animation to audio");
}

@ -2229,75 +2229,6 @@ int update_time(void)
return (tottime < 0.0);
}
double speed_to_swaptime(int speed)
{
switch(speed) {
case 1:
return 1.0/60.0;
case 2:
return 1.0/50.0;
case 3:
return 1.0/30.0;
case 4:
return 1.0/25.0;
case 5:
return 1.0/20.0;
case 6:
return 1.0/15.0;
case 7:
return 1.0/12.5;
case 8:
return 1.0/10.0;
case 9:
return 1.0/6.0;
}
return 1.0/4.0;
}
double key_to_swaptime(int key)
{
switch(key) {
case PAD1:
G.animspeed= 1;
tottime= 0;
return speed_to_swaptime(1);
case PAD2:
G.animspeed= 2;
tottime= 0;
return speed_to_swaptime(2);
case PAD3:
G.animspeed= 3;
tottime= 0;
return speed_to_swaptime(3);
case PAD4:
G.animspeed= 4;
tottime= 0;
return speed_to_swaptime(4);
case PAD5:
G.animspeed= 5;
tottime= 0;
return speed_to_swaptime(5);
case PAD6:
G.animspeed= 6;
tottime= 0;
return speed_to_swaptime(6);
case PAD7:
G.animspeed= 7;
tottime= 0;
return speed_to_swaptime(7);
case PAD8:
G.animspeed= 8;
tottime= 0;
return speed_to_swaptime(8);
case PAD9:
G.animspeed= 9;
tottime= 0;
return speed_to_swaptime(9);
}
return speed_to_swaptime(G.animspeed);
}
void inner_play_anim_loop(int init, int mode)
{
ScrArea *sa;
@ -2308,7 +2239,7 @@ void inner_play_anim_loop(int init, int mode)
/* init */
if(init) {
oldsa= curarea;
swaptime= speed_to_swaptime(G.animspeed);
swaptime= 1.0/(float)G.scene->r.frs_sec;
tottime= 0.0;
curmode= mode;
@ -2452,8 +2383,6 @@ int play_anim(int mode)
sa= sa->next;
}
/* speed button */
// allqueue(REDRAWBUTSOBJECT, 0);
/* groups could have changed ipo */
allspace(REMAKEIPO, 0);
allqueue(REDRAWIPO, 0);

@ -5105,7 +5105,7 @@ void ipo_record()
waitcursor(1);
tottime= 0.0;
swaptime= speed_to_swaptime(G.animspeed);
swaptime= G.scene->r.framelen;
cfrao= CFRA;
cfra=efra= SFRA;
sfra= EFRA;

@ -405,9 +405,9 @@ void scrarea_do_headchange(ScrArea *area)
float ofs= area->headbutofs;
if (area->headertype==HEADERDOWN) {
bwin_ortho2(area->headwin, -0.375+ofs, area->headrct.xmax-area->headrct.xmin-0.375+ofs, -3.375, area->headrct.ymax-area->headrct.ymin-3.375);
bwin_ortho2(area->headwin, -0.375+ofs, area->headrct.xmax-area->headrct.xmin-0.375+ofs, -3.375, area->headrct.ymax-area->headrct.ymin-3.375+1.0);
} else if (area->headertype==HEADERTOP) {
bwin_ortho2(area->headwin, -0.375+ofs, area->headrct.xmax-area->headrct.xmin-0.375+ofs, -2.375, area->headrct.ymax-area->headrct.ymin-2.375);
bwin_ortho2(area->headwin, -0.375+ofs, area->headrct.xmax-area->headrct.xmin-0.375+ofs, -2.375-1.0, area->headrct.ymax-area->headrct.ymin-2.375);
}
}
@ -956,6 +956,132 @@ void reset_autosave(void) {
window_set_timer(mainwin, U.savetime*60*1000, AUTOSAVE_FILE);
}
/* ************ handlers ************** */
/* don't know yet how the handlers will evolve, for simplicity
i choose for an array with eventcodes, this saves in a file!
*/
void add_screenhandler(bScreen *sc, short eventcode, short val)
{
short a;
// find empty spot
for(a=0; a<SCREEN_MAXHANDLER; a+=2) {
if( sc->handler[a]==eventcode ) {
sc->handler[a+1]= val;
break;
}
else if( sc->handler[a]==0) {
sc->handler[a]= eventcode;
sc->handler[a+1]= val;
break;
}
}
if(a==SCREEN_MAXHANDLER) printf("error; max (4) screen handlers reached!\n");
}
void rem_screenhandler(bScreen *sc, short eventcode)
{
short a;
for(a=0; a<SCREEN_MAXHANDLER; a+=2) {
if( sc->handler[a]==eventcode) {
sc->handler[a]= 0;
break;
}
}
}
int has_screenhandler(bScreen *sc, short eventcode)
{
short a;
for(a=0; a<SCREEN_MAXHANDLER; a+=2) {
if( sc->handler[a]==eventcode) {
return 1;
}
}
return 0;
}
static void animated_screen(bScreen *sc, short val)
{
CFRA++;
if(CFRA > EFRA) CFRA= SFRA;
update_for_newframe_nodraw();
if(val & TIME_ALL_3D_WIN)
allqueue(REDRAWVIEW3D, 0);
else if(val & TIME_LEFTMOST_3D_WIN) {
ScrArea *sa= sc->areabase.first, *samin=NULL;
int min= 10000;
for(; sa; sa= sa->next) {
if(sa->spacetype==SPACE_VIEW3D) {
if(sa->winrct.xmin - sa->winrct.ymin < min) {
samin= sa;
min= sa->winrct.xmin - sa->winrct.ymin;
}
}
}
if(samin) scrarea_queue_winredraw(samin);
}
if(val & TIME_ALL_ANIM_WIN) allqueue(REDRAWANIM, 0);
if(val & TIME_ALL_BUTS_WIN) allqueue(REDRAWBUTSALL, 0);
allqueue(REDRAWTIME, 0);
}
/* because we still have to cope with subloops, this function is called
in viewmove() for example too */
/* returns 1 if something was handled */
/* restricts to frames-per-second setting for frequency of updates */
int do_screenhandlers(bScreen *sc)
{
static double ltime=0.0;
double swaptime, time;
short a, done= 0;
time = PIL_check_seconds_timer();
swaptime= 1.0/(float)G.scene->r.frs_sec;
/* only now do the handlers */
if(swaptime < time-ltime || ltime==0.0) {
ltime= time;
for(a=0; a<SCREEN_MAXHANDLER; a+=2) {
switch(sc->handler[a]) {
case SCREEN_HANDLER_ANIM:
animated_screen(sc, sc->handler[a+1]);
done= 1;
break;
case SCREEN_HANDLER_PYTHON:
done= 1;
break;
case SCREEN_HANDLER_VERSE:
done= 1;
break;
}
}
}
else if( qtest()==0) PIL_sleep_ms(5); // 5 milliseconds pause, for idle
/* separate check for if we need to add to afterqueue */
/* is only to keep mainqueue awqke */
for(a=0; a<SCREEN_MAXHANDLER; a+=2) {
if(sc->handler[a]) {
ScrArea *sa= sc->areabase.first;
if(sa->headwin) addafterqueue(sa->headwin, SCREEN_HANDLER, 1);
else addafterqueue(sa->win, SCREEN_HANDLER, 1);
}
}
return done;
}
/* ****** end screen handlers ************ */
static void screen_dispatch_events(void) {
int events_remaining= 1;
ScrArea *sa;
@ -990,6 +1116,7 @@ static void screen_dispatch_events(void) {
}
screen_swapbuffers();
do_screenhandlers(G.curscreen);
}
static ScrArea *screen_find_area_for_pt(bScreen *sc, short *mval)

@ -418,6 +418,53 @@ void timeline_grab(int mode, int smode) // mode and smode unused here, for callb
allqueue(REDRAWTIME, 0);
}
/* copy of this is actually in editscreen.c, but event based */
static void timeline_force_draw(short val)
{
ScrArea *sa, *tempsa, *samin= NULL;
int dodraw;
if(val & TIME_LEFTMOST_3D_WIN) {
ScrArea *sa= G.curscreen->areabase.first;
int min= 10000;
for(; sa; sa= sa->next) {
if(sa->spacetype==SPACE_VIEW3D) {
if(sa->winrct.xmin - sa->winrct.ymin < min) {
samin= sa;
min= sa->winrct.xmin - sa->winrct.ymin;
}
}
}
}
tempsa= curarea;
sa= G.curscreen->areabase.first;
while(sa) {
dodraw= 0;
if(sa->spacetype==SPACE_VIEW3D) {
if(sa==samin || (val & TIME_ALL_3D_WIN)) dodraw= 1;
}
else if(ELEM6(sa->spacetype, SPACE_NLA, SPACE_IPO, SPACE_SEQ, SPACE_BUTS, SPACE_ACTION, SPACE_SOUND)) {
if(val & TIME_ALL_ANIM_WIN) dodraw= 1;
}
else if(sa->spacetype==SPACE_BUTS) {
if(val & TIME_ALL_BUTS_WIN) dodraw= 1;
}
else if(sa->spacetype==SPACE_TIME) dodraw= 2;
if(dodraw) {
areawinset(sa->win);
scrarea_do_windraw(sa);
if(dodraw==2) scrarea_do_headdraw(sa);
}
sa= sa->next;
}
areawinset(tempsa->win);
screen_swapbuffers();
}
/* ***************************** */
/* Right. Now for some implementation: */
@ -462,16 +509,15 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
first= 0;
CFRA= cfra;
update_for_newframe();
force_draw_plus(SPACE_VIEW3D, 1);
update_for_newframe_nodraw();
timeline_force_draw(stime->redraws);
}
else PIL_sleep_ms(30);
} while(get_mbut() & mousebut);
stime->flag &= ~TIME_CFRA_NUM;
doredraw= 1;
allqueue(REDRAWALL, 0);
break;
case RIGHTMOUSE: /* select/deselect marker */

@ -69,7 +69,8 @@
void do_time_buttons(ScrArea *sa, unsigned short event)
{
SpaceTime *stime= sa->spacedata.first;
switch(event) {
case B_TL_REW:
@ -77,7 +78,11 @@ void do_time_buttons(ScrArea *sa, unsigned short event)
update_for_newframe();
break;
case B_TL_PLAY:
play_anim(1);
add_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM, stime->redraws);
break;
case B_TL_STOP:
rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
allqueue(REDRAWALL, 0);
break;
case B_TL_FF:
/* end frame */
@ -95,17 +100,79 @@ void do_time_buttons(ScrArea *sa, unsigned short event)
}
}
static void do_time_redrawmenu(void *arg, int event)
{
SpaceTime *stime= curarea->spacedata.first;
if(event < 1001) {
stime->redraws ^= event;
/* update handler when it's running */
if(has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM))
add_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM, stime->redraws);
}
else {
if(event==1001) {
button(&G.scene->r.frs_sec,1,120,"Frames/Second:");
}
}
}
static uiBlock *time_redrawmenu(void *arg_unused)
{
SpaceTime *stime= curarea->spacedata.first;
uiBlock *block;
short yco= 0, menuwidth=120, icon;
char str[32];
block= uiNewBlock(&curarea->uiblocks, "time_redrawmenu",
UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_time_redrawmenu, NULL);
if(stime->redraws & TIME_LEFTMOST_3D_WIN) 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, "");
if(stime->redraws & TIME_ALL_3D_WIN) icon= ICON_CHECKBOX_HLT;
else icon= ICON_CHECKBOX_DEHLT;
uiDefIconTextBut(block, BUTM, 1, icon, "All 3D Windows", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_ALL_3D_WIN, "");
if(stime->redraws & TIME_ALL_ANIM_WIN) icon= ICON_CHECKBOX_HLT;
else icon= ICON_CHECKBOX_DEHLT;
uiDefIconTextBut(block, BUTM, 1, icon, "Animation Windows", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_ALL_ANIM_WIN, "");
if(stime->redraws & TIME_ALL_BUTS_WIN) icon= ICON_CHECKBOX_HLT;
else icon= ICON_CHECKBOX_DEHLT;
uiDefIconTextBut(block, BUTM, 1, icon, "Buttons Windows", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_ALL_BUTS_WIN, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
sprintf(str, "Set Frames/Sec (%d)", G.scene->r.frs_sec);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, str, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1001, "");
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
}
else {
uiBlockSetDirection(block, UI_TOP);
uiBlockFlipOrder(block);
}
uiTextBoundsBlock(block, 50);
return block;
}
static void do_time_viewmenu(void *arg, int event)
{
SpaceTime *stime= curarea->spacedata.first;
int first;
switch(event) {
case 1: /* Play Back Animation */
play_anim(0);
break;
case 2: /* Play Back Animation in All */
play_anim(1);
case 2: /* Play Back Animation */
add_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM, stime->redraws);
break;
case 3: /* View All */
first= G.scene->r.sfra;
@ -151,7 +218,7 @@ static uiBlock *time_viewmenu(void *arg_unused)
UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_time_viewmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@ -311,10 +378,13 @@ void time_buttons(ScrArea *sa)
"Frame", xco, -2, xmax-3, 24, "");
xco+= xmax;
xmax= GetButStringLength("Playback");
uiDefPulldownBut(block, time_redrawmenu, NULL,
"Playback", xco, -2, xmax-3, 24, "");
xco+= xmax;
}
uiBlockSetEmboss(block, UI_EMBOSSX);
xco += XIC;
uiBlockBeginAlign(block);
uiDefButS(block, NUM, REDRAWALL,"Start:",
@ -345,8 +415,14 @@ void time_buttons(ScrArea *sa)
uiDefIconBut(block, BUT, B_TL_PREVKEY, ICON_PREV_KEYFRAME,
xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Skip to previous keyframe (Ctrl PageDown)");
xco+= XIC+4;
uiDefIconBut(block, BUT, B_TL_PLAY, ICON_PLAY,
xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Play Timeline (Alt Shift A)");
if(has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM))
uiDefIconBut(block, BUT, B_TL_STOP, ICON_MAN_SCALE,
xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Stop Playing Timeline");
else
uiDefIconBut(block, BUT, B_TL_PLAY, ICON_PLAY,
xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Play Timeline ");
xco+= XIC+4;
uiDefIconBut(block, BUT, B_TL_NEXTKEY, ICON_NEXT_KEYFRAME,
xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Skip to next keyframe (Ctrl PageUp)");

@ -488,23 +488,27 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
return xco;
}
static void do_update_for_newframe(int mute)
static void do_update_for_newframe(int mute, int events)
{
extern void audiostream_scrub(unsigned int frame); /* seqaudio.c */
ScrArea *sa;
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION,0);
allqueue(REDRAWNLA,0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWINFO, 1);
allqueue(REDRAWSEQ, 1);
allqueue(REDRAWSOUND, 1);
allqueue(REDRAWTIME, 1);
allqueue(REDRAWBUTSHEAD, 0);
allqueue(REDRAWBUTSSHADING, 0);
allqueue(REDRAWBUTSOBJECT, 0);
if(events) {
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION,0);
allqueue(REDRAWNLA,0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWINFO, 1);
allqueue(REDRAWSEQ, 1);
allqueue(REDRAWSOUND, 1);
allqueue(REDRAWTIME, 1);
allqueue(REDRAWBUTSHEAD, 0);
allqueue(REDRAWBUTSSHADING, 0);
allqueue(REDRAWBUTSOBJECT, 0);
}
/* layers/materials, object ipos are calculted in where_is_object (too) */
do_all_ipos();
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
@ -536,14 +540,21 @@ static void do_update_for_newframe(int mute)
void update_for_newframe(void)
{
do_update_for_newframe(0);
do_update_for_newframe(0, 1);
}
void update_for_newframe_muted(void)
{
do_update_for_newframe(1);
do_update_for_newframe(1, 1);
}
void update_for_newframe_nodraw(void)
{
do_update_for_newframe(1, 0);
}
static void show_splash(void)
{
extern char datatoc_splash_jpg[];

@ -885,22 +885,38 @@ static void ui_draw_links(uiBlock *block)
void uiDrawBlock(uiBlock *block)
{
uiBut *but;
short testmouse=0, mouse[2];
/* handle pending stuff */
if(block->autofill) ui_autofill(block);
if(block->minx==0.0 && block->maxx==0.0) uiBoundsBlock(block, 0);
if(block->flag & UI_BUT_ALIGN) uiBlockEndAlign(block);
/* we set active flag on a redraw again */
if((block->flag & UI_BLOCK_LOOP)==0) {
testmouse= 1;
Mat4CpyMat4(UIwinmat, block->winmat);
uiGetMouse(block->win, mouse);
}
uiPanelPush(block); // panel matrix
if(block->flag & UI_BLOCK_LOOP) {
uiDrawMenuBox(block->minx, block->miny, block->maxx, block->maxy, block->flag);
}
else if(block->panel) ui_draw_panel(block);
else {
if(block->panel) ui_draw_panel(block);
}
if(block->drawextra) block->drawextra();
for (but= block->buttons.first; but; but= but->next) {
if(testmouse && uibut_contains_pt(but, mouse))
but->flag |= UI_ACTIVE;
else
but->flag &= ~UI_ACTIVE;
ui_draw_but(but);
}

@ -1732,6 +1732,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
handle_view3d_around();
scrarea_queue_headredraw(curarea);
scrarea_queue_winredraw(curarea);
break;
case PERIODKEY:
@ -1743,6 +1744,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
handle_view3d_around();
scrarea_queue_headredraw(curarea);
scrarea_queue_winredraw(curarea);
break;
case PADSLASHKEY:
@ -4282,16 +4284,14 @@ static void init_timespace(ScrArea *sa)
stime->spacetype= SPACE_TIME;
stime->blockscale= 0.7;
stime->redraws= TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN;
stime->v2d.tot.xmin= -4.0;
stime->v2d.tot.ymin= 0.0;
stime->v2d.tot.xmax= 250.0;
stime->v2d.tot.xmax= (float)EFRA + 4.0;
stime->v2d.tot.ymax= (float)sa->winy;
stime->v2d.cur.xmin= -4.0;
stime->v2d.cur.ymin= 0.0;
stime->v2d.cur.xmax= 50.0;
stime->v2d.cur.ymax= (float)sa->winy;
stime->v2d.cur= stime->v2d.tot;
stime->v2d.min[0]= 1.0;
stime->v2d.min[1]= (float)sa->winy;
@ -4763,6 +4763,11 @@ void allqueue(unsigned short event, short val)
scrarea_queue_winredraw(sa);
}
break;
case REDRAWANIM:
if ELEM6(sa->spacetype, SPACE_IPO, SPACE_SOUND, SPACE_TIME, SPACE_NLA, SPACE_ACTION, SPACE_SEQ) {
scrarea_queue_winredraw(sa);
if(val) scrarea_queue_headredraw(sa);
}
}
}
sa= sa->next;
@ -4870,7 +4875,7 @@ void force_draw(int header)
}
/* if header==1, then draw header for curarea too. Excepption for headerprint()... */
/* if header==1, then draw header for curarea too. Exception for headerprint()... */
void force_draw_plus(int type, int header)
{
/* draws all areas that show something like curarea AND areas of 'type' */

@ -432,7 +432,8 @@ void viewmove(int mode)
while(TRUE) {
getmouseco_sc(mval);
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || (G.f & G_PLAYANIM)) {
// if playanim = alt+A, screenhandlers are for animated UI, python, etc
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || (G.f & G_PLAYANIM) || do_screenhandlers(G.curscreen)) {
if(firsttime) {