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