Modified interface texture font support, which should work nicely with the freshly...
[blender.git] / source / blender / src / header_action.c
1 /**
2  * header_action.c oct-2003
3  *
4  * Functions to draw the "Action Editor" window header
5  * and handle user events sent to it.
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version. The Blender
15  * Foundation also sells licenses for use in proprietary software under
16  * the Blender License.  See http://www.blender.org/BL/ for information
17  * about this.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
27  *
28  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29  * All rights reserved.
30  *
31  * The Original Code is: all of this file.
32  *
33  * Contributor(s): none yet.
34  *
35  * ***** END GPL/BL DUAL LICENSE BLOCK *****
36  */
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include <stdio.h>
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #ifdef WIN32
47 #include "BLI_winstuff.h"
48 #endif
49
50 #include "DNA_ID.h"
51 #include "DNA_action_types.h"
52 #include "DNA_ipo_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_screen_types.h"
56 #include "DNA_space_types.h"
57 #include "DNA_key_types.h"
58 #include "DNA_curve_types.h"
59
60 #include "BIF_interface.h"
61 #include "BIF_resources.h"
62 #include "BIF_screen.h"
63 #include "BIF_space.h"
64 #include "BIF_editaction.h"
65
66 #include "BKE_action.h"
67 #include "BKE_global.h"
68 #include "BKE_main.h"
69 #include "BKE_constraint.h"
70 #include "BKE_armature.h"
71 #include "BKE_utildefines.h"
72
73 #include "BSE_drawipo.h"
74 #include "BSE_editaction.h"
75 #include "BSE_headerbuttons.h"
76
77 #include "nla.h"
78
79 #include "blendef.h"
80 #include "mydevice.h"
81
82 #define ACTMENU_VIEW_CENTERVIEW 0
83 #define ACTMENU_VIEW_AUTOUPDATE 1
84 #define ACTMENU_VIEW_PLAY3D     2
85 #define ACTMENU_VIEW_PLAYALL    3
86 #define ACTMENU_VIEW_ALL        4
87 #define ACTMENU_VIEW_MAXIMIZE   5
88
89 #define ACTMENU_SEL_BORDER      0
90 #define ACTMENU_SEL_ALL_KEYS    1
91 #define ACTMENU_SEL_ALL_CHAN    2
92
93 #define ACTMENU_KEY_DUPLICATE     0
94 #define ACTMENU_KEY_DELETE        1
95 #define ACTMENU_KEY_BAKE          2
96
97 #define ACTMENU_KEY_TRANSFORM_MOVE      0
98 #define ACTMENU_KEY_TRANSFORM_SCALE     1
99
100 #define ACTMENU_KEY_HANDLE_AUTO   0
101 #define ACTMENU_KEY_HANDLE_ALIGN  1
102 #define ACTMENU_KEY_HANDLE_FREE   2
103 #define ACTMENU_KEY_HANDLE_VECTOR 3
104
105 #define ACTMENU_KEY_INTERP_CONST  0
106 #define ACTMENU_KEY_INTERP_LINEAR 1
107 #define ACTMENU_KEY_INTERP_BEZIER 2
108
109 void do_action_buttons(unsigned short event)
110 {
111
112         switch(event){
113                 case B_ACTBAKE:
114                         bake_action_with_client (G.saction->action, OBACT, 0.01);
115                         break;
116                 case B_ACTCONT:
117                         set_exprap_action(IPO_HORIZ);
118                         break;
119 //      case B_ACTEXTRAP:
120 //              set_exprap_ipo(IPO_DIR);
121 //              break;
122                 case B_ACTCYCLIC:
123                         set_exprap_action(IPO_CYCL);
124                         break;
125 //      case B_ACTCYCLICX:
126 //              set_exprap_ipo(IPO_CYCLX);
127 //              break;
128                 case B_ACTHOME:
129                         //      Find X extents
130                         //v2d= &(G.saction->v2d);
131
132                         G.v2d->cur.xmin = 0;
133                         G.v2d->cur.ymin=-SCROLLB;
134
135                         if (!G.saction->action){        // here the mesh rvk?
136                                 G.v2d->cur.xmax= -5;
137                                 G.v2d->cur.xmax= 100;
138                         }
139                         else {
140                                 float extra;
141                                 G.v2d->cur.xmin= calc_action_start(G.saction->action);
142                                 G.v2d->cur.xmax= calc_action_end(G.saction->action);
143                                 extra= 0.05*(G.v2d->cur.xmax - G.v2d->cur.xmin);
144                                 G.v2d->cur.xmin-= extra;
145                                 G.v2d->cur.xmax+= extra;
146                                 
147                                 if(G.v2d->cur.xmin==G.v2d->cur.xmax) {
148                                         G.v2d->cur.xmax= -5;
149                                         G.v2d->cur.xmax= 100;
150                                 }
151                         }
152
153                         G.v2d->tot= G.v2d->cur;
154                         test_view2d(G.v2d, curarea->winx, curarea->winy);
155
156
157                         addqueue (curarea->win, REDRAW, 1);
158
159                         break;
160                 case B_ACTCOPY:
161                         copy_posebuf();
162                         allqueue(REDRAWVIEW3D, 1);
163                         break;
164                 case B_ACTPASTE:
165                         paste_posebuf(0);
166                         clear_object_constraint_status(OBACT);
167                         make_displists_by_armature(OBACT);
168                         allqueue(REDRAWVIEW3D, 1);
169                         break;
170                 case B_ACTPASTEFLIP:
171                         paste_posebuf(1);
172                         clear_object_constraint_status(OBACT);
173                         make_displists_by_armature(OBACT);
174                         allqueue(REDRAWVIEW3D, 1);
175                         break;
176
177                 case B_ACTPIN:  /* __PINFAKE */
178 /*              if (G.saction->flag & SACTION_PIN){
179                 if (G.saction->action)
180                 G.saction->action->id.us ++;
181                 
182                 }
183                 else {
184                         if (G.saction->action)
185                                 G.saction->action->id.us --;
186                                 }
187 */              /* end PINFAKE */
188                         allqueue(REDRAWACTION, 1);
189                         break;
190
191         }
192 }
193
194 static void do_action_viewmenu(void *arg, int event)
195 {
196         extern int play_anim(int mode);
197
198         switch(event) {
199                 case ACTMENU_VIEW_CENTERVIEW: /* Center View to Current Frame */
200                         center_currframe();
201                         break;
202                 case ACTMENU_VIEW_AUTOUPDATE: /* Update Automatically */
203                         if (BTST(G.saction->lock, 0)) 
204                                 G.saction->lock = BCLR(G.saction->lock, 0);
205                         else 
206                                 G.saction->lock = BSET(G.saction->lock, 0);
207                         break;
208                 case ACTMENU_VIEW_PLAY3D: /* Play Back Animation */
209                         play_anim(0);
210                         break;
211                 case ACTMENU_VIEW_PLAYALL: /* Play Back Animation in All */
212                         play_anim(1);
213                         break;  
214                 case ACTMENU_VIEW_ALL: /* View All */
215                         do_action_buttons(B_ACTHOME);
216                         break;
217                 case ACTMENU_VIEW_MAXIMIZE: /* Maximize Window */
218                         /* using event B_FULL */
219                         break;
220         }
221         allqueue(REDRAWVIEW3D, 0);
222 }
223
224 static uiBlock *action_viewmenu(void *arg_unused)
225 {
226         uiBlock *block;
227         short yco= 0, menuwidth=120;
228         
229         block= uiNewBlock(&curarea->uiblocks, "action_viewmenu", 
230                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
231         uiBlockSetButmFunc(block, do_action_viewmenu, NULL);
232         
233         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
234                                          "Center View to Current Frame|C", 0, yco-=20, 
235                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
236                                          ACTMENU_VIEW_CENTERVIEW, "");
237         
238         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
239                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
240         
241         if(BTST(G.saction->lock, 0)) {
242                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, 
243                                                  "Update Automatically|", 0, yco-=20, 
244                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
245                                                  ACTMENU_VIEW_AUTOUPDATE, "");
246         } 
247         else {
248                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, 
249                                                  "Update Automatically|", 0, yco-=20, 
250                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
251                                                  ACTMENU_VIEW_AUTOUPDATE, "");
252         }
253
254         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
255                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
256         
257         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
258                                          "Play Back Animation|Alt A", 0, yco-=20, 
259                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
260                                          ACTMENU_VIEW_PLAY3D, "");
261         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
262                                          "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
263                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
264                                          ACTMENU_VIEW_PLAYALL, "");
265
266         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
267                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
268         
269         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
270                                          "View All|Home", 0, yco-=20, 
271                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
272                                          ACTMENU_VIEW_ALL, "");
273                 
274         if (!curarea->full) 
275                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, 
276                                                  "Maximize Window|Ctrl UpArrow", 0, yco-=20, 
277                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
278                                                  ACTMENU_VIEW_MAXIMIZE, "");
279         else 
280                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, 
281                                                  "Tile Window|Ctrl DownArrow", 0, yco-=20, 
282                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
283                                                  ACTMENU_VIEW_MAXIMIZE, "");
284         
285         if(curarea->headertype==HEADERTOP) {
286                 uiBlockSetDirection(block, UI_DOWN);
287         }
288         else {
289                 uiBlockSetDirection(block, UI_TOP);
290                 uiBlockFlipOrder(block);
291         }
292
293         uiTextBoundsBlock(block, 50);
294         
295         return block;
296 }
297
298 static void do_action_selectmenu(void *arg, int event)
299 {       
300         SpaceAction *saction;
301         bAction *act;
302         Key *key;
303         
304         saction = curarea->spacedata.first;
305         if (!saction)
306                 return;
307
308         act = saction->action;
309         key = get_action_mesh_key();
310         
311         switch(event)
312         {
313                 case ACTMENU_SEL_BORDER: /* Border Select */
314                         if (key) {
315                                 borderselect_mesh(key);
316                         }
317                         else {
318                                 borderselect_action();
319                         }
320                         break;
321
322                 case ACTMENU_SEL_ALL_KEYS: /* Select/Deselect All Keys */
323                         if (key) {
324                                 deselect_meshchannel_keys(key, 1);
325                                 allqueue (REDRAWACTION, 0);
326                                 allqueue(REDRAWNLA, 0);
327                                 allqueue (REDRAWIPO, 0);
328                         }
329                         else {
330                                 deselect_actionchannel_keys (act, 1);
331                                 allqueue (REDRAWACTION, 0);
332                                 allqueue(REDRAWNLA, 0);
333                                 allqueue (REDRAWIPO, 0);
334                         }
335                         break;
336
337                 case ACTMENU_SEL_ALL_CHAN: /* Select/Deselect All Channels */
338                         deselect_actionchannels (act, 1);
339                         allqueue (REDRAWVIEW3D, 0);
340                         allqueue (REDRAWACTION, 0);
341                         allqueue(REDRAWNLA, 0);
342                         allqueue (REDRAWIPO, 0);
343                         break;
344         }
345 }
346
347 static uiBlock *action_selectmenu(void *arg_unused)
348 {
349         uiBlock *block;
350         short yco= 0, menuwidth=120;
351
352         block= uiNewBlock(&curarea->uiblocks, "action_selectmenu", 
353                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
354         uiBlockSetButmFunc(block, do_action_selectmenu, NULL);
355
356         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
357                                          "Border Select|B", 0, yco-=20, 
358                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
359                                          ACTMENU_SEL_BORDER, "");
360         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
361                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
362         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
363                                          "Select/Deselect All Keys|A", 0, yco-=20, 
364                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
365                                          ACTMENU_SEL_ALL_KEYS, "");
366         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
367                                          "Select/Deselect All Channels", 0, yco-=20, 
368                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
369                                          ACTMENU_SEL_ALL_CHAN, "");
370
371         if(curarea->headertype==HEADERTOP) {
372                 uiBlockSetDirection(block, UI_DOWN);
373         }
374         else {
375                 uiBlockSetDirection(block, UI_TOP);
376                 uiBlockFlipOrder(block);
377         }
378
379         uiTextBoundsBlock(block, 50);
380
381         return block;
382 }
383
384 static void do_action_keymenu_transformmenu(void *arg, int event)
385 {
386         SpaceAction *saction;
387         bAction *act;
388         Key *key;
389         
390         key = get_action_mesh_key();
391         saction= curarea->spacedata.first;
392         
393         act=saction->action;
394         
395         switch(event)
396         {
397                 case ACTMENU_KEY_TRANSFORM_MOVE:
398                         if (key) {
399                                 transform_meshchannel_keys('g', key);
400                         } 
401                         else if (act) { 
402                                 transform_actionchannel_keys ('g');
403                         }
404                         break;
405                 case ACTMENU_KEY_TRANSFORM_SCALE:
406                         if (key) {
407                                 transform_meshchannel_keys('s', key);
408                         } 
409                         else if (act) {
410                                 transform_actionchannel_keys ('s');
411                         }
412                         break;
413         }
414
415         scrarea_queue_winredraw(curarea);
416 }
417
418 static uiBlock *action_keymenu_transformmenu(void *arg_unused)
419 {
420         uiBlock *block;
421         short yco= 0, menuwidth=120;
422
423         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_transformmenu", 
424                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
425         uiBlockSetButmFunc(block, do_action_keymenu_transformmenu, NULL);
426
427         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
428                                          "Grab/Move|G", 0, yco-=20, 
429                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
430                                          ACTMENU_KEY_TRANSFORM_MOVE, "");
431         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
432                                          "Scale|S", 0, yco-=20, 
433                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
434                                          ACTMENU_KEY_TRANSFORM_SCALE, "");
435
436         uiBlockSetDirection(block, UI_RIGHT);
437         uiTextBoundsBlock(block, 60);
438
439         return block;
440 }
441
442 static void do_action_keymenu_handlemenu(void *arg, int event)
443 {
444         Key *key;
445         
446         key = get_action_mesh_key();
447
448         switch (event){
449                 case ACTMENU_KEY_HANDLE_AUTO:
450                         if (key) {
451                                 sethandles_meshchannel_keys(HD_AUTO, key);
452                         } else {
453                                 sethandles_actionchannel_keys(HD_AUTO);
454                         }
455                         break;
456
457                 case ACTMENU_KEY_HANDLE_ALIGN:
458                 case ACTMENU_KEY_HANDLE_FREE:
459                         /* OK, this is kinda dumb, need to fix the
460                          * toggle crap in sethandles_ipo_keys() 
461                          */
462                         if (key) {
463                                 sethandles_meshchannel_keys(HD_ALIGN, key);
464                         } else {
465                                 sethandles_actionchannel_keys(HD_ALIGN);
466                         }
467                         break;
468
469                 case ACTMENU_KEY_HANDLE_VECTOR:
470                         if (key) {
471                                 sethandles_meshchannel_keys(HD_VECT, key);
472                         } else {
473                                 sethandles_actionchannel_keys(HD_VECT);
474                         }
475                         break;
476         }
477 }
478
479 static uiBlock *action_keymenu_handlemenu(void *arg_unused)
480 {
481         uiBlock *block;
482         short yco= 0, menuwidth=120;
483
484         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_handlemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
485         uiBlockSetButmFunc(block, do_action_keymenu_handlemenu, NULL);
486
487         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
488                                          "Auto|Shift H", 0, yco-=20, 
489                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
490                                          ACTMENU_KEY_HANDLE_AUTO, "");
491         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
492                                          "Aligned|H", 0, yco-=20, 
493                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
494                                          ACTMENU_KEY_HANDLE_ALIGN, "");
495         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
496                                          "Free|H", 0, yco-=20, menuwidth, 
497                                          19, NULL, 0.0, 0.0, 0, 
498                                          ACTMENU_KEY_HANDLE_FREE, "");
499         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
500                                          "Vector|V", 0, yco-=20, 
501                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
502                                          ACTMENU_KEY_HANDLE_VECTOR, "");
503
504         uiBlockSetDirection(block, UI_RIGHT);
505         uiTextBoundsBlock(block, 60);
506
507         return block;
508 }
509
510 static void do_action_keymenu_intpolmenu(void *arg, int event)
511 {
512         Key *key;
513
514         key = get_action_mesh_key();
515
516         switch(event)
517         {
518                 case ACTMENU_KEY_INTERP_CONST:
519                         if (key) {
520                                 /* to do */
521                         }
522                         else {
523                                 set_ipotype_actionchannels(SET_IPO_CONSTANT);
524                         }
525                         break;
526                 case ACTMENU_KEY_INTERP_LINEAR:
527                         if (key) {
528                                 /* to do */
529                         }
530                         else {
531                                 set_ipotype_actionchannels(SET_IPO_LINEAR);
532                         }
533                         break;
534                 case ACTMENU_KEY_INTERP_BEZIER:
535                         if (key) {
536                                 /* to do */
537                         }
538                         else {
539                                 set_ipotype_actionchannels(SET_IPO_BEZIER);
540                         }
541                         break;
542         }
543
544         scrarea_queue_winredraw(curarea);
545 }
546
547 static uiBlock *action_keymenu_intpolmenu(void *arg_unused)
548 {
549         uiBlock *block;
550         short yco= 0, menuwidth=120;
551
552         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_intpolmenu", 
553                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
554         uiBlockSetButmFunc(block, do_action_keymenu_intpolmenu, NULL);
555
556         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
557                                          "Constant", 0, yco-=20, 
558                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
559                                          ACTMENU_KEY_INTERP_CONST, "");
560         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
561                                          "Linear", 0, yco-=20, 
562                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
563                                          ACTMENU_KEY_INTERP_LINEAR, "");
564         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
565                                          "Bezier", 0, yco-=20, 
566                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
567                                          ACTMENU_KEY_INTERP_BEZIER, "");
568
569         uiBlockSetDirection(block, UI_RIGHT);
570         uiTextBoundsBlock(block, 60);
571
572         return block;
573 }
574
575 static void do_action_keymenu(void *arg, int event)
576 {       
577         SpaceAction *saction;
578         bAction *act;
579         Key *key;
580         
581         saction= curarea->spacedata.first;
582         if (!saction)
583                 return;
584
585         act = saction->action;
586         key = get_action_mesh_key();
587
588         switch(event)
589         {
590                 case ACTMENU_KEY_DUPLICATE:
591                         if (key) {
592                                 duplicate_meshchannel_keys(key);
593                         }
594                         else if (act) {
595                                 duplicate_actionchannel_keys();
596                                 remake_action_ipos(act);
597                         }
598                         break;
599
600                 case ACTMENU_KEY_DELETE:
601                         if (key) {
602                                 delete_meshchannel_keys(key);
603                         }
604                         else if (act) {
605                                 delete_actionchannel_keys ();
606                         }
607                         break;
608                 case ACTMENU_KEY_BAKE:
609                         bake_action_with_client (G.saction->action, OBACT, 0.01);
610                         break;
611         }
612 }
613
614 static uiBlock *action_keymenu(void *arg_unused)
615 {
616         uiBlock *block;
617         short yco= 0, menuwidth=120;
618
619         block= uiNewBlock(&curarea->uiblocks, "action_keymenu", 
620                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
621         uiBlockSetButmFunc(block, do_action_keymenu, NULL);
622         
623         uiDefIconTextBlockBut(block, action_keymenu_transformmenu, 
624                                         NULL, ICON_RIGHTARROW_THIN, 
625                                         "Transform", 0, yco-=20, 120, 20, "");
626                                                   
627         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
628                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
629
630         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
631                                         "Duplicate|Shift D", 0, yco-=20, 
632                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
633                                         ACTMENU_KEY_DUPLICATE, "");
634         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
635                                         "Delete|X", 0, yco-=20, 
636                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
637                                         ACTMENU_KEY_DELETE, "");
638
639         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
640                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
641
642         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
643                                          "Bake Action to Ipo Keys", 0, yco-=20, 
644                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
645                                          ACTMENU_KEY_BAKE, "");
646
647         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
648                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
649
650         uiDefIconTextBlockBut(block, action_keymenu_intpolmenu, 
651                                                   NULL, ICON_RIGHTARROW_THIN, 
652                                                   "Interpolation Mode", 0, yco-=20, 120, 20, "");
653         uiDefIconTextBlockBut(block, action_keymenu_handlemenu, 
654                                                   NULL, ICON_RIGHTARROW_THIN, 
655                                                   "Handle Type", 0, yco-=20, 120, 20, "");
656         
657         if(curarea->headertype==HEADERTOP) {
658                 uiBlockSetDirection(block, UI_DOWN);
659         }
660         else {
661                 uiBlockSetDirection(block, UI_TOP);
662                 uiBlockFlipOrder(block);
663         }
664
665         uiTextBoundsBlock(block, 50);
666
667         return block;
668 }
669
670 void action_buttons(void)
671 {
672         uiBlock *block;
673         short xco, xmax;
674         char naam[256];
675         Object *ob;
676         ID *from;
677
678         if (!G.saction)
679                 return;
680
681         // copy from drawactionspace....
682         if (!G.saction->pin) {
683                 if (OBACT)
684                         G.saction->action = OBACT->action;
685                 else
686                         G.saction->action=NULL;
687         }
688
689         sprintf(naam, "header %d", curarea->headwin);
690         block= uiNewBlock(&curarea->uiblocks, naam, 
691                                           UI_EMBOSS, UI_HELV, curarea->headwin);
692
693         if (area_is_active_area(curarea)) 
694                 uiBlockSetCol(block, TH_HEADER);
695         else 
696                 uiBlockSetCol(block, TH_HEADERDESEL);
697
698         curarea->butspacetype= SPACE_ACTION;
699         
700         xco = 8;
701         
702         uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, 
703                                           windowtype_pup(), xco, 0, XIC+10, YIC, 
704                                           &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, 
705                                           "Displays Current Window Type. "
706                                           "Click for menu of available types.");
707
708         xco += XIC + 14;
709
710         uiBlockSetEmboss(block, UI_EMBOSSN);
711         if (curarea->flag & HEADER_NO_PULLDOWN) {
712                 uiDefIconButS(block, TOG|BIT|0, B_FLIPINFOMENU, 
713                                           ICON_DISCLOSURE_TRI_RIGHT,
714                                           xco,2,XIC,YIC-2,
715                                           &(curarea->flag), 0, 0, 0, 0, 
716                                           "Show pulldown menus");
717         }
718         else {
719                 uiDefIconButS(block, TOG|BIT|0, B_FLIPINFOMENU, 
720                                           ICON_DISCLOSURE_TRI_DOWN,
721                                           xco,2,XIC,YIC-2,
722                                           &(curarea->flag), 0, 0, 0, 0, 
723                                           "Hide pulldown menus");
724         }
725         uiBlockSetEmboss(block, UI_EMBOSS);
726         xco+=XIC;
727
728         if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
729                 /* pull down menus */
730                 uiBlockSetEmboss(block, UI_EMBOSSP);
731         
732                 xmax= GetButStringLength("View");
733                 uiDefPulldownBut(block, action_viewmenu, NULL, 
734                                           "View", xco, -2, xmax-3, 24, "");
735                 xco+= xmax;
736                 
737                 xmax= GetButStringLength("Select");
738                 uiDefPulldownBut(block, action_selectmenu, NULL, 
739                                           "Select", xco, -2, xmax-3, 24, "");
740                 xco+= xmax;
741         
742                 xmax= GetButStringLength("Key");
743                 uiDefPulldownBut(block, action_keymenu, NULL, 
744                                           "Key", xco, -2, xmax-3, 24, "");
745                 xco+= xmax;
746         }
747
748         uiBlockSetEmboss(block, UI_EMBOSSX);
749         
750         // object action is allowed to be zero!
751         /* (ton) commented out below line, since people can apparently link Action to any object (mesh) and
752                 not unlink anymore when theres a mesh key. Needs to be rethought this stuff! */
753         //if (!get_action_mesh_key()) {
754         
755                 /* NAME ETC */
756                 ob=OBACT;
757                 from = (ID*) ob;
758
759                 xco= std_libbuttons(block, xco, 0, B_ACTPIN, &G.saction->pin, 
760                                                         B_ACTIONBROWSE, (ID*)G.saction->action, 
761                                                         from, &(G.saction->actnr), B_ACTALONE, 
762                                                         B_ACTLOCAL, B_ACTIONDELETE, 0, 0);      
763
764                 /* Draw action baker */
765                 xco+= 8;
766                 
767                 uiDefBut(block, BUT, B_ACTBAKE, 
768                                  "Bake", xco, 0, 64, YIC, 0, 0, 0, 0, 0, 
769                                  "Create an action with the constraint effects "
770                                  "converted into Ipo keys");
771                 xco+=64;
772
773         //}
774         uiClearButLock();
775
776         /* draw LOCK */
777         xco+= 8;
778         uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco, 0, XIC, YIC, 
779                                   &(G.saction->lock), 0, 0, 0, 0, 
780                                   "Updates other affected window spaces automatically "
781                                   "to reflect changes in real time");
782
783
784         /* always as last  */
785         curarea->headbutlen = xco + 2*XIC;
786
787         uiDrawBlock(block);
788 }