Bug found by Bassam; in certain occasions reading a file calls setscreen()
[blender.git] / source / blender / src / drawaction.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * Drawing routines for the Action window type
32  */
33
34 /* System includes ----------------------------------------------------- */
35
36 #include <math.h>
37 #include <stdlib.h>
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #ifdef WIN32
44 #include "BLI_winstuff.h"
45 #endif
46
47 #include "MEM_guardedalloc.h"
48
49 #include "BMF_Api.h"
50
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
53
54 /* Types --------------------------------------------------------------- */
55 #include "DNA_action_types.h"
56 #include "DNA_curve_types.h"
57 #include "DNA_ipo_types.h"
58 #include "DNA_object_types.h"
59 #include "DNA_screen_types.h"
60 #include "DNA_scene_types.h"
61 #include "DNA_space_types.h"
62 #include "DNA_constraint_types.h"
63 #include "DNA_key_types.h"
64
65 #include "BKE_action.h"
66 #include "BKE_global.h"
67
68 /* Everything from source (BIF, BDR, BSE) ------------------------------ */ 
69
70 #include "BIF_gl.h"
71 #include "BIF_glutil.h"
72 #include "BIF_resources.h"
73 #include "BIF_screen.h"
74 #include "BIF_interface.h"
75 #include "BIF_mywindow.h"
76 #include "BIF_space.h"
77
78 #include "BDR_editcurve.h"
79 #include "BSE_view.h"
80 #include "BSE_drawipo.h"
81 #include "BSE_editaction.h"
82 #include "BSE_editaction_types.h"
83 #include "BDR_drawaction.h"
84
85 /* 'old' stuff": defines and types, and own include -------------------- */
86
87 #include "blendef.h"
88 #include "mydevice.h"
89
90 #include "BKE_ipo.h"
91
92 /* local functions ----------------------------------------------------- */
93 void drawactionspace(ScrArea *sa, void *spacedata);
94 static void draw_channel_names(void);
95 static void draw_channel_strips(SpaceAction *saction);
96 int count_action_levels(bAction *act);
97 static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert);
98 static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert);
99 static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert);
100 static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert);
101 static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos);
102 void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos);
103 static void draw_action_mesh_names(Key *key);
104
105 /* implementation ------------------------------------------------------ */
106
107 extern void make_rvk_slider(uiBlock *block, Key *key, int i,
108                                                         int x, int y, int w, int h); /* editkey.c */
109 extern short showsliders; /* editaction .c */
110 extern short ACTWIDTH;
111
112 void meshactionbuts(SpaceAction *saction, Key *key)
113 {
114         int           i;
115         char          str[64];
116         float           x, y;
117         uiBlock       *block;
118         uiBut             *but;
119
120 #define XIC 20
121 #define YIC 20
122
123         /* lets make the rvk sliders */
124
125         /* reset the damn myortho2 or the sliders won't draw/redraw
126          * correctly *grumble*
127          */
128         mywinset(curarea->win);
129         myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
130
131     sprintf(str, "actionbuttonswin %d", curarea->win);
132     block= uiNewBlock (&curarea->uiblocks, str, 
133                        UI_EMBOSS, UI_HELV, curarea->win);
134
135         x = NAMEWIDTH + 1;
136     y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP) 
137           + CHANNELHEIGHT/2  - G.v2d->cur.ymin;
138
139         /* make the little 'open the sliders' widget */
140     BIF_ThemeColor(TH_FACE); // this slot was open...
141         glRects(2,            y + 2*CHANNELHEIGHT - 2,  
142                         ACTWIDTH - 2, y + CHANNELHEIGHT + 2);
143         glColor3ub(0, 0, 0);
144         glRasterPos2f(4, y + CHANNELHEIGHT + 6);
145         BMF_DrawString(G.font, "Sliders");
146
147         uiBlockSetEmboss(block, UI_EMBOSSN);
148
149         if (!showsliders) {
150                 ACTWIDTH = NAMEWIDTH;
151                 but=uiDefIconButS(block, TOG, B_REDR, 
152                                           ICON_DISCLOSURE_TRI_RIGHT,
153                                           NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
154                                           XIC,YIC-2,
155                                           &(showsliders), 0, 0, 0, 0, 
156                                           "Show action window sliders");
157                 // no hilite, the winmatrix is not correct later on...
158                 uiButSetFlag(but, UI_NO_HILITE);
159
160         }
161         else {
162                 but= uiDefIconButS(block, TOG, B_REDR, 
163                                           ICON_DISCLOSURE_TRI_DOWN,
164                                           NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
165                                           XIC,YIC-2,
166                                           &(showsliders), 0, 0, 0, 0, 
167                                           "Hide action window sliders");
168                 // no hilite, the winmatrix is not correct later on...
169                 uiButSetFlag(but, UI_NO_HILITE);
170                                           
171                 ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
172
173                 /* sliders are open so draw them */
174                 BIF_ThemeColor(TH_FACE); 
175
176                 glRects(NAMEWIDTH,  0,  NAMEWIDTH+SLIDERWIDTH,  curarea->winy);
177                 uiBlockSetEmboss(block, UI_EMBOSS);
178                 for (i=1 ; i < key->totkey ; ++ i) {
179                         make_rvk_slider(block, key, i, 
180                                                         x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1);
181
182                         y-=CHANNELHEIGHT+CHANNELSKIP;
183                         
184                 }
185         }
186         uiDrawBlock(block);
187
188 }
189
190 void draw_cfra_action(void)
191 {
192         Object *ob;
193         float vec[2];
194         
195         vec[0]= (G.scene->r.cfra);
196         vec[0]*= G.scene->r.framelen;
197         
198         vec[1]= G.v2d->cur.ymin;
199         glColor3ub(0x60, 0xc0, 0x40);
200         glLineWidth(2.0);
201         
202         glBegin(GL_LINE_STRIP);
203         glVertex2fv(vec);
204         vec[1]= G.v2d->cur.ymax;
205         glVertex2fv(vec);
206         glEnd();
207         
208         ob= (G.scene->basact) ? (G.scene->basact->object) : 0;
209         if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
210                 vec[0]-= ob->sf;
211                 
212                 glColor3ub(0x10, 0x60, 0);
213                 
214                 glBegin(GL_LINE_STRIP);
215                 glVertex2fv(vec);
216                 vec[1]= G.v2d->cur.ymin;
217                 glVertex2fv(vec);
218                 glEnd();
219         }
220         
221         glLineWidth(1.0);
222 }
223
224
225 static void draw_action_channel_names(bAction   *act) 
226 {
227     bActionChannel *chan;
228     bConstraintChannel *conchan;
229     float       x, y;
230
231     x = 0.0;
232         y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
233
234         for (chan=act->chanbase.first; chan; chan=chan->next){
235                 BIF_ThemeColorShade(TH_HEADER, 20);
236                 glRectf(x,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
237         
238                 if (chan->flag & ACHAN_SELECTED)
239                         BIF_ThemeColor(TH_TEXT_HI);
240                 else
241                         BIF_ThemeColor(TH_TEXT);
242                 glRasterPos2f(x+8,  y-4);
243                 BMF_DrawString(G.font, chan->name);
244                 y-=CHANNELHEIGHT+CHANNELSKIP;
245         
246                 /* Draw constraint channels */
247                 for (conchan=chan->constraintChannels.first; 
248                                 conchan; conchan=conchan->next){
249                         if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
250                                 BIF_ThemeColor(TH_TEXT_HI);
251                         else
252                                 BIF_ThemeColor(TH_TEXT);
253                                 
254                         glRasterPos2f(x+32,  y-4);
255                         BMF_DrawString(G.font, conchan->name);
256                         y-=CHANNELHEIGHT+CHANNELSKIP;
257                 }
258         }
259 }
260
261
262 static void draw_action_mesh_names(Key *key) 
263 {
264         /* draws the names of the rvk keys in the
265          * left side of the action window
266          */
267         int          i;
268         char     keyname[32];
269         float    x, y;
270         KeyBlock *kb;
271
272         x = 0.0;
273         y= key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
274
275         kb= key->block.first;
276
277         for (i=1 ; i < key->totkey ; ++ i) {
278                 glColor3ub(0xAA, 0xAA, 0xAA);
279                 glRectf(x,      y-CHANNELHEIGHT/2,      (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
280
281                 glColor3ub(0, 0, 0);
282
283                 glRasterPos2f(x+8,      y-4);
284                 kb = kb->next;
285                 /* Blender now has support for named
286                  * key blocks. If a name hasn't
287                  * been set for an key block then
288                  * just display the key number -- 
289                  * otherwise display the name stored
290                  * in the keyblock.
291                  */
292                 if (kb->name[0] == '\0') {
293                   sprintf(keyname, "Key %d", i);
294                   BMF_DrawString(G.font, keyname);
295                 }
296                 else {
297                   BMF_DrawString(G.font, kb->name);
298                 }
299
300                 y-=CHANNELHEIGHT+CHANNELSKIP;
301
302         }
303 }
304
305 static void draw_channel_names(void) 
306 {
307         short ofsx, ofsy = 0; 
308         bAction *act;
309         Key *key;
310
311         /* Clip to the scrollable area */
312         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
313                 if(G.v2d->scroll) {     
314                         ofsx= curarea->winrct.xmin;     
315                         ofsy= curarea->winrct.ymin;
316                         glViewport(ofsx,  ofsy+G.v2d->mask.ymin, NAMEWIDTH, 
317                                            (ofsy+G.v2d->mask.ymax) -
318                                            (ofsy+G.v2d->mask.ymin)); 
319                         glScissor(ofsx,  ofsy+G.v2d->mask.ymin, NAMEWIDTH, 
320                                           (ofsy+G.v2d->mask.ymax) -
321                                           (ofsy+G.v2d->mask.ymin));
322                 }
323         }
324         
325         myortho2(0,     NAMEWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax);   //      Scaling
326         
327         glColor3ub(0x00, 0x00, 0x00);
328
329         act=G.saction->action;
330
331         if (act) {
332                 /* if there is a selected action then
333                  * draw the channel names
334                  */
335                 draw_action_channel_names(act);
336         }
337         if ( (key = get_action_mesh_key()) ) {
338                 /* if there is a mesh selected with rvk's,
339                         * then draw the RVK names
340                         */
341                 draw_action_mesh_names(key);
342     }
343
344     myortho2(0, NAMEWIDTH, 0, (ofsy+G.v2d->mask.ymax) -
345               (ofsy+G.v2d->mask.ymin)); //      Scaling
346
347 }
348
349 int count_action_levels(bAction *act)
350 {
351         int y=0;
352         bActionChannel *achan;
353
354         if (!act)
355                 return 0;
356
357         for (achan=act->chanbase.first; achan; achan=achan->next){
358                 y+=1;
359                 y+=BLI_countlist(&achan->constraintChannels);
360         }
361
362         return y;
363 }
364         /** Draw a nicely beveled button (in screen space) */
365 void draw_bevel_but(int x, int y, int w, int h, int sel)
366 {
367         int xmin= x, ymin= y;
368         int xmax= x+w-1, ymax= y+h-1;
369         int i;
370
371         glColor3ub(0,0,0);
372         glBegin(GL_LINE_LOOP);
373         glVertex2i(xmin, ymin);
374         glVertex2i(xmax, ymin);
375         glVertex2i(xmax, ymax);
376         glVertex2i(xmin, ymax);
377         glEnd();
378
379         glBegin(GL_LINE_LOOP);
380         if (sel) glColor3ub(0xD0, 0x7E, 0x06);
381         else glColor3ub(0x8C, 0x8C, 0x8C);
382         glVertex2i(xmax-1, ymin+1);
383         glVertex2i(xmax-1, ymax-1);
384         if (sel) glColor3ub(0xF4, 0xEE, 0x8E);
385         else glColor3ub(0xDF, 0xDF, 0xDF);
386         glVertex2i(xmin+1, ymax-1);
387         glVertex2i(xmin+1, ymin+1);
388         glEnd();
389
390         if (sel) glColor3ub(0xF1, 0xCA, 0x13);
391         else glColor3ub(0xAC, 0xAC, 0xAC);
392         glBegin(GL_LINES);
393         for (i=xmin+2; i<=xmax-2; i++) {
394                 glVertex2f(i, ymin+2);
395                 glVertex2f(i, ymax-1);
396         }
397         glEnd();
398 }
399
400 static void draw_channel_strips(SpaceAction *saction)
401 {
402         rcti scr_rct;
403         gla2DDrawInfo *di;
404         bAction *act;
405         bActionChannel *chan;
406         bConstraintChannel *conchan;
407         float   y;
408         char col1[3], col2[3];
409         
410         BIF_GetThemeColor3ubv(TH_SHADE2, col2);
411         BIF_GetThemeColor3ubv(TH_HILITE, col1);
412
413         act= saction->action;
414         if (!act)
415                 return;
416
417         scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH;
418         scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin;
419         scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
420         scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax; 
421         di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
422
423         y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
424
425         for (chan=act->chanbase.first; chan; chan=chan->next){
426                 int frame1_x, channel_y;
427
428                 gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
429
430                 glEnable(GL_BLEND);
431                 if (chan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x22);
432                 else glColor4b(col2[0], col2[1], col2[2], 0x22);
433                 glRectf(0,  channel_y-CHANNELHEIGHT/2,  frame1_x,  channel_y+CHANNELHEIGHT/2);
434
435                 if (chan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x44);
436                 else glColor4b(col2[0], col2[1], col2[2], 0x44);
437                 glRectf(frame1_x,  channel_y-CHANNELHEIGHT/2,  G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2);
438                 glDisable(GL_BLEND);
439         
440                 draw_ipo_channel(di, chan->ipo, 0, y);
441
442                 /*      Increment the step */
443                 y-=CHANNELHEIGHT+CHANNELSKIP;
444
445
446                 /* Draw constraint channels */
447                 for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
448                         gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
449                         glEnable(GL_BLEND);
450                         if (conchan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x22);
451                         else glColor4b(col2[0], col2[1], col2[2], 0x22);
452                         glRectf(0,  channel_y-CHANNELHEIGHT/2+4,  frame1_x,  channel_y+CHANNELHEIGHT/2-4);
453                         
454                         if (conchan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x44);
455                         else glColor4b(col2[0], col2[1], col2[2], 0x44);
456                         glRectf(frame1_x,  channel_y-CHANNELHEIGHT/2+4,  G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2-4);
457                         glDisable(GL_BLEND);
458                         
459                         draw_ipo_channel(di, conchan->ipo, 0, y);
460                         y-=CHANNELHEIGHT+CHANNELSKIP;
461                 }
462         }
463
464         glaEnd2DDraw(di);
465 }
466
467 static void draw_mesh_strips(SpaceAction *saction, Key *key)
468 {
469         /* draw the RVK keyframes as those little square button things
470          */
471         rcti scr_rct;
472         gla2DDrawInfo *di;
473         float   y, ybase;
474         IpoCurve *icu;
475         char col1[3], col2[3];
476         
477         BIF_GetThemeColor3ubv(TH_SHADE2, col2);
478         BIF_GetThemeColor3ubv(TH_HILITE, col1);
479
480         if (!key->ipo) return;
481
482         scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH;
483         scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin;
484         scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
485         scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax; 
486         di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
487
488         ybase = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
489
490         for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
491
492                 int frame1_x, channel_y;
493
494                 /* lets not deal with the "speed" Ipo
495                  */
496                 if (icu->adrcode==0) continue;
497
498                 y = ybase       - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
499                 gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
500
501                 /* all frames that have a frame number less than one
502                  * get a desaturated orange background
503                  */
504                 glEnable(GL_BLEND);
505                 glColor4b(col2[0], col2[1], col2[2], 0x22);
506                 glRectf(0,        channel_y-CHANNELHEIGHT/2,  
507                                 frame1_x, channel_y+CHANNELHEIGHT/2);
508
509                 /* frames one and higher get a saturated orange background
510                  */
511                 glColor4b(col2[0], col2[1], col2[2], 0x44);
512                 glRectf(frame1_x,         channel_y-CHANNELHEIGHT/2,  
513                                 G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2);
514                 glDisable(GL_BLEND);
515
516                 /* draw the little squares
517                  */
518                 draw_icu_channel(di, icu, 0, y); 
519         }
520
521         glaEnd2DDraw(di);
522 }
523
524 /* ********* action panel *********** */
525
526
527 void do_actionbuts(unsigned short event)
528 {
529         switch(event) {
530         case REDRAWVIEW3D:
531                 allqueue(REDRAWVIEW3D, 0);
532                 break;
533         case B_REDR:
534                 allqueue(REDRAWACTION, 0);
535                 break;
536         }
537 }
538
539
540 static void action_panel_properties(short cntrl)        // ACTION_HANDLER_PROPERTIES
541 {
542         uiBlock *block;
543
544         block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
545         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
546         uiSetPanelHandler(ACTION_HANDLER_PROPERTIES);  // for close and esc
547         if(uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0) return;
548
549         uiDefBut(block, LABEL, 0, "test text",          10,180,300,19, 0, 0, 0, 0, 0, "");
550
551 }
552
553 static void action_blockhandlers(ScrArea *sa)
554 {
555         SpaceAction *sact= sa->spacedata.first;
556         short a;
557         
558         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
559                 switch(sact->blockhandler[a]) {
560
561                 case ACTION_HANDLER_PROPERTIES:
562                         action_panel_properties(sact->blockhandler[a+1]);
563                         break;
564                 
565                 }
566                 /* clear action value for event */
567                 sact->blockhandler[a+1]= 0;
568         }
569         uiDrawBlocksPanels(sa, 0);
570 }
571
572 void drawactionspace(ScrArea *sa, void *spacedata)
573 {
574         short ofsx = 0, ofsy = 0;
575         Key *key;
576         float col[3];
577         short maxymin;
578
579         if (!G.saction)
580                 return;
581
582         /* warning; blocks need to be freed each time, handlers dont remove  */
583         uiFreeBlocksWin(&sa->uiblocks, sa->win);
584
585         if (!G.saction->pin) {
586                 if (OBACT)
587                         G.saction->action = OBACT->action;
588                 else
589                         G.saction->action=NULL;
590         }
591         key = get_action_mesh_key();
592
593         /* Damn I hate hunting to find my rvk's because
594          * they have scrolled off of the screen ... this
595          * oughta fix it
596          */
597                    
598         if (key) {
599                 if (G.v2d->cur.ymin < -CHANNELHEIGHT) 
600                         G.v2d->cur.ymin = -CHANNELHEIGHT;
601                 
602                 maxymin = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
603                 if (G.v2d->cur.ymin > maxymin) G.v2d->cur.ymin = maxymin;
604         }
605
606         /* Lets make sure the width of the left hand of the screen
607          * is set to an appropriate value based on whether sliders
608          * are showing of not
609          */
610         if (key && showsliders) ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
611         else ACTWIDTH = NAMEWIDTH;
612
613         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
614
615         calc_scrollrcts(sa, G.v2d, curarea->winx, curarea->winy);
616
617         /* background color for entire window (used in lefthand part tho) */
618         BIF_GetThemeColor3fv(TH_HEADER, col);
619         glClearColor(col[0], col[1], col[2], 0.0); 
620         glClear(GL_COLOR_BUFFER_BIT);
621         
622         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
623                 if(G.v2d->scroll) {     
624                         ofsx= curarea->winrct.xmin;     
625                         ofsy= curarea->winrct.ymin;
626                         glViewport(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, 
627                                            ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
628                                            ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); 
629                         glScissor(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, 
630                                           ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
631                                           ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
632                 }
633         }
634
635         BIF_GetThemeColor3fv(TH_BACK, col);
636         glClearColor(col[0], col[1], col[2], 0.0);
637         glClear(GL_COLOR_BUFFER_BIT);
638
639         myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
640         bwin_clear_viewmat(sa->win);    /* clear buttons view */
641         glLoadIdentity();
642
643         /*      Draw backdrop */
644         calc_ipogrid(); 
645         draw_ipogrid();
646
647         /* Draw channel strips */
648         draw_channel_strips(G.saction);
649
650         if (key) {
651                 /* if there is a mesh with rvk's selected,
652                  * then draw the key frames in the action window
653                  */
654                 draw_mesh_strips(G.saction, key);
655                 /*meshactionbuts(G.saction, key);*/
656         }
657
658
659         /* Draw current frame */
660         glViewport(ofsx+G.v2d->mask.xmin,  
661              ofsy+G.v2d->mask.ymin, 
662              ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
663              ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); 
664         glScissor(ofsx+G.v2d->mask.xmin,  
665             ofsy+G.v2d->mask.ymin, 
666             ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
667             ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
668         myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax,  G.v2d->cur.ymin, G.v2d->cur.ymax);
669         draw_cfra_action();
670
671         /* Draw scroll */
672         mywinset(curarea->win); // reset scissor too
673         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
674       myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
675       if(G.v2d->scroll) drawscroll(0);
676         }
677
678         /* Draw channel names */
679         draw_channel_names();
680
681         if ( key ) {
682                 /* if there is a mesh with rvk's selected,
683                  * then draw the key frames in the action window
684                  */
685                 meshactionbuts(G.saction, key);
686         }
687
688         mywinset(curarea->win); // reset scissor too
689         myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
690         draw_area_emboss(sa);
691
692         /* it is important to end a view in a transform compatible with buttons */
693         bwin_scalematrix(sa->win, G.saction->blockscale, G.saction->blockscale, G.saction->blockscale);
694         action_blockhandlers(sa);
695
696         curarea->win_swap= WIN_BACK_OK;
697 }
698
699
700 void draw_channel_name(const char* name, short type, float ypos, int selected)
701 {
702 }
703
704 static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos)
705 {
706         int v;
707
708         if (!blist)
709                 return;
710
711         for (v = 0; v<totvert; v++){
712                 if (v==0 || (blist[v]->vec[1][0] != blist[v-1]->vec[1][0])){
713                         int sc_x, sc_y;
714                         gla2DDrawTranslatePt(di, blist[v]->vec[1][0], ypos, &sc_x, &sc_y);
715                         draw_bevel_but(sc_x-2, sc_y-5, 7, 13, (blist[v]->f2 & 1));
716                 }
717         }                       
718 }
719
720 void draw_object_channel(gla2DDrawInfo *di, Object *ob, int flags, float ypos)
721 {
722         BezTriple **blist;
723         int totvert;
724
725         blist = ob_to_keylist(ob, flags, &totvert);
726         if (blist){
727                 draw_keylist(di,totvert, blist, ypos);
728                 MEM_freeN(blist);
729         }
730 }
731
732 void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, int flags, float ypos)
733 {
734         BezTriple **blist;
735         int totvert;
736
737         blist = ipo_to_keylist(ipo, flags, &totvert);
738         if (blist){
739                 draw_keylist(di,totvert, blist, ypos);
740                 MEM_freeN(blist);
741         }
742 }
743
744 void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos)
745 {
746         /* draw the keys for an IpoCurve
747          */
748         BezTriple **blist;
749         int totvert;
750
751         blist = icu_to_keylist(icu, flags, &totvert);
752         if (blist){
753                 draw_keylist(di,totvert, blist, ypos);
754                 MEM_freeN(blist);
755         }
756 }
757
758 void draw_action_channel(gla2DDrawInfo *di, bAction *act, int flags, float ypos)
759 {
760         BezTriple **blist;
761         int totvert;
762
763         blist = action_to_keylist(act, flags, &totvert);
764         if (blist){
765                 draw_keylist(di,totvert, blist, ypos);
766                 MEM_freeN(blist);
767         }
768 }
769
770 static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert)
771 {
772         IpoCurve *icu;
773         int v, count=0;
774
775         BezTriple **list = NULL;
776
777         if (ob){
778
779                 /* Count Object Keys */
780                 if (ob->ipo){
781                         for (icu=ob->ipo->curve.first; icu; icu=icu->next){
782                                 count+=icu->totvert;
783                         }
784                 }
785                 
786                 /* Count Constraint Keys */
787                 /* Count object data keys */
788
789                 /* Build the list */
790                 if (count){
791                         list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
792                         count=0;
793                         
794                         /* Add object keyframes */
795                         for (icu=ob->ipo->curve.first; icu; icu=icu->next){
796                                 for (v=0; v<icu->totvert; v++){
797                                         list[count++]=&icu->bezt[v];
798                                 }
799                         }
800                         
801                         /* Add constraint keyframes */
802                         /* Add object data keyframes */
803
804                         /* Sort */
805                         qsort(list, count, sizeof(BezTriple*), bezt_compare);
806                 }
807         }
808         (*totvert)=count;
809         return list;
810 }
811
812 static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert)
813 {
814         /* compile a list of all bezier triples in an
815          * IpoCurve.
816          */
817         int v, count = 0;
818
819         BezTriple **list = NULL;
820
821         count=icu->totvert;
822
823         if (count){
824                 list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
825                 count=0;
826                         
827                 for (v=0; v<icu->totvert; v++){
828                         list[count++]=&icu->bezt[v];
829                 }
830                 qsort(list, count, sizeof(BezTriple*), bezt_compare);
831         }
832         (*totvert)=count;
833         return list;
834
835 }
836
837 static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert)
838 {
839         IpoCurve *icu;
840         int v, count=0;
841
842         BezTriple **list = NULL;
843
844         if (ipo){
845                 /* Count required keys */
846                 for (icu=ipo->curve.first; icu; icu=icu->next){
847                         count+=icu->totvert;
848                 }
849                 
850                 /* Build the list */
851                 if (count){
852                         list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
853                         count=0;
854                         
855                         for (icu=ipo->curve.first; icu; icu=icu->next){
856                                 for (v=0; v<icu->totvert; v++){
857                                         list[count++]=&icu->bezt[v];
858                                 }
859                         }                       
860                         qsort(list, count, sizeof(BezTriple*), bezt_compare);
861                 }
862         }
863         (*totvert)=count;
864         return list;
865 }
866
867 static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert)
868 {
869         IpoCurve *icu;
870         bActionChannel *achan;
871         bConstraintChannel *conchan;
872         int v, count=0;
873
874         BezTriple **list = NULL;
875
876         if (act){
877                 /* Count required keys */
878                 for (achan=act->chanbase.first; achan; achan=achan->next){
879                         /* Count transformation keys */
880                         if(achan->ipo) {
881                                 for (icu=achan->ipo->curve.first; icu; icu=icu->next)
882                                         count+=icu->totvert;
883                                 
884                                 /* Count constraint keys */
885                                 for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
886                                         for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
887                                                 count+=icu->totvert;
888                                 
889                         }
890                 }
891                 
892                 /* Build the list */
893                 if (count){
894                         list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
895                         count=0;
896                         
897                         for (achan=act->chanbase.first; achan; achan=achan->next){
898                                 /* Add transformation keys */
899                                 for (icu=achan->ipo->curve.first; icu; icu=icu->next){
900                                         for (v=0; v<icu->totvert; v++)
901                                                 list[count++]=&icu->bezt[v];
902                                 }
903                                         
904                                         /* Add constraint keys */
905                                 for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
906                                         for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
907                                                 for (v=0; v<icu->totvert; v++)
908                                                         list[count++]=&icu->bezt[v];
909                                 }
910                                                         
911                         }               
912                         qsort(list, count, sizeof(BezTriple*), bezt_compare);
913                         
914                 }
915         }
916         (*totvert)=count;
917         return list;
918 }
919