Two in one:
[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 #include "DNA_action_types.h"
47 #include "DNA_curve_types.h"
48 #include "DNA_ID.h"
49 #include "DNA_ipo_types.h"
50 #include "DNA_key_types.h"
51 #include "DNA_object_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_screen_types.h"
54 #include "DNA_space_types.h"
55
56 #include "BIF_editaction.h"
57 #include "BIF_interface.h"
58 #include "BIF_poseobject.h"
59 #include "BIF_resources.h"
60 #include "BIF_screen.h"
61 #include "BIF_space.h"
62 #include "BIF_toolbox.h"
63
64 #include "BKE_action.h"
65 #include "BKE_armature.h"
66 #include "BKE_constraint.h"
67 #include "BKE_depsgraph.h"
68 #include "BKE_global.h"
69 #include "BKE_main.h"
70 #include "BKE_utildefines.h"
71
72 #include "BSE_drawipo.h"
73 #include "BSE_headerbuttons.h"
74 #include "BSE_time.h"
75
76 #include "nla.h"
77
78 #include "blendef.h"
79 #include "mydevice.h"
80
81 #define ACTMENU_VIEW_CENTERVIEW 0
82 #define ACTMENU_VIEW_AUTOUPDATE 1
83 #define ACTMENU_VIEW_PLAY3D     2
84 #define ACTMENU_VIEW_PLAYALL    3
85 #define ACTMENU_VIEW_ALL        4
86 #define ACTMENU_VIEW_MAXIMIZE   5
87 #define ACTMENU_VIEW_LOCK               6
88 #define ACTMENU_VIEW_SLIDERS    7
89 #define ACTMENU_VIEW_NEXTMARKER 8
90 #define ACTMENU_VIEW_PREVMARKER 9
91
92 #define ACTMENU_SEL_BORDER                      0
93 #define ACTMENU_SEL_BORDERM                     1
94 #define ACTMENU_SEL_ALL_KEYS                    2
95 #define ACTMENU_SEL_ALL_CHAN                    3
96 #define ACTMENU_SEL_ALL_MARKERS                 4
97 #define ACTMENU_SEL_INVERSE_KEYS                5
98 #define ACTMENU_SEL_INVERSE_MARKERS             6
99
100 #define ACTMENU_SEL_COLUMN_KEYS                         1
101 #define ACTMENU_SEL_COLUMN_MARKERSCOLUMN        2
102 #define ACTMENU_SEL_COLUMN_MARKERSBETWEEN       3
103
104 #define ACTMENU_KEY_DUPLICATE     0
105 #define ACTMENU_KEY_DELETE        1
106 #define ACTMENU_KEY_BAKE          2
107 #define ACTMENU_KEY_CLEAN                 3
108
109 #define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_UP             0
110 #define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_DOWN   1
111 #define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_TOP    2
112 #define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_BOTTOM 3
113
114 #define ACTMENU_KEY_TRANSFORM_MOVE      0
115 #define ACTMENU_KEY_TRANSFORM_SCALE     1
116 #define ACTMENU_KEY_TRANSFORM_SLIDE     2
117
118 #define ACTMENU_KEY_HANDLE_AUTO   0
119 #define ACTMENU_KEY_HANDLE_ALIGN  1
120 #define ACTMENU_KEY_HANDLE_FREE   2
121 #define ACTMENU_KEY_HANDLE_VECTOR 3
122
123 #define ACTMENU_KEY_INTERP_CONST  0
124 #define ACTMENU_KEY_INTERP_LINEAR 1
125 #define ACTMENU_KEY_INTERP_BEZIER 2
126
127 #define ACTMENU_KEY_EXTEND_CONST 0
128 #define ACTMENU_KEY_EXTEND_EXTRAPOLATION 1
129 #define ACTMENU_KEY_EXTEND_CYCLIC 2
130 #define ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION 3
131
132 #define ACTMENU_KEY_SNAP_NEARFRAME  1
133 #define ACTMENU_KEY_SNAP_CURFRAME 2
134
135 #define ACTMENU_KEY_MIRROR_CURFRAME 1
136 #define ACTMENU_KEY_MIRROR_YAXIS 2
137
138 #define ACTMENU_MARKERS_ADD 0
139 #define ACTMENU_MARKERS_DUPLICATE 1
140 #define ACTMENU_MARKERS_DELETE 2
141 #define ACTMENU_MARKERS_NAME 3
142 #define ACTMENU_MARKERS_MOVE 4
143
144 void do_action_buttons(unsigned short event)
145 {
146         Object *ob= OBACT;
147
148         switch(event){
149                 case B_ACTBAKE:
150                         bake_action_with_client (G.saction->action, ob, 0.01);
151                         break;
152                 case B_ACTCONT:
153                         set_exprap_action(IPO_HORIZ);
154                         break;
155 //      case B_ACTEXTRAP:
156 //              set_exprap_ipo(IPO_DIR);
157 //              break;
158                 case B_ACTCYCLIC:
159                         set_exprap_action(IPO_CYCL);
160                         break;
161 //      case B_ACTCYCLICX:
162 //              set_exprap_ipo(IPO_CYCLX);
163 //              break;
164                 case B_ACTHOME:
165                         //      Find X extents
166                         //v2d= &(G.saction->v2d);
167
168                         G.v2d->cur.xmin = 0;
169                         G.v2d->cur.ymin=-SCROLLB;
170
171                         if (!G.saction->action){        // here the mesh rvk?
172                                 G.v2d->cur.xmax= -5;
173                                 G.v2d->cur.xmax= 100;
174                         }
175                         else {
176                                 float extra;
177                                 
178                                 calc_action_range(G.saction->action, &G.v2d->cur.xmin, &G.v2d->cur.xmax, 0);
179                                 if(G.saction->pin==0 && ob) {
180                                         G.v2d->cur.xmin= get_action_frame_inv(ob, G.v2d->cur.xmin);
181                                         G.v2d->cur.xmax= get_action_frame_inv(ob, G.v2d->cur.xmax);
182                                 }                               
183                                 extra= 0.05*(G.v2d->cur.xmax - G.v2d->cur.xmin);
184                                 G.v2d->cur.xmin-= extra;
185                                 G.v2d->cur.xmax+= extra;
186
187                                 if(G.v2d->cur.xmin==G.v2d->cur.xmax) {
188                                         G.v2d->cur.xmax= -5;
189                                         G.v2d->cur.xmax= 100;
190                                 }
191                         }
192                         G.v2d->cur.ymin= 0.0f;
193                         G.v2d->cur.ymax= 1000.0f;
194                         
195                         G.v2d->tot= G.v2d->cur;
196                         test_view2d(G.v2d, curarea->winx, curarea->winy);
197                         view2d_do_locks(curarea, V2D_LOCK_COPY);
198
199                         addqueue (curarea->win, REDRAW, 1);
200
201                         break;
202                 case B_ACTCOPY:
203                         copy_posebuf();
204                         allqueue(REDRAWVIEW3D, 1);
205                         break;
206                 case B_ACTPASTE:
207                         paste_posebuf(0);
208                         allqueue(REDRAWVIEW3D, 1);
209                         break;
210                 case B_ACTPASTEFLIP:
211                         paste_posebuf(1);
212                         allqueue(REDRAWVIEW3D, 1);
213                         break;
214
215                 case B_ACTPIN:  /* __PINFAKE */
216 /*              if (G.saction->flag & SACTION_PIN){
217                 if (G.saction->action)
218                 G.saction->action->id.us ++;
219                 
220                 }
221                 else {
222                         if (G.saction->action)
223                                 G.saction->action->id.us --;
224                                 }
225 */              /* end PINFAKE */
226                         allqueue(REDRAWACTION, 1);
227                         break;
228
229         }
230 }
231
232 static void do_action_viewmenu(void *arg, int event)
233 {
234         extern int play_anim(int mode);
235
236         switch(event) {
237                 case ACTMENU_VIEW_CENTERVIEW: /* Center View to Current Frame */
238                         center_currframe();
239                         break;
240                 case ACTMENU_VIEW_AUTOUPDATE: /* Update Automatically */
241                         if (BTST(G.saction->lock, 0)) 
242                                 G.saction->lock = BCLR(G.saction->lock, 0);
243                         else 
244                                 G.saction->lock = BSET(G.saction->lock, 0);
245                         break;
246                 case ACTMENU_VIEW_PLAY3D: /* Play Back Animation */
247                         play_anim(0);
248                         break;
249                 case ACTMENU_VIEW_PLAYALL: /* Play Back Animation in All */
250                         play_anim(1);
251                         break;  
252                 case ACTMENU_VIEW_ALL: /* View All */
253                         do_action_buttons(B_ACTHOME);
254                         break;
255                 case ACTMENU_VIEW_LOCK:
256                         G.v2d->flag ^= V2D_VIEWLOCK;
257                         if(G.v2d->flag & V2D_VIEWLOCK)
258                                 view2d_do_locks(curarea, 0);
259                         break;
260                 case ACTMENU_VIEW_SLIDERS:       /* Show sliders (when applicable) */
261                         G.saction->flag ^= SACTION_SLIDERS;
262                         break;
263                 case ACTMENU_VIEW_MAXIMIZE: /* Maximize Window */
264                         /* using event B_FULL */
265                         break;
266                 case ACTMENU_VIEW_NEXTMARKER: /* jump to next marker */
267                         nextprev_marker(1);
268                         break;
269                 case ACTMENU_VIEW_PREVMARKER: /* jump to previous marker */
270                         nextprev_marker(-1);
271                         break;
272         }
273         allqueue(REDRAWVIEW3D, 0);
274 }
275
276 static uiBlock *action_viewmenu(void *arg_unused)
277 {
278         uiBlock *block;
279         short yco= 0, menuwidth=120;
280         
281         block= uiNewBlock(&curarea->uiblocks, "action_viewmenu", 
282                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
283         uiBlockSetButmFunc(block, do_action_viewmenu, NULL);
284         
285         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
286                                          "Center View to Current Frame|C", 0, yco-=20, 
287                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
288                                          ACTMENU_VIEW_CENTERVIEW, "");
289                 
290         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
291                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
292         
293         uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_SLIDERS)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
294                                          "Show Sliders|", 0, yco-=20, 
295                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
296                                          ACTMENU_VIEW_SLIDERS, "");
297                                          
298         uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
299                                          "Lock Time to Other Windows|", 0, yco-=20, 
300                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
301                                          ACTMENU_VIEW_LOCK, "");
302                                          
303         uiDefIconTextBut(block, BUTM, 1, BTST(G.saction->lock, 0)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
304                                          "Update Automatically|", 0, yco-=20, 
305                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
306                                          ACTMENU_VIEW_AUTOUPDATE, "");
307
308         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
309                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
310                                          
311         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
312                                 "Jump To Next Marker|PageUp", 0, yco-=20,
313                                 menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_NEXTMARKER, "");
314         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
315                                 "Jump To Prev Marker|PageDown", 0, yco-=20, 
316                                 menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_PREVMARKER, "");
317                                          
318         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
319                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
320                         
321         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
322                                          "Play Back Animation|Alt A", 0, yco-=20, 
323                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
324                                          ACTMENU_VIEW_PLAY3D, "");
325         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
326                                          "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
327                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
328                                          ACTMENU_VIEW_PLAYALL, "");
329
330         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
331                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
332         
333         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
334                                          "View All|Home", 0, yco-=20, 
335                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
336                                          ACTMENU_VIEW_ALL, "");
337         
338         if (!curarea->full) 
339                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, 
340                                                  "Maximize Window|Ctrl UpArrow", 0, yco-=20, 
341                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
342                                                  ACTMENU_VIEW_MAXIMIZE, "");
343         else 
344                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, 
345                                                  "Tile Window|Ctrl DownArrow", 0, yco-=20, 
346                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
347                                                  ACTMENU_VIEW_MAXIMIZE, "");
348         
349         if(curarea->headertype==HEADERTOP) {
350                 uiBlockSetDirection(block, UI_DOWN);
351         }
352         else {
353                 uiBlockSetDirection(block, UI_TOP);
354                 uiBlockFlipOrder(block);
355         }
356
357         uiTextBoundsBlock(block, 50);
358         
359         return block;
360 }
361
362 static void do_action_selectmenu_columnmenu(void *arg, int event)
363 {
364         SpaceAction *saction;
365         bAction *act;
366         Key *key;
367         
368         saction= curarea->spacedata.first;
369         act=saction->action;
370         key = get_action_mesh_key();
371         
372         if (event == ACTMENU_SEL_COLUMN_MARKERSBETWEEN) {
373                 markers_selectkeys_between();
374         }
375         else if (ELEM(event, ACTMENU_SEL_COLUMN_KEYS, ACTMENU_SEL_COLUMN_MARKERSCOLUMN)) {
376                 if (key)
377                         column_select_shapekeys(key, event);
378                 else
379                         column_select_actionkeys(act, event);
380         }
381         else
382                 return;
383                 
384         allqueue(REDRAWTIME, 0);
385         allqueue(REDRAWIPO, 0);
386         allqueue(REDRAWACTION, 0);
387         allqueue(REDRAWNLA, 0);
388         allqueue(REDRAWSOUND, 0);
389 }
390
391 static uiBlock *action_selectmenu_columnmenu(void *arg_unused)
392 {
393         uiBlock *block;
394         short yco= 0, menuwidth=120;
395
396         block= uiNewBlock(&curarea->uiblocks, "action_selectmenu_columnmenu", 
397                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
398         uiBlockSetButmFunc(block, do_action_selectmenu_columnmenu, NULL);
399
400         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
401                                          "On Selected Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,  
402                                          ACTMENU_SEL_COLUMN_KEYS, "");
403         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
404                                          "On Selected Markers|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
405                                          ACTMENU_SEL_COLUMN_MARKERSCOLUMN, "");
406         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
407                                          "Between Selected Markers|Ctrl K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
408                                          ACTMENU_SEL_COLUMN_MARKERSBETWEEN, "");
409         
410         
411         uiBlockSetDirection(block, UI_RIGHT);
412         uiTextBoundsBlock(block, 60);
413
414         return block;
415 }
416
417 static void do_action_selectmenu(void *arg, int event)
418 {       
419         SpaceAction *saction;
420         bAction *act;
421         Key *key;
422         
423         saction = curarea->spacedata.first;
424         if (!saction)
425                 return;
426
427         act = saction->action;
428         key = get_action_mesh_key();
429         
430         switch(event)
431         {
432                 case ACTMENU_SEL_BORDER: /* Border Select */
433                         if (key) {
434                                 borderselect_mesh(key);
435                         }
436                         else {
437                                 borderselect_action();
438                         }
439                         break;
440                         
441                 case ACTMENU_SEL_BORDERM: /* Border Select */
442                         borderselect_markers();
443                         break;
444
445                 case ACTMENU_SEL_ALL_KEYS: /* Select/Deselect All Keys */
446                         if (key) {
447                                 deselect_meshchannel_keys(key, 1, 1);
448                                 allqueue (REDRAWACTION, 0);
449                                 allqueue(REDRAWNLA, 0);
450                                 allqueue (REDRAWIPO, 0);
451                         }
452                         else {
453                                 deselect_actionchannel_keys (act, 1, 1);
454                                 allqueue (REDRAWACTION, 0);
455                                 allqueue(REDRAWNLA, 0);
456                                 allqueue (REDRAWIPO, 0);
457                         }
458                         break;
459
460                 case ACTMENU_SEL_ALL_CHAN: /* Select/Deselect All Channels */
461                         deselect_actionchannels (act, 1);
462                         allqueue (REDRAWVIEW3D, 0);
463                         allqueue (REDRAWACTION, 0);
464                         allqueue(REDRAWNLA, 0);
465                         allqueue (REDRAWIPO, 0);
466                         break;
467                         
468                 case ACTMENU_SEL_ALL_MARKERS: /* select/deselect all markers */
469                         deselect_markers(1, 0);
470                         allqueue(REDRAWTIME, 0);
471                         allqueue(REDRAWIPO, 0);
472                         allqueue(REDRAWACTION, 0);
473                         allqueue(REDRAWNLA, 0);
474                         allqueue(REDRAWSOUND, 0);
475                         break;
476                         
477                 case ACTMENU_SEL_INVERSE_KEYS: /* invert selection status of keys */
478                         if (key) {
479                                 deselect_meshchannel_keys(key, 0, 2);
480                                 allqueue (REDRAWACTION, 0);
481                                 allqueue(REDRAWNLA, 0);
482                                 allqueue (REDRAWIPO, 0);
483                         }
484                         else {
485                                 deselect_actionchannel_keys (act, 0, 2);
486                                 allqueue (REDRAWACTION, 0);
487                                 allqueue(REDRAWNLA, 0);
488                                 allqueue (REDRAWIPO, 0);
489                         }
490                         break;
491                         
492                 case ACTMENU_SEL_INVERSE_MARKERS: /* invert selection of markers */
493                         deselect_markers(0, 2);
494                         allqueue(REDRAWTIME, 0);
495                         allqueue(REDRAWIPO, 0);
496                         allqueue(REDRAWACTION, 0);
497                         allqueue(REDRAWNLA, 0);
498                         allqueue(REDRAWSOUND, 0);
499                         break;
500         }
501 }
502
503 static uiBlock *action_selectmenu(void *arg_unused)
504 {
505         uiBlock *block;
506         short yco= 0, menuwidth=120;
507
508         block= uiNewBlock(&curarea->uiblocks, "action_selectmenu", 
509                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
510         uiBlockSetButmFunc(block, do_action_selectmenu, NULL);
511
512         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
513                                          "Border Select Keys|B", 0, yco-=20, 
514                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
515                                          ACTMENU_SEL_BORDER, "");
516         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
517                                          "Border Select Markers|Ctrl B", 0, yco-=20, 
518                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
519                                          ACTMENU_SEL_BORDERM, "");
520                                          
521         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
522                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
523                          
524         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
525                                          "Select/Deselect All Keys|A", 0, yco-=20, 
526                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
527                                          ACTMENU_SEL_ALL_KEYS, "");
528         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
529                                          "Select/Deselect All Markers|Ctrl A", 0, yco-=20, 
530                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
531                                          ACTMENU_SEL_ALL_MARKERS, "");
532         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
533                                          "Select/Deselect All Channels", 0, yco-=20, 
534                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
535                                          ACTMENU_SEL_ALL_CHAN, "");
536                                          
537         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
538                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
539
540         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
541                                          "Inverse Keys", 0, yco-=20, 
542                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
543                                          ACTMENU_SEL_INVERSE_KEYS, "");
544         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
545                                          "Inverse Markers", 0, yco-=20, 
546                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
547                                          ACTMENU_SEL_INVERSE_MARKERS, "");
548                 
549         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
550                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
551                          
552         uiDefIconTextBlockBut(block, action_selectmenu_columnmenu, 
553                                                   NULL, ICON_RIGHTARROW_THIN, "Column Select Keys", 0, yco-=20, 120, 20, "");
554         
555         if(curarea->headertype==HEADERTOP) {
556                 uiBlockSetDirection(block, UI_DOWN);
557         }
558         else {
559                 uiBlockSetDirection(block, UI_TOP);
560                 uiBlockFlipOrder(block);
561         }
562
563         uiTextBoundsBlock(block, 50);
564
565         return block;
566 }
567
568 static void do_action_keymenu_transformmenu(void *arg, int event)
569 {
570         SpaceAction *saction;
571         bAction *act;
572         Key *key;
573         
574         key = get_action_mesh_key();
575         saction= curarea->spacedata.first;
576         
577         act=saction->action;
578         
579         switch(event)
580         {
581                 case ACTMENU_KEY_TRANSFORM_MOVE:
582                         if (key) {
583                                 transform_meshchannel_keys('g', key);
584                         } 
585                         else if (act) { 
586                                 transform_actionchannel_keys ('g', 0);
587                         }
588                         break;
589                 case ACTMENU_KEY_TRANSFORM_SCALE:
590                         if (key) {
591                                 transform_meshchannel_keys('s', key);
592                         } 
593                         else if (act) {
594                                 transform_actionchannel_keys ('s', 0);
595                         }
596                         break;
597                 case ACTMENU_KEY_TRANSFORM_SLIDE:
598                         if (key) {
599                                 //transform_meshchannel_keys('t', key);
600                         } 
601                         else if (act) {
602                                 transform_actionchannel_keys ('t', 0);
603                         }
604                         break;
605         }
606
607         scrarea_queue_winredraw(curarea);
608 }
609
610 static uiBlock *action_keymenu_transformmenu(void *arg_unused)
611 {
612         uiBlock *block;
613         short yco= 0, menuwidth=120;
614
615         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_transformmenu", 
616                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
617         uiBlockSetButmFunc(block, do_action_keymenu_transformmenu, NULL);
618
619         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
620                                          "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,  
621                                          ACTMENU_KEY_TRANSFORM_MOVE, "");
622         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
623                                          "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
624                                          ACTMENU_KEY_TRANSFORM_SCALE, "");
625         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
626                                          "Time Slide|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
627                                          ACTMENU_KEY_TRANSFORM_SLIDE, "");
628         
629         
630         uiBlockSetDirection(block, UI_RIGHT);
631         uiTextBoundsBlock(block, 60);
632
633         return block;
634 }
635
636 static void do_action_keymenu_handlemenu(void *arg, int event)
637 {
638         Key *key;
639         
640         key = get_action_mesh_key();
641
642         switch (event){
643                 case ACTMENU_KEY_HANDLE_AUTO:
644                         if (key) {
645                                 sethandles_meshchannel_keys(HD_AUTO, key);
646                         } else {
647                                 sethandles_actionchannel_keys(HD_AUTO);
648                         }
649                         break;
650
651                 case ACTMENU_KEY_HANDLE_ALIGN:
652                 case ACTMENU_KEY_HANDLE_FREE:
653                         /* OK, this is kinda dumb, need to fix the
654                          * toggle crap in sethandles_ipo_keys() 
655                          */
656                         if (key) {
657                                 sethandles_meshchannel_keys(HD_ALIGN, key);
658                         } else {
659                                 sethandles_actionchannel_keys(HD_ALIGN);
660                         }
661                         break;
662
663                 case ACTMENU_KEY_HANDLE_VECTOR:
664                         if (key) {
665                                 sethandles_meshchannel_keys(HD_VECT, key);
666                         } else {
667                                 sethandles_actionchannel_keys(HD_VECT);
668                         }
669                         break;
670         }
671 }
672
673 static uiBlock *action_keymenu_handlemenu(void *arg_unused)
674 {
675         uiBlock *block;
676         short yco= 0, menuwidth=120;
677
678         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_handlemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
679         uiBlockSetButmFunc(block, do_action_keymenu_handlemenu, NULL);
680
681         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
682                                          "Auto|Shift H", 0, yco-=20, 
683                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
684                                          ACTMENU_KEY_HANDLE_AUTO, "");
685         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
686                                          "Aligned|H", 0, yco-=20, 
687                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
688                                          ACTMENU_KEY_HANDLE_ALIGN, "");
689         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
690                                          "Free|H", 0, yco-=20, menuwidth, 
691                                          19, NULL, 0.0, 0.0, 0, 
692                                          ACTMENU_KEY_HANDLE_FREE, "");
693         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
694                                          "Vector|V", 0, yco-=20, 
695                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
696                                          ACTMENU_KEY_HANDLE_VECTOR, "");
697
698         uiBlockSetDirection(block, UI_RIGHT);
699         uiTextBoundsBlock(block, 60);
700
701         return block;
702 }
703
704 static void do_action_keymenu_intpolmenu(void *arg, int event)
705 {
706         Key *key;
707
708         key = get_action_mesh_key();
709
710         switch(event)
711         {
712                 case ACTMENU_KEY_INTERP_CONST:
713                         if (key) {
714                                 /* to do */
715                         }
716                         else {
717                                 set_ipotype_actionchannels(SET_IPO_CONSTANT);
718                         }
719                         break;
720                 case ACTMENU_KEY_INTERP_LINEAR:
721                         if (key) {
722                                 /* to do */
723                         }
724                         else {
725                                 set_ipotype_actionchannels(SET_IPO_LINEAR);
726                         }
727                         break;
728                 case ACTMENU_KEY_INTERP_BEZIER:
729                         if (key) {
730                                 /* to do */
731                         }
732                         else {
733                                 set_ipotype_actionchannels(SET_IPO_BEZIER);
734                         }
735                         break;
736         }
737
738         scrarea_queue_winredraw(curarea);
739 }
740
741 static uiBlock *action_keymenu_intpolmenu(void *arg_unused)
742 {
743         uiBlock *block;
744         short yco= 0, menuwidth=120;
745
746         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_intpolmenu", 
747                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
748         uiBlockSetButmFunc(block, do_action_keymenu_intpolmenu, NULL);
749
750         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
751                                          "Constant", 0, yco-=20, 
752                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
753                                          ACTMENU_KEY_INTERP_CONST, "");
754         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
755                                          "Linear", 0, yco-=20, 
756                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
757                                          ACTMENU_KEY_INTERP_LINEAR, "");
758         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
759                                          "Bezier", 0, yco-=20, 
760                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
761                                          ACTMENU_KEY_INTERP_BEZIER, "");
762
763         uiBlockSetDirection(block, UI_RIGHT);
764         uiTextBoundsBlock(block, 60);
765
766         return block;
767 }
768
769 static void do_action_keymenu_extendmenu(void *arg, int event)
770 {
771         Key *key;
772
773         key = get_action_mesh_key();
774
775         switch(event)
776         {
777                 case ACTMENU_KEY_EXTEND_CONST:
778                         if (key) {
779                                 /* to do */
780                         }
781                         else {
782                                 set_extendtype_actionchannels(SET_EXTEND_CONSTANT);
783                         }
784                         break;
785                 case ACTMENU_KEY_EXTEND_EXTRAPOLATION:
786                         if (key) {
787                                 /* to do */
788                         }
789                         else {
790                                 set_extendtype_actionchannels(SET_EXTEND_EXTRAPOLATION);
791                         }
792                         break;
793                 case ACTMENU_KEY_EXTEND_CYCLIC:
794                         if (key) {
795                                 /* to do */
796                         }
797                         else {
798                                 set_extendtype_actionchannels(SET_EXTEND_CYCLIC);
799                         }
800                         break;
801                 case ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION:
802                         if (key) {
803                                 /* to do */
804                         }
805                         else {
806                                 set_extendtype_actionchannels(SET_EXTEND_CYCLICEXTRAPOLATION);
807                         }
808                         break;
809         }
810
811         scrarea_queue_winredraw(curarea);
812 }
813
814 static uiBlock *action_keymenu_extendmenu(void *arg_unused)
815 {
816         uiBlock *block;
817         short yco= 0, menuwidth=120;
818
819         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_extendmenu", 
820                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
821         uiBlockSetButmFunc(block, do_action_keymenu_extendmenu, NULL);
822
823         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
824                                          "Constant", 0, yco-=20, 
825                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
826                                          ACTMENU_KEY_EXTEND_CONST, "");
827         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
828                                          "Extrapolation", 0, yco-=20, 
829                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
830                                          ACTMENU_KEY_EXTEND_EXTRAPOLATION, "");
831         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
832                                          "Cyclic", 0, yco-=20, 
833                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
834                                          ACTMENU_KEY_EXTEND_CYCLIC, "");
835         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
836                                          "Cyclic Extrapolation", 0, yco-=20, 
837                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
838                                          ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION, "");
839
840         uiBlockSetDirection(block, UI_RIGHT);
841         uiTextBoundsBlock(block, 60);
842
843         return block;
844 }
845
846 static void do_action_keymenu_chanposmenu(void *arg, int event)
847 {
848         switch(event)
849         {
850                 case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_DOWN:
851                         down_sel_action();
852                         break;
853                 case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_UP:
854                         up_sel_action();
855                         break;
856                 case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_TOP:
857                         top_sel_action();
858                         break;
859                 case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_BOTTOM:
860                         bottom_sel_action();
861                         break;
862         }
863
864         scrarea_queue_winredraw(curarea);
865 }
866
867 static uiBlock *action_keymenu_chanposmenu(void *arg_unused)
868 {
869         uiBlock *block;
870         short yco= 0, menuwidth=120;
871
872         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_chanposmenu", 
873                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
874         uiBlockSetButmFunc(block, do_action_keymenu_chanposmenu, NULL);
875
876         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
877                                          "Move Up|Ctrl Page Up", 0, yco-=20, 
878                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
879                                          ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_UP, "");
880         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
881                                          "Move Down|Ctrl Page Down", 0, yco-=20, 
882                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
883                                          ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_DOWN, "");
884         
885         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
886                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
887                                         
888         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
889                                          "Move to Top|Shift Page Up", 0, yco-=20, 
890                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
891                                          ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_TOP, "");
892         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
893                                          "Move to Bottom|Shift Page Down", 0, yco-=20, 
894                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
895                                          ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_BOTTOM, "");
896
897         uiBlockSetDirection(block, UI_RIGHT);
898         uiTextBoundsBlock(block, 60);
899
900         return block;
901 }
902
903 static void do_action_keymenu_snapmenu(void *arg, int event)
904 {
905         switch(event)
906         {
907                 case ACTMENU_KEY_SNAP_NEARFRAME:
908                 case ACTMENU_KEY_SNAP_CURFRAME:
909                         snap_keys_to_frame(event);
910                         break;
911         }
912
913         scrarea_queue_winredraw(curarea);
914 }
915
916 static uiBlock *action_keymenu_snapmenu(void *arg_unused)
917 {
918         uiBlock *block;
919         short yco= 0, menuwidth=120;
920
921         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_snapmenu", 
922                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
923         uiBlockSetButmFunc(block, do_action_keymenu_snapmenu, NULL);
924
925         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
926                                          "Nearest Frame|Shift S, 1", 0, yco-=20, 
927                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
928                                          ACTMENU_KEY_SNAP_NEARFRAME, "");
929         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
930                                          "Current Frame|Shift S, 2", 0, yco-=20, 
931                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
932                                          ACTMENU_KEY_SNAP_CURFRAME, "");
933
934         uiBlockSetDirection(block, UI_RIGHT);
935         uiTextBoundsBlock(block, 60);
936
937         return block;
938 }
939
940 static void do_action_keymenu_mirrormenu(void *arg, int event)
941 {
942         switch(event)
943         {
944                 case ACTMENU_KEY_MIRROR_CURFRAME:
945                 case ACTMENU_KEY_MIRROR_YAXIS:
946                         mirror_action_keys(event);
947                         break;
948         }
949
950         scrarea_queue_winredraw(curarea);
951 }
952
953 static uiBlock *action_keymenu_mirrormenu(void *arg_unused)
954 {
955         uiBlock *block;
956         short yco= 0, menuwidth=120;
957
958         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_mirrormenu", 
959                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
960         uiBlockSetButmFunc(block, do_action_keymenu_mirrormenu, NULL);
961
962         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
963                                          "Current Frame|Shift M, 1", 0, yco-=20, 
964                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
965                                          ACTMENU_KEY_MIRROR_CURFRAME, "");
966         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
967                                          "Vertical Axis|Shift M, 2", 0, yco-=20, 
968                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
969                                          ACTMENU_KEY_MIRROR_YAXIS, "");
970
971         uiBlockSetDirection(block, UI_RIGHT);
972         uiTextBoundsBlock(block, 60);
973
974         return block;
975 }
976
977 static void do_action_keymenu(void *arg, int event)
978 {       
979         SpaceAction *saction;
980         bAction *act;
981         Key *key;
982         
983         saction= curarea->spacedata.first;
984         if (!saction)
985                 return;
986
987         act = saction->action;
988         key = get_action_mesh_key();
989
990         switch(event)
991         {
992                 case ACTMENU_KEY_DUPLICATE:
993                         if (key) {
994                                 duplicate_meshchannel_keys(key);
995                         }
996                         else if (act) {
997                                 duplicate_actionchannel_keys();
998                                 remake_action_ipos(act);
999                         }
1000                         break;
1001
1002                 case ACTMENU_KEY_DELETE:
1003                         if (okee("Erase selected keys")) {
1004                                 if (key) {
1005                                         delete_meshchannel_keys(key);
1006                                 }
1007                                 else if (act) {
1008                                         delete_actionchannel_keys ();
1009                                 }
1010                         }
1011                         break;
1012                 case ACTMENU_KEY_BAKE:
1013                         bake_action_with_client (G.saction->action, OBACT, 0.01);
1014                         break;
1015                 case ACTMENU_KEY_CLEAN:
1016                         if (key) 
1017                                 clean_shapekeys(key);
1018                         else if (act) 
1019                                 clean_actionchannels(act);
1020                         break;
1021         }
1022 }
1023
1024 static uiBlock *action_keymenu(void *arg_unused)
1025 {
1026         uiBlock *block;
1027         short yco= 0, menuwidth=120;
1028
1029         block= uiNewBlock(&curarea->uiblocks, "action_keymenu", 
1030                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
1031         uiBlockSetButmFunc(block, do_action_keymenu, NULL);
1032         
1033         uiDefIconTextBlockBut(block, action_keymenu_transformmenu, 
1034                                                   NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 20, "");
1035         
1036         uiDefIconTextBlockBut(block, action_keymenu_snapmenu, 
1037                                                   NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 20, "");
1038         
1039         uiDefIconTextBlockBut(block, action_keymenu_mirrormenu, 
1040                                                   NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 20, "");
1041         
1042         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1043                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1044
1045         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1046                                         "Duplicate|Shift D", 0, yco-=20, 
1047                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
1048                                         ACTMENU_KEY_DUPLICATE, "");
1049         
1050         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1051                                         "Delete|X", 0, yco-=20, 
1052                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
1053                                         ACTMENU_KEY_DELETE, "");
1054
1055         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1056                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1057
1058         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1059                                          "Clean Action|O", 0, yco-=20, 
1060                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1061                                          ACTMENU_KEY_CLEAN, "");
1062                          
1063         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1064                                          "Bake Action to Ipo Keys", 0, yco-=20, 
1065                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1066                                          ACTMENU_KEY_BAKE, "");
1067
1068         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1069                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1070
1071         uiDefIconTextBlockBut(block, action_keymenu_handlemenu, 
1072                                                   NULL, ICON_RIGHTARROW_THIN, 
1073                                                   "Handle Type", 0, yco-=20, 120, 20, "");
1074         
1075         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1076                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1077
1078         uiDefIconTextBlockBut(block, action_keymenu_extendmenu, 
1079                                                   NULL, ICON_RIGHTARROW_THIN, 
1080                                                   "Extend Mode", 0, yco-=20, 120, 20, "");
1081         uiDefIconTextBlockBut(block, action_keymenu_intpolmenu, 
1082                                                   NULL, ICON_RIGHTARROW_THIN, 
1083                                                   "Interpolation Mode", 0, yco-=20, 120, 20, "");
1084         uiDefIconTextBlockBut(block, action_keymenu_chanposmenu, 
1085                                                   NULL, ICON_RIGHTARROW_THIN, 
1086                                                   "Channel Ordering", 0, yco-=20, 120, 20, "");
1087
1088         
1089         if(curarea->headertype==HEADERTOP) {
1090                 uiBlockSetDirection(block, UI_DOWN);
1091         }
1092         else {
1093                 uiBlockSetDirection(block, UI_TOP);
1094                 uiBlockFlipOrder(block);
1095         }
1096
1097         uiTextBoundsBlock(block, 50);
1098
1099         return block;
1100 }
1101
1102 static void do_action_markermenu(void *arg, int event)
1103 {       
1104         switch(event)
1105         {
1106                 case ACTMENU_MARKERS_ADD:
1107                         add_marker(CFRA);
1108                         break;
1109                 case ACTMENU_MARKERS_DUPLICATE:
1110                         duplicate_marker();
1111                         break;
1112                 case ACTMENU_MARKERS_DELETE:
1113                         remove_marker();
1114                         break;
1115                 case ACTMENU_MARKERS_NAME:
1116                         rename_marker();
1117                         break;
1118                 case ACTMENU_MARKERS_MOVE:
1119                         transform_markers('g', 0);
1120                         break;
1121         }
1122         
1123         allqueue(REDRAWTIME, 0);
1124         allqueue(REDRAWIPO, 0);
1125         allqueue(REDRAWACTION, 0);
1126         allqueue(REDRAWNLA, 0);
1127         allqueue(REDRAWSOUND, 0);
1128 }
1129
1130 static uiBlock *action_markermenu(void *arg_unused)
1131 {
1132         uiBlock *block;
1133         short yco= 0, menuwidth=120;
1134
1135         block= uiNewBlock(&curarea->uiblocks, "action_markermenu", 
1136                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
1137         uiBlockSetButmFunc(block, do_action_markermenu, NULL);
1138
1139         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Marker|M", 0, yco-=20, 
1140                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_ADD, "");
1141         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate Marker|Ctrl Shift D", 0, yco-=20, 
1142                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_DUPLICATE, "");
1143         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete Marker|X", 0, yco-=20,
1144                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_DELETE, "");
1145                                          
1146         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1147
1148         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "(Re)Name Marker|Ctrl M", 0, yco-=20,
1149                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_NAME, "");
1150         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move Marker|Ctrl G", 0, yco-=20,
1151                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_MOVE, "");
1152         
1153         
1154         if(curarea->headertype==HEADERTOP) {
1155                 uiBlockSetDirection(block, UI_DOWN);
1156         }
1157         else {
1158                 uiBlockSetDirection(block, UI_TOP);
1159                 uiBlockFlipOrder(block);
1160         }
1161
1162         uiTextBoundsBlock(block, 50);
1163
1164         return block;
1165 }
1166
1167 void action_buttons(void)
1168 {
1169         uiBlock *block;
1170         short xco, xmax;
1171         char naam[256];
1172         Object *ob;
1173         ID *from;
1174
1175         if (!G.saction)
1176                 return;
1177
1178         // copy from drawactionspace....
1179         if (!G.saction->pin) {
1180                 if (OBACT)
1181                         G.saction->action = OBACT->action;
1182                 else
1183                         G.saction->action=NULL;
1184         }
1185
1186         sprintf(naam, "header %d", curarea->headwin);
1187         block= uiNewBlock(&curarea->uiblocks, naam, 
1188                                           UI_EMBOSS, UI_HELV, curarea->headwin);
1189
1190         if (area_is_active_area(curarea)) 
1191                 uiBlockSetCol(block, TH_HEADER);
1192         else 
1193                 uiBlockSetCol(block, TH_HEADERDESEL);
1194
1195         curarea->butspacetype= SPACE_ACTION;
1196         
1197         xco = 8;
1198         
1199         uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, 
1200                                           windowtype_pup(), xco, 0, XIC+10, YIC, 
1201                                           &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, 
1202                                           "Displays Current Window Type. "
1203                                           "Click for menu of available types.");
1204
1205         xco += XIC + 14;
1206
1207         uiBlockSetEmboss(block, UI_EMBOSSN);
1208         if (curarea->flag & HEADER_NO_PULLDOWN) {
1209                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, 
1210                                           ICON_DISCLOSURE_TRI_RIGHT,
1211                                           xco,2,XIC,YIC-2,
1212                                           &(curarea->flag), 0, 0, 0, 0, 
1213                                           "Show pulldown menus");
1214         }
1215         else {
1216                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, 
1217                                           ICON_DISCLOSURE_TRI_DOWN,
1218                                           xco,2,XIC,YIC-2,
1219                                           &(curarea->flag), 0, 0, 0, 0, 
1220                                           "Hide pulldown menus");
1221         }
1222         uiBlockSetEmboss(block, UI_EMBOSS);
1223         xco+=XIC;
1224
1225         if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
1226                 /* pull down menus */
1227                 uiBlockSetEmboss(block, UI_EMBOSSP);
1228         
1229                 xmax= GetButStringLength("View");
1230                 uiDefPulldownBut(block, action_viewmenu, NULL, 
1231                                           "View", xco, -2, xmax-3, 24, "");
1232                 xco+= xmax;
1233                 
1234                 xmax= GetButStringLength("Select");
1235                 uiDefPulldownBut(block, action_selectmenu, NULL, 
1236                                           "Select", xco, -2, xmax-3, 24, "");
1237                 xco+= xmax;
1238                 
1239                 xmax= GetButStringLength("Marker");
1240                 uiDefPulldownBut(block, action_markermenu, NULL, 
1241                                           "Marker", xco, -2, xmax-3, 24, "");
1242                 xco+= xmax;
1243                 
1244                 xmax= GetButStringLength("Key");
1245                 uiDefPulldownBut(block, action_keymenu, NULL, 
1246                                           "Key", xco, -2, xmax-3, 24, "");
1247                 xco+= xmax;
1248         }
1249
1250         uiBlockSetEmboss(block, UI_EMBOSS);
1251         
1252         /* NAME ETC */
1253         ob=OBACT;
1254         from = (ID*) ob;
1255
1256         xco= std_libbuttons(block, xco, 0, B_ACTPIN, &G.saction->pin, 
1257                                                 B_ACTIONBROWSE, ID_AC, 0, (ID*)G.saction->action, 
1258                                                 from, &(G.saction->actnr), B_ACTALONE, 
1259                                                 B_ACTLOCAL, B_ACTIONDELETE, 0, 0);      
1260
1261                 
1262         /* Draw action baker */
1263         xco+= 8;
1264         
1265         uiDefBut(block, BUT, B_ACTBAKE, 
1266                          "Bake", xco, 0, 64, YIC, 0, 0, 0, 0, 0, 
1267                          "Create an action with the constraint effects "
1268                          "converted into Ipo keys");
1269         xco+=64;
1270
1271         uiClearButLock();
1272
1273         /* draw AUTOSNAP */
1274         xco+= 8;
1275         
1276         uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, 
1277                                                 "Auto-Snap Keys %t|Off %x0|Frame Step %x1|Nearest Frame %x2", 
1278                                                 xco,0,XIC+10,YIC, &(G.saction->autosnap), 0, 1, 0, 0, 
1279                                                 "Auto-snapping mode for keys when transforming");
1280         
1281         xco+= (XIC + 18);
1282         
1283         /* draw LOCK*/
1284                 
1285         uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco, 0, XIC, YIC, 
1286                                   &(G.saction->lock), 0, 0, 0, 0, 
1287                                   "Updates other affected window spaces automatically "
1288                                   "to reflect changes in real time");
1289
1290         /* always as last  */
1291         curarea->headbutlen = xco + 2*XIC;
1292
1293         uiDrawBlock(block);
1294 }